[
  {
    "path": ".circleci/config.yml",
    "content": "version: 2.1\n\norbs:\n    windows: circleci/windows@5.1.1\n\njobs:\n    build-linux:\n        docker:\n            - image: circleci/rust:stretch\n\n        environment:\n            OPENSSL_STATIC: \"1\"\n            OPENSSL_LIB_DIR: \"/usr/lib/x86_64-linux-gnu/\"\n            OPENSSL_INCLUDE_DIR: \"/usr/include/x86_64-linux-gnu/\"\n            RUSTFLAGS: \"-Ctarget-feature=+aes,+ssse3\"\n\n        steps:\n            - checkout\n            - run:\n                  name: \"APT Install Dependencies\"\n                  command: |\n                      sudo apt-get update\n                      sudo apt-get install -y build-essential\n            - run:\n                  name: \"Generate Cargo.lock\"\n                  command: |\n                      rustc --version >rust-version\n                      test -e Cargo.lock || cargo generate-lockfile\n            - restore_cache:\n                  key: cargo-cache-{{ arch }}-{{ checksum \"rust-version\" }}-{{ checksum \"Cargo.lock\" }}\n            - run:\n                  name: \"Build Release\"\n                  command: BUILD_EXTRA_FEATURES=\"openssl-vendored local-redir\" ./build-host-release\n                  no_output_timeout: 1h\n            - save_cache:\n                  paths:\n                      - /usr/local/cargo/registry\n                      - ./target\n                  key: cargo-cache-{{ arch }}-{{ checksum \"rust-version\" }}-{{ checksum \"Cargo.lock\" }}\n\n    build-windows:\n        executor: windows/default\n\n        environment:\n            OPENSSL_STATIC: \"1\"\n            OPENSSL_DIR: \"C:\\\\OpenSSL\"\n            RUSTFLAGS: \"-Ctarget-feature=+aes,+ssse3\"\n            CARGO_NET_GIT_FETCH_WITH_CLI: \"true\"\n\n        steps:\n            - checkout\n            - run:\n                  name: \"Install Rust\"\n                  command: |\n                      $ProgressPreference = \"SilentlyContinue\"\n                      Invoke-WebRequest -Uri \"https://win.rustup.rs/\" -OutFile \"C:\\rustup-init.exe\"\n                      & C:\\rustup-init.exe -y --default-toolchain \"stable-x86_64-pc-windows-msvc\" --no-modify-path --profile minimal\n\n                      $env:Path += \";C:\\Users\\circleci\\.cargo\\bin\"\n                      rustc -Vv\n                      cargo --version\n\n                      rustc --version | Out-File -FilePath \"rust-version\"\n                      if (!(Test-Path \"Cargo.lock\" -PathType Leaf)) {\n                          cargo generate-lockfile\n                      }\n            - run:\n                  name: \"Install OpenSSL\"\n                  command: |\n                      $env:Path += \";C:\\Users\\circleci\\.cargo\\bin\"\n\n                      $TargetTriple = (rustc -Vv | Select-String -Pattern \"host: (.*)\" | foreach {$_.Matches.Value}).split()[-1]\n                      if ($TargetTriple.StartsWith(\"x86_64-\")) {\n                          $OpenSSLBits = \"64\"\n                      } else {\n                          $OpenSSLBits = \"32\"\n                      }\n                      $OpenSSLVersion = \"1_1_0L\"\n                      $OpenSSLFileName = \"Win${OpenSSLBits}OpenSSL-${OpenSSLVersion}.exe\"\n\n                      $ProgressPreference = \"SilentlyContinue\"\n                      Invoke-WebRequest -Uri \"http://slproweb.com/download/${OpenSSLFileName}\" -OutFile \"${OpenSSLFileName}\"\n                      Write-Host \"* Done downloading ${OpenSSLFileName}\"\n                      dir\n                      Start-Process \"${OpenSSLFileName}\" -ArgumentList \"/SILENT /VERYSILENT /SP- /SUPPRESSMSGBOXES /DIR=C:\\OpenSSL\" -Wait\n                      Write-Host \"* Done installing ${OpenSSLFileName}\"\n            - restore_cache:\n                  key: cargo-cache-{{ arch }}-{{ checksum \"rust-version\" }}-{{ checksum \"Cargo.lock\" }}\n            # - run: ./build-host-release\n            - run:\n                  name: \"Package Release\"\n                  command: |\n                      $ProgressPreference = \"SilentlyContinue\"\n                      $env:Path += \";C:\\Users\\circleci\\.cargo\\bin;.\"\n\n                      $PackageReleasePath = \"${PWD}\\build\\release\"\n\n                      Pushd target\\release\n                      $Version = (sslocal -V).split()[-1]\n                      $TargetTriple = (rustc -Vv | Select-String -Pattern \"host: (.*)\" | foreach {$_.Matches.Value}).split()[-1]\n                      $PackageName = \"shadowsocks-v${Version}.${TargetTriple}.zip\"\n                      $PackagePath = \"${PackageReleasePath}\\${PackageName}\"\n\n                      Write-Host \"${Version}\"\n                      Write-Host \"${TargetTriple}\"\n                      Write-Host \"${PackagePath}\"\n\n                      New-Item \"${PackageReleasePath}\" -ItemType Directory -ErrorAction SilentlyContinue\n                      $CompressParam = @{\n                          LiteralPath = \"sslocal.exe\", \"ssserver.exe\", \"ssurl.exe\", \"ssmanager.exe\"\n                          DestinationPath = \"${PackagePath}\"\n                      }\n                      Compress-Archive @CompressParam\n                      Popd\n\n                      $PackageChecksumPath = \"${PackagePath}.sha256\"\n                      $PackageHash = (Get-FileHash -Path \"${PackagePath}\" -Algorithm SHA256).Hash\n                      \"${PackageHash}  ${PackageName}\" | Out-File -FilePath \"${PackageChecksumPath}\"\n            - save_cache:\n                  paths:\n                      - C:\\Users\\circleci\\.cargo\\registry\n                      - target\n                  key: cargo-cache-{{ arch }}-{{ checksum \"rust-version\" }}-{{ checksum \"Cargo.lock\" }}\n            - store_artifacts:\n                  path: build\\\\release\n                  destination: releases\n            - persist_to_workspace:\n                  root: build\n                  paths:\n                      - release\n\n    build-docker:\n        machine:\n            image: ubuntu-1604:201903-01\n            docker_layer_caching: true\n\n        steps:\n            - checkout\n            - run:\n                  name: \"APT Install Dependencies\"\n                  command: |\n                      sudo apt-get update\n                      sudo apt-get install curl\n            - run:\n                  name: \"Build docker images\"\n                  command: |\n                      cd build\n                      docker build -t shadowsocks-rust:x86_64-pc-windows-gnu -f Dockerfile.x86_64-pc-windows-gnu .\n                      docker build -t shadowsocks-rust:x86_64-unknown-linux-musl -f Dockerfile.x86_64-unknown-linux-musl .\n                      docker build -t shadowsocks-rust:x86_64-unknown-linux-gnu -f Dockerfile.x86_64-unknown-linux-gnu .\n                      docker build -t shadowsocks-rust:arm-unknown-linux-gnueabihf -f Dockerfile.arm-unknown-linux-gnueabihf .\n                      docker build -t shadowsocks-rust:arm-unknown-linux-musleabi -f Dockerfile.arm-unknown-linux-musleabi .\n                      docker build -t shadowsocks-rust:aarch64-unknown-linux-gnu -f Dockerfile.aarch64-unknown-linux-gnu .\n            - run:\n                  name: \"Install Rust\"\n                  command: |\n                      curl \"https://sh.rustup.rs\" -o \"rust-init.sh\"\n                      chmod +x \"rust-init.sh\"\n                      ./rust-init.sh -y --default-toolchain stable --no-modify-path --profile minimal\n                      export PATH=\"$HOME/.cargo/bin:$PATH\"\n                      echo 'export PATH=\"$HOME/.cargo/bin:$PATH\"' >> $BASH_ENV\n                      rustup --version\n                      cargo --version\n                      rustc --version\n            - restore_cache:\n                  key: cargo-cache-{{ arch }}\n            - run: cargo install cross\n            - run:\n                  name: \"Build Releases\"\n                  command: |\n                      cd build\n                      ./build-release\n                  no_output_timeout: 2h\n            - save_cache:\n                  paths:\n                      - /usr/local/cargo/registry\n                      - ./target\n                  key: cargo-cache-{{ arch }}\n            - store_artifacts:\n                  path: ./build/release\n                  destination: releases\n            - persist_to_workspace:\n                  root: build\n                  paths:\n                      - release\n\n    publish-github-releases:\n        docker:\n            - image: circleci/golang:1.17\n        steps:\n            - attach_workspace:\n                  at: /tmp/workspace\n            - run:\n                  name: \"Publish Release on GitHub\"\n                  command: |\n                      ls -alh /tmp/workspace/release\n\n                      if [[ ! -z \"${CIRCLE_TAG}\" ]]; then\n                          go get github.com/tcnksm/ghr\n                          EXTRA_FLAGS=\"-replace\"\n                          if [[ \"${CIRCLE_TAG}\" == *\"-alpha.\"* ]]; then\n                              EXTRA_FLAGS=\"${EXTRA_FLAGS} -prerelease\"\n                          fi\n                          ghr -t \"${GITHUB_TOKEN}\" \\\n                              -u \"${CIRCLE_PROJECT_USERNAME}\" -r \"${CIRCLE_PROJECT_REPONAME}\" \\\n                              -c \"${CIRCLE_SHA1}\" \\\n                              ${EXTRA_FLAGS} \\\n                              \"${CIRCLE_TAG}\" /tmp/workspace/release\n                      else\n                          echo \"Current build is not tagged.\"\n                      fi\n\nworkflows:\n    version: 2\n    build-releases:\n        jobs:\n            - build-linux:\n                  filters:\n                      tags:\n                          only: /^v\\d+\\.\\d+\\.\\d+(-alpha\\.\\d+)?$/\n            - build-windows:\n                  filters:\n                      tags:\n                          only: /^v\\d+\\.\\d+\\.\\d+(-alpha\\.\\d+)?$/\n            - build-docker:\n                  filters:\n                      branches:\n                          ignore: /.*/\n                      tags:\n                          only: /^v\\d+\\.\\d+\\.\\d+(-alpha\\.\\d+)?$/\n            - publish-github-releases:\n                  requires:\n                      - build-windows\n                      - build-docker\n                  filters:\n                      branches:\n                          ignore: /.*/\n                      tags:\n                          only: /^v\\d+\\.\\d+\\.\\d+(-alpha\\.\\d+)?$/\n"
  },
  {
    "path": ".dockerignore",
    "content": "**/.git\n.circleci\n.devcontainer\n.github\n.ssh\n.vscode\n**/target\ndev\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "version: 2\nupdates:\n- package-ecosystem: cargo\n  directory: \"/\"\n  schedule:\n    interval: weekly\n  open-pull-requests-limit: 0\n"
  },
  {
    "path": ".github/workflows/build-and-test.yml",
    "content": "name: Build & Test\n\non: [push, pull_request]\n\nenv:\n  CARGO_TERM_COLOR: always\n  RUST_LOG: \"trace\"\n\njobs:\n  build-and-test:\n    strategy:\n      matrix:\n        platform:\n          - ubuntu-latest\n          - windows-latest\n          - macos-latest\n    runs-on: ${{ matrix.platform }}\n\n    steps:\n      - if: ${{ matrix.platform == 'ubuntu-latest' }}\n        name: Free Disk Space (Ubuntu)\n        uses: jlumbroso/free-disk-space@main\n      - uses: actions/checkout@v6\n      - uses: Swatinem/rust-cache@v2\n      - if: ${{ runner.os == 'Windows' }}\n        uses: ilammy/setup-nasm@v1\n      - if: ${{ matrix.platform == 'ubuntu-latest' }}\n        name: Install LLVM and Clang\n        run: sudo apt update && sudo apt install -y clang\n      - name: Install Rust\n        run: |\n          rustup set profile minimal\n          rustup toolchain install stable\n          rustup default stable\n          rustup override set stable\n      - name: Build & Test (Default)\n        run: cargo test --verbose --no-fail-fast\n      - name: Build & Test (full)\n        run: cargo test --features \"full\" --verbose --no-fail-fast\n      - name: Build & Test (full-extra)\n        run: cargo test --features \"full-extra\" --verbose --no-fail-fast\n      - name: Build & Test (Default) - shadowsocks\n        run: cargo test --manifest-path ./crates/shadowsocks/Cargo.toml --verbose --no-fail-fast\n      - name: Build & Test (Default) - shadowsocks-service\n        run: cargo test --manifest-path ./crates/shadowsocks-service/Cargo.toml --verbose --no-fail-fast\n      - name: Build & Test (--no-default-features)\n        run: cargo test --verbose --no-default-features --no-fail-fast\n      - name: Build & Test (--no-default-features) - shadowsocks\n        run: cargo test --manifest-path ./crates/shadowsocks/Cargo.toml --verbose --no-default-features --no-fail-fast\n      - name: Build & Test (--no-default-features) - shadowsocks-service\n        run: cargo test --manifest-path ./crates/shadowsocks-service/Cargo.toml --verbose --no-default-features --no-fail-fast\n      - name: Build with All Features Enabled (Unix)\n        if: ${{ runner.os == 'Linux' || runner.os == 'macOS' }}\n        run: cargo build --verbose --features \"full-extra local-flow-stat utility-url-outline\"\n      - name: Build with All Features Enabled (Windows)\n        if: ${{ runner.os == 'Windows' }}\n        run: cargo build --verbose --features \"full-extra local-flow-stat utility-url-outline winservice\"\n      - name: Build with All Features Enabled - shadowsocks\n        run: cargo build --manifest-path ./crates/shadowsocks/Cargo.toml --verbose --features \"stream-cipher aead-cipher-extra aead-cipher-2022 aead-cipher-2022-extra security-replay-attack-detect\"\n"
  },
  {
    "path": ".github/workflows/build-docker-image.yml",
    "content": "name: Build Docker Images\non:\n  push:\n    tags:\n      - v*\n  workflow_dispatch:\n\njobs:\n  build-docker-image:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        bin:\n          - ssserver\n          - sslocal\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v6\n      - name: Setup Docker Buildx\n        uses: docker/setup-buildx-action@v4\n      - name: Login to GitHub Container Registry\n        uses: docker/login-action@v4\n        with:\n          registry: ghcr.io\n          username: ${{ github.repository_owner }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n      - name: Docker metadata\n        id: metadata\n        uses: docker/metadata-action@v6\n        with:\n          images: ghcr.io/${{ github.repository_owner }}/${{ matrix.bin }}-rust\n      - name: Build and release Docker images\n        uses: docker/build-push-action@v7\n        with:\n          platforms: linux/386,linux/amd64,linux/arm64/v8\n          target: ${{ matrix.bin }}\n          tags: ${{ steps.metadata.outputs.tags }}\n          push: true\n"
  },
  {
    "path": ".github/workflows/build-msrv.yml",
    "content": "name: Build MSRV\n\non: [push, pull_request]\n\nenv:\n  CARGO_TERM_COLOR: always\n  RUST_LOG: \"trace\"\n\njobs:\n  build-msrv-shadowsocks-rust:\n    strategy:\n      matrix:\n        platform:\n          - ubuntu-latest\n          - windows-latest\n          - macos-latest\n    runs-on: ${{ matrix.platform }}\n\n    steps:\n      - if: ${{ matrix.platform == 'ubuntu-latest' }}\n        name: Free Disk Space (Ubuntu)\n        uses: jlumbroso/free-disk-space@main\n      - if: ${{ matrix.platform == 'ubuntu-latest' }}\n        name: Install LLVM and Clang\n        run: sudo apt update && sudo apt install -y clang\n      - uses: actions/checkout@v6\n      - uses: Swatinem/rust-cache@v2\n      - if: ${{ runner.os == 'Windows' }}\n        uses: ilammy/setup-nasm@v1\n      - name: Install Rust\n        run: |\n          rustup set profile minimal\n          rustup toolchain install 1.88\n          rustup default 1.88\n          rustup override set 1.88\n      - name: Build with All Features Enabled (Unix)\n        if: ${{ runner.os == 'Linux' || runner.os == 'macOS' }}\n        run: cargo build --verbose --features \"full-extra local-flow-stat utility-url-outline\"\n      - name: Build with All Features Enabled (Windows)\n        if: ${{ runner.os == 'Windows' }}\n        run: cargo build --verbose --features \"full-extra local-flow-stat utility-url-outline winservice\"\n\n  build-msrv-shadowsocks-service:\n    strategy:\n      matrix:\n        platform:\n          - ubuntu-latest\n          - windows-latest\n          - macos-latest\n    runs-on: ${{ matrix.platform }}\n\n    steps:\n      - if: ${{ matrix.platform == 'ubuntu-latest' }}\n        name: Free Disk Space (Ubuntu)\n        uses: jlumbroso/free-disk-space@main\n      - if: ${{ matrix.platform == 'ubuntu-latest' }}\n        name: Install LLVM and Clang\n        run: sudo apt update && sudo apt install -y clang\n      - uses: actions/checkout@v6\n      - uses: Swatinem/rust-cache@v2\n      - if: ${{ runner.os == 'Windows' }}\n        uses: ilammy/setup-nasm@v1\n      - name: Install Rust\n        run: |\n          rustup set profile minimal\n          rustup toolchain install 1.88\n          rustup default 1.88\n          rustup override set 1.88\n      - name: Build with All Features Enabled\n        run: cargo build --manifest-path crates/shadowsocks-service/Cargo.toml --verbose --features \"full dns-over-tls dns-over-https dns-over-h3 local-dns local-flow-stat local-http-rustls local-tun local-fake-dns local-online-config stream-cipher aead-cipher-extra aead-cipher-2022 aead-cipher-2022-extra security-replay-attack-detect\"\n\n  build-msrv-shadowsocks:\n    strategy:\n      matrix:\n        platform:\n          - ubuntu-latest\n          - windows-latest\n          - macos-latest\n    runs-on: ${{ matrix.platform }}\n\n    steps:\n      - if: ${{ matrix.platform == 'ubuntu-latest' }}\n        name: Free Disk Space (Ubuntu)\n        uses: jlumbroso/free-disk-space@main\n      - if: ${{ matrix.platform == 'ubuntu-latest' }}\n        name: Install LLVM and Clang\n        run: sudo apt update && sudo apt install -y clang\n      - uses: actions/checkout@v6\n      - uses: Swatinem/rust-cache@v2\n      - if: ${{ runner.os == 'Windows' }}\n        uses: ilammy/setup-nasm@v1\n      - name: Install Rust\n        run: |\n          rustup set profile minimal\n          rustup toolchain install 1.88\n          rustup default 1.88\n          rustup override set 1.88\n      - name: Build with All Features Enabled\n        run: cargo build --manifest-path crates/shadowsocks/Cargo.toml --verbose --features \"stream-cipher aead-cipher-extra aead-cipher-2022 aead-cipher-2022-extra security-replay-attack-detect\"\n"
  },
  {
    "path": ".github/workflows/build-nightly-release.yml",
    "content": "name: Build Nightly Releases\non:\n  push:\n    branches: [master]\n  workflow_dispatch:\n\nenv:\n  CARGO_TERM_COLOR: always\n\njobs:\n  build-nightly-cross:\n    runs-on: ubuntu-latest\n    env:\n      RUST_BACKTRACE: full\n    strategy:\n      fail-fast: false\n      matrix:\n        platform:\n          - target: x86_64-unknown-linux-gnu\n            toolchain: stable\n          - target: x86_64-unknown-linux-musl\n            toolchain: stable\n          - target: aarch64-unknown-linux-gnu\n            toolchain: stable\n          - target: aarch64-unknown-linux-musl\n            toolchain: stable\n          - target: mips-unknown-linux-gnu\n            toolchain: nightly\n          - target: mipsel-unknown-linux-gnu\n            toolchain: nightly\n          - target: mips64el-unknown-linux-gnuabi64\n            toolchain: nightly\n          - target: x86_64-unknown-freebsd\n            toolchain: stable\n          - target: x86_64-unknown-netbsd\n            toolchain: stable\n          - target: loongarch64-unknown-linux-gnu\n            toolchain: stable\n          - target: loongarch64-unknown-linux-musl\n            toolchain: stable\n          - target: powerpc-unknown-linux-gnu\n            toolchain: stable\n          - target: powerpc64-unknown-linux-gnu\n            toolchain: stable\n          - target: powerpc64le-unknown-linux-gnu\n            toolchain: stable\n          - target: riscv64gc-unknown-linux-gnu\n            toolchain: stable\n          - target: riscv64gc-unknown-linux-musl\n            toolchain: stable\n          - target: aarch64-linux-android\n            toolchain: stable\n          - target: x86_64-linux-android\n            toolchain: stable\n\n    steps:\n      - name: Free Disk Space (Ubuntu)\n        uses: jlumbroso/free-disk-space@main\n\n      - name: Install LLVM and Clang\n        run: sudo apt update && sudo apt install -y clang\n\n      - uses: actions/checkout@v6\n\n      - name: Install Rust\n        run: |\n          rustup set profile minimal\n          rustup toolchain install ${{ matrix.platform.toolchain }}\n          rustup default ${{ matrix.platform.toolchain }}\n          rustup override set ${{ matrix.platform.toolchain }}\n\n      - name: Install cross\n        run: cargo install cross --git https://github.com/cross-rs/cross\n\n      - name: Build ${{ matrix.platform.target }}\n        timeout-minutes: 120\n        run: |\n          compile_target=${{ matrix.platform.target }}\n\n          compile_features=\"-f full\"\n\n          if [[ \"$compile_target\" == *\"-windows-\"* ]]; then\n            compile_features=\"$compile_features -f winservice\"\n          fi\n\n          if [[ \"$compile_target\" == \"mips-\"* || \"$compile_target\" == \"mipsel-\"* || \"$compile_target\" == \"mips64-\"* || \"$compile_target\" == \"mips64el-\"* ]]; then\n            sudo apt-get update -y && sudo apt-get install -y upx;\n            if [[ \"$?\" == \"0\" ]]; then\n              compile_compress=\"-u\"\n            fi\n\n            compile_nightly=\"-n\"\n            #compile_cargo_flags=\"-Z build-std=std,panic_abort,proc_macro\"\n          fi\n\n          cd build\n          ./build-release -t ${{ matrix.platform.target }} $compile_features $compile_compress $compile_nightly $compile_cargo_flags\n\n      - name: Upload Artifacts\n        uses: actions/upload-artifact@v7\n        with:\n          name: ${{ matrix.platform.target }}\n          path: build/release/*\n\n  build-nightly-unix:\n    runs-on: ${{ matrix.os }}\n    env:\n      BUILD_EXTRA_FEATURES: \"full\"\n      RUST_BACKTRACE: full\n    strategy:\n      fail-fast: false\n      matrix:\n        os: [macos-latest]\n        target:\n          - x86_64-apple-darwin\n          - aarch64-apple-darwin\n    steps:\n      - uses: actions/checkout@v6\n\n      - name: Install GNU tar\n        if: runner.os == 'macOS'\n        run: |\n          brew install gnu-tar\n          # echo \"::add-path::/usr/local/opt/gnu-tar/libexec/gnubin\"\n          echo \"/usr/local/opt/gnu-tar/libexec/gnubin\" >> $GITHUB_PATH\n\n      - name: Install Rust\n        run: |\n          rustup set profile minimal\n          rustup toolchain install stable\n          rustup default stable\n          rustup override set stable\n          rustup target add --toolchain stable ${{ matrix.target }}\n\n      - name: Build release\n        shell: bash\n        run: |\n          ./build/build-host-release -t ${{ matrix.target }}\n\n      - name: Upload Artifacts\n        uses: actions/upload-artifact@v7\n        with:\n          name: ${{ matrix.target }}\n          path: build/release/*\n\n  build-nightly-windows:\n    runs-on: windows-latest\n    env:\n      RUSTFLAGS: \"-C target-feature=+crt-static\"\n      RUST_BACKTRACE: full\n    steps:\n      - uses: actions/checkout@v6\n      - uses: ilammy/setup-nasm@v1\n\n      - name: Install Rust\n        run: |\n          rustup set profile minimal\n          rustup toolchain install stable\n          rustup default stable\n          rustup override set stable\n\n      - name: Build release\n        run: |\n          pwsh ./build/build-host-release.ps1 \"full winservice\"\n\n      - name: Upload Artifacts\n        uses: actions/upload-artifact@v7\n        with:\n          name: windows-native\n          path: build/release/*\n"
  },
  {
    "path": ".github/workflows/build-release.yml",
    "content": "name: Build Releases\non:\n  push:\n    tags:\n      - v*\n  workflow_dispatch:\n    inputs:\n      tag:\n        description: 'Release Tag'\n        required: true\n        type: string\n\nenv:\n  CARGO_TERM_COLOR: always\n\njobs:\n  build-release-cross:\n    runs-on: ubuntu-latest\n    env:\n      RUST_BACKTRACE: full\n    strategy:\n      fail-fast: false\n      matrix:\n        platform:\n          - target: i686-unknown-linux-musl\n            toolchain: stable\n          - target: x86_64-pc-windows-gnu\n            toolchain: stable\n          - target: x86_64-unknown-linux-gnu\n            toolchain: stable\n          - target: x86_64-unknown-linux-musl\n            toolchain: stable\n          - target: armv7-unknown-linux-musleabihf\n            toolchain: stable\n          - target: armv7-unknown-linux-gnueabihf\n            toolchain: stable\n          - target: arm-unknown-linux-gnueabi\n            toolchain: stable\n          - target: arm-unknown-linux-gnueabihf\n            toolchain: stable\n          - target: arm-unknown-linux-musleabi\n            toolchain: stable\n          - target: arm-unknown-linux-musleabihf\n            toolchain: stable\n          - target: aarch64-unknown-linux-gnu\n            toolchain: stable\n          - target: aarch64-unknown-linux-musl\n            toolchain: stable\n          - target: mips-unknown-linux-gnu\n            toolchain: nightly\n          # cross mips-*-musl images are disabled\n          # - target: mips-unknown-linux-musl\n          #   toolchain: nightly\n          - target: mipsel-unknown-linux-gnu\n            toolchain: nightly\n          # - target: mipsel-unknown-linux-musl\n          #   toolchain: nightly\n          # FIXME: ring doesn't support mips64 CPU\n          # - target: mips64-unknown-linux-gnuabi64\n          #   toolchain: nightly\n          # - target: mips64-unknown-linux-muslabi64\n          #   toolchain: nightly\n          - target: mips64el-unknown-linux-gnuabi64\n            toolchain: nightly\n          # FIXME: Link Error. \n          #   = note: mips64el-linux-muslsf-gcc: error: crt1.o: No such file or directory\n          #           mips64el-linux-muslsf-gcc: error: crti.o: No such file or directory\n          #           mips64el-linux-muslsf-gcc: error: crtbegin.o: No such file or directory\n          #           mips64el-linux-muslsf-gcc: error: crtend.o: No such file or directory\n          #           mips64el-linux-muslsf-gcc: error: crtn.o: No such file or directory\n          # - target: mips64el-unknown-linux-muslabi64\n          #   toolchain: nightly\n          - target: x86_64-unknown-freebsd\n            toolchain: stable\n          - target: x86_64-unknown-netbsd\n            toolchain: stable\n          - target: loongarch64-unknown-linux-gnu\n            toolchain: stable\n          - target: loongarch64-unknown-linux-musl\n            toolchain: stable\n          - target: riscv64gc-unknown-linux-gnu\n            toolchain: stable\n          - target: riscv64gc-unknown-linux-musl\n            toolchain: stable\n          - target: aarch64-linux-android\n            toolchain: stable\n          - target: x86_64-linux-android\n            toolchain: stable\n\n    steps:\n      - name: Free Disk Space (Ubuntu)\n        uses: jlumbroso/free-disk-space@main\n\n      - name: Install LLVM and Clang\n        run: sudo apt update && sudo apt install -y clang\n\n      - uses: actions/checkout@v6\n\n      - name: Install Rust\n        run: |\n          rustup set profile minimal\n          rustup toolchain install ${{ matrix.platform.toolchain }}\n          rustup default ${{ matrix.platform.toolchain }}\n          rustup override set ${{ matrix.platform.toolchain }}\n\n      - name: Install cross\n        run: cargo install cross --git https://github.com/cross-rs/cross\n\n      - name: Build ${{ matrix.platform.target }}\n        timeout-minutes: 120\n        run: |\n          compile_target=${{ matrix.platform.target }}\n\n          compile_features=\"-f full\"\n\n          if [[ \"$compile_target\" == *\"-windows-\"* ]]; then\n            compile_features=\"$compile_features -f winservice\"\n          fi\n\n          if [[ \"$compile_target\" == \"mips-\"* || \"$compile_target\" == \"mipsel-\"* || \"$compile_target\" == \"mips64-\"* || \"$compile_target\" == \"mips64el-\"* ]]; then\n            sudo apt-get update -y && sudo apt-get install -y upx;\n            if [[ \"$?\" == \"0\" ]]; then\n              compile_compress=\"-u\"\n            fi\n\n            compile_nightly=\"-n\"\n            #compile_cargo_flags=\"-Z build-std=std,panic_abort,proc_macro\"\n          fi\n\n          cd build\n          ./build-release -t ${{ matrix.platform.target }} $compile_features $compile_compress $compile_nightly $compile_cargo_flags\n\n      - name: Upload Github Assets\n        uses: softprops/action-gh-release@v2\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        with:\n          files: build/release/*\n          prerelease: ${{ contains(github.ref_name, '-') }}\n          tag_name: ${{ inputs.tag || github.ref_name }}\n\n  build-release-unix:\n    runs-on: ${{ matrix.os }}\n    env:\n      BUILD_EXTRA_FEATURES: \"full\"\n      RUST_BACKTRACE: full\n    strategy:\n      fail-fast: false\n      matrix:\n        # os: [ubuntu-latest, macos-latest]\n        os: [macos-latest]\n        target:\n          - x86_64-apple-darwin\n          - aarch64-apple-darwin\n    steps:\n      - uses: actions/checkout@v6\n\n      - name: Install GNU tar\n        if: runner.os == 'macOS'\n        run: |\n          brew install gnu-tar\n          # echo \"::add-path::/usr/local/opt/gnu-tar/libexec/gnubin\"\n          echo \"/usr/local/opt/gnu-tar/libexec/gnubin\" >> $GITHUB_PATH\n\n      - name: Install Rust\n        run: |\n          rustup set profile minimal\n          rustup toolchain install stable\n          rustup default stable\n          rustup override set stable\n          rustup target add --toolchain stable ${{ matrix.target }}\n\n      - name: Build release\n        shell: bash\n        run: |\n          ./build/build-host-release -t ${{ matrix.target }}\n\n      - name: Upload Github Assets\n        uses: softprops/action-gh-release@v2\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        with:\n          files: build/release/*\n          prerelease: ${{ contains(github.ref_name, '-') }}\n          tag_name: ${{ inputs.tag || github.ref_name }}\n\n  build-release-windows:\n    runs-on: windows-latest\n    env:\n      RUSTFLAGS: \"-C target-feature=+crt-static\"\n      RUST_BACKTRACE: full\n    steps:\n      - uses: actions/checkout@v6\n      - uses: ilammy/setup-nasm@v1\n\n      - name: Install Rust\n        run: |\n          rustup set profile minimal\n          rustup toolchain install stable\n          rustup default stable\n          rustup override set stable\n\n      - name: Build release\n        run: |\n          pwsh ./build/build-host-release.ps1 \"full winservice\"\n\n      - name: Upload Github Assets\n        uses: softprops/action-gh-release@v2\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        with:\n          files: build/release/*\n          prerelease: ${{ contains(github.ref_name, '-') }}\n          tag_name: ${{ inputs.tag || github.ref_name }}\n"
  },
  {
    "path": ".github/workflows/clippy-check.yml",
    "content": "name: Clippy Check\n\non: [push, pull_request]\n\nenv:\n  CARGO_TERM_COLOR: always\n  RUST_LOG: \"trace\"\n\njobs:\n  clippy-check:\n    strategy:\n      matrix:\n        platform:\n          - ubuntu-latest\n          - windows-latest\n          - macos-latest\n    runs-on: ${{ matrix.platform }}\n\n    steps:\n      - uses: actions/checkout@v6\n      - uses: Swatinem/rust-cache@v2\n      - if: ${{ runner.os == 'Windows' }}\n        uses: ilammy/setup-nasm@v1\n      - name: Install Rust\n        run: |\n          rustup set profile minimal\n          rustup toolchain install stable --component clippy\n      - name: Clippy Check\n        uses: actions-rs/clippy-check@v1\n        with:\n          token: ${{ secrets.GITHUB_TOKEN }}\n          args: |\n            --features \"full-extra local-flow-stat utility-url-outline\"\n            -- -A clippy::absurd_extreme_comparisons\n          name: clippy ${{ matrix.platform }}\n"
  },
  {
    "path": ".github/workflows/deny-check.yml",
    "content": "name: Cargo Deny Check\non: [push, pull_request]\njobs:\n  deny-check:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        checks:\n          - advisories\n          - bans licenses sources\n\n    # Prevent sudden announcement of a new advisory from failing ci:\n    continue-on-error: ${{ matrix.checks == 'advisories' }}\n\n    steps:\n    - uses: actions/checkout@v6\n    - uses: EmbarkStudios/cargo-deny-action@v2\n      with:\n        command: check ${{ matrix.checks }}\n"
  },
  {
    "path": ".gitignore",
    "content": "target\n/build/release\n/build/target\n/build/install\n/build/*.sha256\n/dev\n/*.log\n/debian/*.log\n/.vscode\n/*.json\n/restart.sh\n/udp_echo_server.py\n/.idea\n/.devcontainer\n.DS_Store\n"
  },
  {
    "path": ".travis.yml",
    "content": "sudo: false\nlanguage: rust\njobs:\n  include:\n    - os: windows\n      rust: stable\n\n    - os: osx\n      rust: stable\n      osx_image: xcode11.3\n      env: SODIUM_USE_PKG_CONFIG=1\n\n    - os: linux\n      rust: stable\n      dist: bionic\n      env: SODIUM_USE_PKG_CONFIG=1\n    - os: linux\n      rust: beta\n      dist: bionic\n      env: SODIUM_USE_PKG_CONFIG=1\n    - os: linux\n      rust: nightly\n      dist: bionic\n      env: SODIUM_USE_PKG_CONFIG=1\n\n  allow_failures:\n    # FIXME: Travis build success but tests crash\n    - os: osx\n    - os: windows\n\nenv:\n  - RUSTFLAGS=\"-Ctarget-feature=+aes,+ssse3\" RUSTDOCFLAGS=\"-Ctarget-feature=+aes,+ssse3\" RUST_BACKTRACE=1\n\naddons:\n  apt:\n    packages:\n      - libssl-dev\n      - libsodium-dev\n  homebrew:\n    packages:\n      - libsodium\n\ninstall:\n  # Install OpenSSL on Windows\n  - if [ \"${TRAVIS_OS_NAME}\" = \"windows\" ]; then\n    curl -Lo \"openssl-1.0.2c-win64-mingw.zip\" \"https://dl.bintray.com/vszakats/generic/openssl-1.0.2c-win64-mingw.zip\";\n    unzip \"openssl-1.0.2c-win64-mingw.zip\" -d \"/c/OpenSSL\";\n    export OPENSSL_LIB_DIR=/c/OpenSSL/openssl-1.0.2c-win64-mingw;\n    export OPENSSL_INCLUDE_DIR=/c/OpenSSL/openssl-1.0.2c-win64-mingw/include;\n    export OPENSSL_DIR=/c/OpenSSL/openssl-1.0.2c-win64-mingw;\n    fi\n  # - if [ \"${TRAVIS_OS_NAME}\" = \"windows\" ]; then\n  #   choco install openssl;\n  #   export OPENSSL_DIR='/c/Program Files/OpenSSL-Win64/';\n  #   export OPENSSL_STATIC=1;\n  #   fi\n\nscript:\n  - cargo test --no-fail-fast\n  # - cargo test --no-fail-fast --no-default-features\n  # - cargo test --no-fail-fast --features aes-pmac-siv\n  # - cargo test --no-fail-fast --features single-threaded\n  # - cargo test --no-fail-fast --features openssl-vendored\n  # - cargo test --no-fail-fast --no-default-features --features \"local-http local-http-rustls\"\n  - if [ \"${TRAVIS_OS_NAME}\" = \"linux\" -o \"${TRAVIS_OS_NAME}\" = \"osx\" ]; then\n    cargo test --no-fail-fast --features local-redir;\n    fi\n\n# cache: cargo\n"
  },
  {
    "path": "Cargo.toml",
    "content": "[package]\nname = \"shadowsocks-rust\"\nversion = \"1.24.0\"\nauthors = [\"Shadowsocks Contributors\"]\ndescription = \"shadowsocks is a fast tunnel proxy that helps you bypass firewalls.\"\nrepository = \"https://github.com/shadowsocks/shadowsocks-rust\"\nreadme = \"README.md\"\ndocumentation = \"https://docs.rs/shadowsocks-rust\"\nkeywords = [\"shadowsocks\", \"proxy\", \"socks\", \"socks5\", \"firewall\"]\nlicense = \"MIT\"\nedition = \"2024\"\nrust-version = \"1.88\"\n\n[badges]\nmaintenance = { status = \"passively-maintained\" }\n\n[[bin]]\nname = \"sslocal\"\npath = \"bin/sslocal.rs\"\nrequired-features = [\"local\"]\n\n[[bin]]\nname = \"ssserver\"\npath = \"bin/ssserver.rs\"\nrequired-features = [\"server\"]\n\n[[bin]]\nname = \"ssurl\"\npath = \"bin/ssurl.rs\"\nrequired-features = [\"utility\"]\n\n[[bin]]\nname = \"ssmanager\"\npath = \"bin/ssmanager.rs\"\nrequired-features = [\"manager\"]\n\n[[bin]]\nname = \"ssservice\"\npath = \"bin/ssservice.rs\"\nrequired-features = [\"service\"]\n\n[[bin]]\nname = \"sswinservice\"\npath = \"bin/sswinservice.rs\"\nrequired-features = [\"winservice\"]\n\n[workspace]\nmembers = [\"crates/shadowsocks\", \"crates/shadowsocks-service\"]\n\n[profile.release]\nlto = \"fat\"\ncodegen-units = 1\nincremental = false\npanic = \"abort\"\nstrip = true\n\n[features]\ndefault = [\"full\"]\n\n# Basic Features\nbasic = [\n    \"logging\",\n    \"hickory-dns\",\n    \"local\",\n    \"server\",\n    \"multi-threaded\",\n    \"aead-cipher\",\n]\n\n# All Suggested Features\nfull = [\n    \"logging\",\n    \"hickory-dns\",\n    \"dns-over-tls\",\n    \"dns-over-https\",\n    \"local\",\n    \"server\",\n    \"manager\",\n    \"utility\",\n    \"service\",\n    \"local-http\",\n    \"local-http-rustls\",\n    \"local-tunnel\",\n    \"local-socks4\",\n    \"local-dns\",\n    \"local-redir\",\n    \"local-tun\",\n    \"local-online-config\",\n    \"multi-threaded\",\n    \"stream-cipher\",\n    \"aead-cipher\",\n    \"aead-cipher-2022\",\n]\n\n# Full features with extra (non-stable)\nfull-extra = [\n    \"full\",\n    \"dns-over-h3\",\n    \"local-fake-dns\",\n    \"aead-cipher-extra\",\n    \"aead-cipher-2022-extra\",\n    \"security-replay-attack-detect\",\n]\n\n# Enable local server\nlocal = [\"shadowsocks-service/local\"]\n# Enable remote server\nserver = [\"shadowsocks-service/server\"]\n# Enable manager server\nmanager = [\"shadowsocks-service/manager\"]\n# Enable utility\nutility = [\"qrcode\"]\n# Enable service\nservice = [\"local\", \"server\", \"manager\"]\n# Enable Windows Service\nwinservice = [\"service\", \"windows-service\"]\n\n# Enables Hickory-DNS for replacing tokio's builtin DNS resolver\nhickory-dns = [\"shadowsocks-service/hickory-dns\"]\n# Hickory-DNS was renamed from Trust-DNS, keep compatibility.\ntrust-dns = [\"hickory-dns\"]\ndns-over-tls = [\"shadowsocks-service/dns-over-tls\"]\ndns-over-https = [\"shadowsocks-service/dns-over-https\"]\ndns-over-h3 = [\"shadowsocks-service/dns-over-h3\"]\n\n# Enable logging output\nlogging = [\n    \"log4rs\",\n    \"tracing\",\n    \"tracing-subscriber\",\n    \"time\",\n    \"tracing-appender\",\n    \"tracing-syslog\",\n]\n\n# Enable DNS-relay\nlocal-dns = [\"local\", \"shadowsocks-service/local-dns\"]\n# Enable client flow statistic report\n# Currently is only used in Android\nlocal-flow-stat = [\"local\", \"shadowsocks-service/local-flow-stat\"]\n# Enable HTTP protocol for sslocal\nlocal-http = [\"local\", \"shadowsocks-service/local-http\"]\nlocal-http-native-tls = [\n    \"local-http\",\n    \"shadowsocks-service/local-http-native-tls\",\n]\nlocal-http-native-tls-vendored = [\n    \"local-http\",\n    \"shadowsocks-service/local-http-native-tls-vendored\",\n]\nlocal-http-rustls = [\"local-http\", \"shadowsocks-service/local-http-rustls\"]\n# Enable REDIR protocol for sslocal\n# (transparent proxy)\nlocal-redir = [\"local\", \"shadowsocks-service/local-redir\"]\n# Enable tunnel protocol for sslocal\nlocal-tunnel = [\"local\", \"shadowsocks-service/local-tunnel\"]\n# Enable socks4 protocol for sslocal\nlocal-socks4 = [\"local\", \"shadowsocks-service/local-socks4\"]\n# Enable Tun interface protocol for sslocal\nlocal-tun = [\"local\", \"shadowsocks-service/local-tun\", \"ipnet\"]\n# Enable Fake DNS for sslocal\nlocal-fake-dns = [\"local\", \"shadowsocks-service/local-fake-dns\", \"ipnet\"]\n# sslocal support online URL (SIP008 Online Configuration Delivery)\n# https://shadowsocks.org/doc/sip008.html\nlocal-online-config = [\"local\", \"shadowsocks-service/local-online-config\"]\n\n# ssurl support outline (ssconf) URL\nutility-url-outline = [\"reqwest\"]\n\n# Enable jemalloc for binaries\njemalloc = [\"jemallocator\"]\n# Enable bundled tcmalloc\ntcmalloc-vendored = [\"tcmalloc/bundled\"]\n\n# Enable snmalloc for binaries\nsnmalloc = [\"snmalloc-rs\"]\n\n# Enable tokio's multi-threaded runtime\nmulti-threaded = [\"tokio/rt-multi-thread\"]\n\n# Enable Stream Cipher Protocol\n# WARN: Stream Cipher Protocol is proved to be insecure\n# https://github.com/shadowsocks/shadowsocks-rust/issues/373\n# Users should always avoid using these ciphers in practice\nstream-cipher = [\"shadowsocks-service/stream-cipher\"]\n\n# Enable AEAD ciphers\naead-cipher = [\"shadowsocks-service/aead-cipher\"]\n\n# Enable extra AEAD ciphers\n# WARN: These non-standard AEAD ciphers are not officially supported by shadowsocks community\naead-cipher-extra = [\"aead-cipher\", \"shadowsocks-service/aead-cipher-extra\"]\n\n# Enable AEAD 2022\naead-cipher-2022 = [\"shadowsocks-service/aead-cipher-2022\"]\n# Enable AEAD 2022 with extra ciphers\naead-cipher-2022-extra = [\"shadowsocks-service/aead-cipher-2022-extra\"]\n\n# Enable detection against replay attack (Stream / AEAD)\nsecurity-replay-attack-detect = [\n    \"shadowsocks-service/security-replay-attack-detect\",\n]\nreplay-attack-detect = [\n    \"security-replay-attack-detect\",\n] # Backward compatibility. DO NOT USE.\n\n# Logging to syslog (Unix only)\ntracing-syslog = [\"dep:syslog-tracing\"]\n\n[dependencies]\nlog = \"0.4\"\nlog4rs = { version = \"1.2\", optional = true }\ntracing = { version = \"0.1\", optional = true }\ntracing-subscriber = { version = \"0.3\", optional = true, features = [\n    \"std\",\n    \"fmt\",\n    \"env-filter\",\n    \"time\",\n    \"local-time\",\n] }\ntracing-appender = { version = \"0.2.3\", optional = true, default-features = false }\nsyslog-tracing = { version = \"0.3\", optional = true }\ntime = { version = \"0.3\", optional = true }\n\nserde = { version = \"1.0\", features = [\"derive\"] }\njson5 = \"1.3\"\nthiserror = \"2.0\"\nbase64 = \"0.22\"\n\nclap = { version = \"4.5\", features = [\"wrap_help\", \"suggestions\"] }\ncfg-if = \"1\"\nqrcode = { version = \"0.14\", default-features = false, optional = true }\nsysexits = \"0.13\"\nbuild-time = \"0.1\"\ndirectories = \"6.0\"\nrpassword = \"7.3\"\nlibc = { version = \"0.2\", features = [\"extra_traits\"] }\nrand = \"0.10\"\n\nfutures = \"0.3\"\ntokio = { version = \"1\", features = [\"rt\", \"signal\"] }\n\nipnet = { version = \"2.10\", optional = true }\nreqwest = { version = \"0.13\", features = [\"blocking\"], optional = true }\n\nmimalloc = { version = \"0.1\", default-features = false, optional = true }\ntcmalloc = { version = \"0.3\", optional = true }\njemallocator = { version = \"0.5\", optional = true }\nsnmalloc-rs = { version = \"0.3\", optional = true }\nrpmalloc = { version = \"0.2\", optional = true }\n\nshadowsocks-service = { version = \"1.24.0\", path = \"./crates/shadowsocks-service\", default-features = false }\n\nwindows-service = { version = \"0.8\", optional = true }\n\n[target.'cfg(unix)'.dependencies]\nxdg = \"3.0\"\n\n[dev-dependencies]\nbyteorder = \"1.5\"\nenv_logger = \"0.11\"\nbyte_string = \"1.0\"\ntokio = { version = \"1\", features = [\"net\", \"time\", \"macros\", \"io-util\"] }\n\n[lints.clippy]\nuninlined_format_args = \"allow\"\n"
  },
  {
    "path": "Cross-centos.toml",
    "content": "[build.env]\npassthrough = [\"RUSTFLAGS\"]\n\n# WARN: GCC 4.8.2 doesn't support <stdatomic.h>\n[target.x86_64-unknown-linux-gnu]\nimage = \"ghcr.io/cross-rs/x86_64-unknown-linux-gnu:main-centos\"\n# GCC 4.8.2 doesn't support ACLE\n# https://github.com/briansmith/ring/issues/1728\n# [target.aarch64-unknown-linux-gnu]\n# image = \"ghcr.io/cross-rs/aarch64-unknown-linux-gnu:main-centos\"\n"
  },
  {
    "path": "Cross.toml",
    "content": "[build]\n# dockerfile = \"./docker/linux-cross/Dockerfile\"\n# pre-build = [\n#     \"curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain stable\",\n#     \". $HOME/.cargo/env\",\n#     \"cargo install --force --locked bindgen-cli && mv $HOME/.cargo/bin/bindgen /usr/bin\",\n#     \"rm -rf $HOME/.cargo\"\n# ]\n# pre-build = [\n#     \"apt update\",\n#     \"apt install --assume-yes --no-install-recommends build-essential llvm-8-dev libclang-8-dev clang-8\",\n# ]\n\n[build.env]\npassthrough = [\"RUSTFLAGS\"]\n\n# MIPS targets are dropped to Tier 3\n# https://github.com/rust-lang/compiler-team/issues/648\n# FIXME: build-std with sequence is supported only on git\n[target.mips-unknown-linux-gnu]\nbuild-std = [\"std\", \"panic_abort\", \"proc_macro\"]\n[target.mips-unknown-linux-musl]\nbuild-std = [\"std\", \"panic_abort\", \"proc_macro\"]\n[target.mips64-unknown-linux-gnuabi64]\nbuild-std = [\"std\", \"panic_abort\", \"proc_macro\"]\n[target.mips64-unknown-linux-muslabi64]\nbuild-std = [\"std\", \"panic_abort\", \"proc_macro\"]\n[target.mips64el-unknown-linux-gnuabi64]\nbuild-std = [\"std\", \"panic_abort\", \"proc_macro\"]\n[target.mips64el-unknown-linux-muslabi64]\nbuild-std = [\"std\", \"panic_abort\", \"proc_macro\"]\n[target.mipsel-unknown-linux-gnu]\nbuild-std = [\"std\", \"panic_abort\", \"proc_macro\"]\n[target.mipsel-unknown-linux-musl]\nbuild-std = [\"std\", \"panic_abort\", \"proc_macro\"]\n"
  },
  {
    "path": "Dockerfile",
    "content": "FROM --platform=$BUILDPLATFORM rust:1.94.0-alpine3.22 AS builder\n\nARG TARGETARCH\n\nRUN set -x \\\n    && apk add --no-cache musl-dev\n\nWORKDIR /root/shadowsocks-rust\n\nADD . .\n\nRUN case \"$TARGETARCH\" in \\\n    \"386\") \\\n        RUST_TARGET=\"i686-unknown-linux-musl\" \\\n        MUSL=\"i686-linux-musl\" \\\n        SHA512=\"5047afc68170a2910895db2dfa448227e71a984bfa2130a1bc946fd1015d722b80b15e4abf90c64300815aa84fe781cc8b8a72f10174f9dce96169e035911880\" \\\n    ;; \\\n    \"amd64\") \\\n        RUST_TARGET=\"x86_64-unknown-linux-musl\" \\\n        MUSL=\"x86_64-linux-musl\" \\\n        SHA512=\"52abd1a56e670952116e35d1a62e048a9b6160471d988e16fa0e1611923dd108a581d2e00874af5eb04e4968b1ba32e0eb449a1f15c3e4d5240ebe09caf5a9f3\" \\\n    ;; \\\n    \"arm64\") \\\n        RUST_TARGET=\"aarch64-unknown-linux-musl\" \\\n        MUSL=\"aarch64-linux-musl\" \\\n        SHA512=\"8695ff86979cdf30fbbcd33061711f5b1ebc3c48a87822b9ca56cde6d3a22abd4dab30fdcd1789ac27c6febbaeb9e5bde59d79d66552fae53d54cc1377a19272\" \\\n    ;; \\\n    *) \\\n        echo \"Doesn't support $TARGETARCH architecture\" \\\n        exit 1 \\\n    ;; \\\n    esac \\\n    && wget \"https://github.com/AaronChen0/musl-cc-mirror/releases/download/2021-09-23/$MUSL-cross.tgz\" \\\n    && ( echo \"$SHA512\" \"$MUSL-cross.tgz\" | sha512sum -c ) \\\n    && tar -xzf \"$MUSL-cross.tgz\" -C /root/ \\\n    && PATH=\"/root/$MUSL-cross/bin:$PATH\" \\\n    && CC=/root/$MUSL-cross/bin/$MUSL-gcc \\\n    && echo \"CC=$CC\" \\\n    && rustup target add \"$RUST_TARGET\" \\\n    && RUSTFLAGS=\"-C linker=$CC\" CC=$CC cargo build --target \"$RUST_TARGET\" --release --features \"full\" \\\n    && mv target/$RUST_TARGET/release/ss* target/release/\n\nFROM alpine:3.23 AS sslocal\n\n# NOTE: Please be careful to change the path of these binaries, refer to #1149 for more information.\nCOPY --from=builder /root/shadowsocks-rust/target/release/sslocal /usr/bin/\nCOPY --from=builder /root/shadowsocks-rust/examples/config.json /etc/shadowsocks-rust/\nCOPY --from=builder /root/shadowsocks-rust/docker/docker-entrypoint.sh /usr/bin/\n\nENTRYPOINT [ \"docker-entrypoint.sh\" ]\nCMD [ \"sslocal\", \"--log-without-time\", \"-c\", \"/etc/shadowsocks-rust/config.json\" ]\n\nFROM alpine:3.23 AS ssserver\n\nCOPY --from=builder /root/shadowsocks-rust/target/release/ssserver /usr/bin/\nCOPY --from=builder /root/shadowsocks-rust/examples/config.json /etc/shadowsocks-rust/\nCOPY --from=builder /root/shadowsocks-rust/docker/docker-entrypoint.sh /usr/bin/\n\nENTRYPOINT [ \"docker-entrypoint.sh\" ]\n\nCMD [ \"ssserver\", \"--log-without-time\", \"-a\", \"nobody\", \"-c\", \"/etc/shadowsocks-rust/config.json\" ]"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2017 Y. T. CHUNG <zonyitoo@gmail.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "Makefile",
    "content": "PREFIX ?= /usr/local/bin\nTARGET ?= debug\n\n.PHONY: all build install uninstall clean\nall: build\n\nbuild:\nifeq (${TARGET}, release)\n\tcargo build --release --features \"full\"\nelse\n\tcargo build --features \"full\"\nendif\n\ninstall:\n\tinstall -d ${DESTDIR}${PREFIX}\n\tinstall -m 755 target/${TARGET}/sslocal ${DESTDIR}${PREFIX}/sslocal\n\tinstall -m 755 target/${TARGET}/ssserver ${DESTDIR}${PREFIX}/ssserver\n\tinstall -m 755 target/${TARGET}/ssurl ${DESTDIR}${PREFIX}/ssurl\n\tinstall -m 755 target/${TARGET}/ssmanager ${DESTDIR}${PREFIX}/ssmanager\n\tinstall -m 755 target/${TARGET}/ssservice ${DESTDIR}${PREFIX}/ssservice\n\nuninstall:\n\trm ${DESTDIR}${PREFIX}/sslocal\n\trm ${DESTDIR}${PREFIX}/ssserver\n\trm ${DESTDIR}${PREFIX}/ssurl\n\trm ${DESTDIR}${PREFIX}/ssmanager\n\trm ${DESTDIR}${PREFIX}/ssservice\n\nclean:\n\tcargo clean\n"
  },
  {
    "path": "README.md",
    "content": "# shadowsocks\n\n[![License](https://img.shields.io/github/license/zonyitoo/shadowsocks-rust.svg)](https://github.com/zonyitoo/shadowsocks-rust)\n[![Build & Test](https://github.com/shadowsocks/shadowsocks-rust/actions/workflows/build-and-test.yml/badge.svg)](https://github.com/shadowsocks/shadowsocks-rust/actions/workflows/build-and-test.yml)\n[![Build MSRV](https://github.com/shadowsocks/shadowsocks-rust/actions/workflows/build-msrv.yml/badge.svg)](https://github.com/shadowsocks/shadowsocks-rust/actions/workflows/build-msrv.yml)\n[![Build Releases](https://github.com/shadowsocks/shadowsocks-rust/actions/workflows/build-release.yml/badge.svg?event=push)](https://github.com/shadowsocks/shadowsocks-rust/actions/workflows/build-release.yml)\n[![Build Nightly Releases](https://github.com/shadowsocks/shadowsocks-rust/actions/workflows/build-nightly-release.yml/badge.svg)](https://github.com/shadowsocks/shadowsocks-rust/actions/workflows/build-nightly-release.yml)\n[![Gurubase](https://img.shields.io/badge/Gurubase-Ask%20shadowsocks%20Guru-006BFF)](https://gurubase.io/g/shadowsocks)\n\n[![crates.io](https://img.shields.io/crates/v/shadowsocks-rust.svg)](https://crates.io/crates/shadowsocks-rust)\n[![Release](https://img.shields.io/github/release/shadowsocks/shadowsocks-rust.svg)](https://github.com/shadowsocks/shadowsocks-rust/releases)\n[![shadowsocks-rust](https://img.shields.io/archlinux/v/extra/x86_64/shadowsocks-rust)](https://archlinux.org/packages/extra/x86_64/shadowsocks-rust/)\n[![aur shadowsocks-rust-git](https://img.shields.io/aur/version/shadowsocks-rust-git)](https://aur.archlinux.org/packages/shadowsocks-rust-git)\n[![NixOS](https://img.shields.io/badge/NixOS-shadowsocks--rust-blue?logo=nixos)](https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/sh/shadowsocks-rust/package.nix)\n[![snap shadowsocks-rust](https://snapcraft.io/shadowsocks-rust/badge.svg)](https://snapcraft.io/shadowsocks-rust)\n[![homebrew shadowsocks-rust](https://img.shields.io/homebrew/v/shadowsocks-rust)](https://formulae.brew.sh/formula/shadowsocks-rust#default)\n[![MacPorts shadowsocks-rust](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fports.macports.org%2Fapi%2Fv1%2Fports%2Fshadowsocks-rust%2F&query=%24.version&label=macports)](https://ports.macports.org/port/shadowsocks-rust/)\n\nThis is a port of [shadowsocks](https://github.com/shadowsocks/shadowsocks).\n\nshadowsocks is a fast tunnel proxy that helps you bypass firewalls.\n\n| Library                                                                 | Description                                                                                                                                                                                                                                                 |\n| ----------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| [**shadowsocks**](https://crates.io/crates/shadowsocks)                 | [![crates.io](https://img.shields.io/crates/v/shadowsocks.svg)](https://crates.io/crates/shadowsocks) [![docs.rs](https://img.shields.io/docsrs/shadowsocks)](https://docs.rs/shadowsocks) shadowsocks core protocol                                        |\n| [**shadowsocks-service**](https://crates.io/crates/shadowsocks-service) | [![crates.io](https://img.shields.io/crates/v/shadowsocks-service.svg)](https://crates.io/crates/shadowsocks-service) [![docs.rs](https://img.shields.io/docsrs/shadowsocks-service)](https://docs.rs/shadowsocks-service) Services for serving shadowsocks |\n| [**shadowsocks-rust**](https://crates.io/crates/shadowsocks-rust)       | [![crates.io](https://img.shields.io/crates/v/shadowsocks-rust.svg)](https://crates.io/crates/shadowsocks-rust) Binaries running common shadowsocks services                                                                                                |\n\nRelated Projects:\n\n- [spyophobia/shadowsocks-gtk-rs](https://github.com/spyophobia/shadowsocks-gtk-rs) A GUI on Linux for `sslocal` using GTK, [discussion](https://github.com/shadowsocks/shadowsocks-rust/issues/664)\n- [honwen/openwrt-shadowsocks-rust](https://github.com/honwen/openwrt-shadowsocks-rust) OpenWRT solution for `sslocal`, [discussion](https://github.com/honwen/openwrt-shadowsocks-rust)\n- [cg31/shadowsocks-windows-gui-rust](https://github.com/cg31/shadowsocks-windows-gui-rust) Windows GUI client, [discussion](https://github.com/shadowsocks/shadowsocks-rust/issues/375)\n\n## Build & Install\n\n### Optional Features\n\n- `hickory-dns` - Uses [`hickory-resolver`](https://crates.io/crates/hickory-resolver) as DNS resolver instead of `tokio`'s builtin.\n\n- `local-http` - Allow using HTTP protocol for `sslocal`\n\n  - `local-http-native-tls` - Support HTTPS with [`native-tls`](https://crates.io/crates/native-tls)\n\n  - `local-http-rustls` - Support HTTPS with [`rustls`](https://crates.io/crates/rustls)\n\n- `local-tunnel` - Allow using tunnel protocol for `sslocal`\n\n- `local-socks4` - Allow using SOCKS4/4a protocol for `sslocal`\n\n- `local-redir` - Allow using redir (transparent proxy) protocol for `sslocal`\n\n- `local-dns` - Allow using dns protocol for `sslocal`, serves as a DNS server proxying queries to local or remote DNS servers by ACL rules\n\n- `local-fake-dns` - FakeDNS, allocating an IP address for each individual Query from a specific IP pool\n\n- `local-tun` - [TUN](https://en.wikipedia.org/wiki/TUN/TAP) interface support for `sslocal`\n\n- `local-online-config` - [SIP008](https://shadowsocks.org/doc/sip008.html) Online Configuration Delivery\n\n- `stream-cipher` - Enable deprecated stream ciphers. WARN: stream ciphers are UNSAFE!\n\n- `aead-cipher-extra` - Enable non-standard AEAD ciphers\n\n- `aead-cipher-2022` - Enable AEAD-2022 ciphers ([SIP022](https://github.com/shadowsocks/shadowsocks-org/issues/196))\n\n- `aead-cipher-2022-extra` - Enable AEAD-2022 extra ciphers (non-standard ciphers)\n\n#### Memory Allocators\n\nThis project uses system (libc) memory allocator (Rust's default). But it also allows you to use other famous allocators by features:\n\n- `jemalloc` - Uses [jemalloc](http://jemalloc.net/) as global memory allocator\n- `mimalloc` - Uses [mi-malloc](https://microsoft.github.io/mimalloc/) as global memory allocator\n- `tcmalloc` - Uses [TCMalloc](https://google.github.io/tcmalloc/overview.html) as global memory allocator. It tries to link system-wide tcmalloc by default, use vendored from source with `tcmalloc-vendored`.\n- `snmalloc` - Uses [snmalloc](https://github.com/microsoft/snmalloc) as global memory allocator\n- `rpmalloc` - Uses [rpmalloc](https://github.com/mjansson/rpmalloc) as global memory allocator\n\n### **crates.io**\n\nInstall from [crates.io](https://crates.io/crates/shadowsocks-rust):\n\n```bash\n# Install from crates.io\ncargo install shadowsocks-rust\n```\n\nthen you can find `sslocal` and `ssserver` in `$CARGO_HOME/bin`.\n\n### **Install using Homebrew**\n\nFor macOS and Linux, you can install it using [Homebrew](https://brew.sh/):\n\n```bash\nbrew install shadowsocks-rust\n```\n\n### **Install using snap**\n\n```bash\n# Install from snapstore\nsnap install shadowsocks-rust\n\n# List services\nsnap services shadowsocks-rust\n\n# Enable and start shadowsocks-rust.sslocal-daemon snap service\nsnap start --enable shadowsocks-rust.sslocal-daemon\n\n# Show generated systemd service status\nsystemctl status snap.shadowsocks-rust.sslocal-daemon.service\n\n# Override generated systemd service (configure startup options)\nsystemctl edit snap.shadowsocks-rust.sslocal-daemon.service\n\n## NOTE: you can pass args to sslocal:\n##  [Service]\n##  ExecStart=\n##  ExecStart=/usr/bin/snap run shadowsocks-rust.sslocal-daemon -b \"127.0.0.1:1080\" --server-url \"ss://....\"\n\n# Restart generated systemd service to apply changes\nsystemctl restart snap.shadowsocks-rust.sslocal-daemon.service\n\n# ... and show service status\nsystemctl status snap.shadowsocks-rust.sslocal-daemon.service\n```\n\nDefault configuration file path probably is `/var/snap/shadowsocks-rust/common/etc/shadowsocks-rust/config.json`.\n\n### **Download release**\n\nDownload static-linked build [here](https://github.com/shadowsocks/shadowsocks-rust/releases).\n\n- Most of them are built with [cross](https://github.com/cross-rs/cross). Build environment details could be found in its README, such as glibc's version.\n- `x86_64-apple-darwin`, `aarch64-apple-darwin` are built in github's `macos-latest` image. Information could be found in [here](https://docs.github.com/en/actions/using-github-hosted-runners/using-github-hosted-runners/about-github-hosted-runners).\n- `x86_64-pc-windows-msvc` is built in github's `windows-latest` image. Information could be found in [here](https://docs.github.com/en/actions/using-github-hosted-runners/using-github-hosted-runners/about-github-hosted-runners).\n\n### **Docker**\n\nThis project provided Docker images for the `linux/i386` and `linux/amd64` and `linux/arm64/v8` architectures.\n\n> :warning: **Docker containers do not have access to IPv6 by default**: Make sure to disable IPv6 Route in the client or [enable IPv6 access to docker containers](https://docs.docker.com/config/daemon/ipv6/#use-ipv6-for-the-default-bridge-network).\n\n#### Pull from GitHub Container Registry\n\nDocker will pull the image of the appropriate architecture from our [GitHub Packages](https://github.com/orgs/shadowsocks/packages?repo_name=shadowsocks-rust).\n\n```bash\ndocker pull ghcr.io/shadowsocks/sslocal-rust:latest\ndocker pull ghcr.io/shadowsocks/ssserver-rust:latest\n```\n\n#### Build on the local machine（Optional）\n\nIf you want to build the Docker image yourself, you need to use the [BuildX](https://docs.docker.com/buildx/working-with-buildx/).\n\n```bash\ndocker buildx build -t shadowsocks/ssserver-rust:latest -t shadowsocks/ssserver-rust:v1.15.2 --target ssserver .\ndocker buildx build -t shadowsocks/sslocal-rust:latest -t shadowsocks/sslocal-rust:v1.15.2 --target sslocal .\n```\n\n#### Run the container\n\nYou need to mount the configuration file into the container and create an external port map for the container to connect to it.\n\n```bash\ndocker run --name sslocal-rust \\\n  --restart always \\\n  -p 1080:1080/tcp \\\n  -v /path/to/config.json:/etc/shadowsocks-rust/config.json \\\n  -dit ghcr.io/shadowsocks/sslocal-rust:latest\n\ndocker run --name ssserver-rust \\\n  --restart always \\\n  -p 8388:8388/tcp \\\n  -p 8388:8388/udp \\\n  -v /path/to/config.json:/etc/shadowsocks-rust/config.json \\\n  -dit ghcr.io/shadowsocks/ssserver-rust:latest\n```\n\n### **Deploy to Kubernetes**\n\nThis project provided yaml manifests for deploying to Kubernetes.\n\nYou can leverage k8s Service to expose traffic outside, like LoadBalancer or NodePort which gains more fine-grained compared with fixed host or port.\n\nFor a more interesting use case, you can use a Ingress(Istio, nginx, etc.) which routes the matched traffic to shadowsocks along with the real web service.\n\n#### Using `kubectl`\n\n`kubectl apply -f https://github.com/shadowsocks/shadowsocks-rust/raw/master/k8s/shadowsocks-rust.yaml`\n\nYou can change the config via editing the ConfigMap named `shadowsocks-rust`.\n\nFor more fine-grained control, use `helm`.\n\n#### Using `helm`\n\n`helm install my-release k8s/chart -f my-values.yaml`\n\nBelow is the common default values you can change:\n\n```yaml\n# This is the shadowsocks config which will be mount to /etc/shadowocks-rust.\n# You can put arbitrary yaml here, and it will be translated to json before mounting.\nservers:\n- server: \"::\"\n  server_port: 8388\n  service_port: 80 # the k8s service port, default to server_port\n  password: mypassword\n  method: aes-256-gcm\n  fast_open: true\n  mode: tcp_and_udp\n  # plugin: v2ray-plugin\n  # plugin_opts: server;tls;host=github.com\n\n# Whether to download v2ray and xray plugin.\ndownloadPlugins: false\n\n# Name of the ConfigMap with config.json configuration for shadowsocks-rust.\nconfigMapName: \"\"\n\nservice:\n  # Change to LoadBalancer if you are behind a cloud provider like aws, gce, or tke.\n  type: ClusterIP\n\n# Bind shadowsocks port port to host, i.e., we can use host:port to access shawdowsocks server.\nhostPort: false\n\nreplicaCount: 1\n\nimage:\n  repository: ghcr.io/shadowsocks/ssserver-rust\n  pullPolicy: IfNotPresent\n  # Overrides the image tag whose default is the chart appVersion.\n  tag: \"latest\"\n```\n\n### **Build from source**\n\nUse cargo to build. NOTE: **RAM >= 2GiB**\n\n```bash\ncargo build --release\n```\n\nThen `sslocal` and `ssserver` will appear in `./target/(debug|release)/`, it works similarly as the two binaries in the official ShadowSocks' implementation.\n\n```bash\nmake install TARGET=release\n```\n\nThen `sslocal`, `ssserver`, `ssmanager` and `ssurl` will be installed to `/usr/local/bin` (variable PREFIX).\n\nFor Windows users, if you have encountered any problem in building, check and discuss in [#102](https://github.com/shadowsocks/shadowsocks-rust/issues/102).\n\n### **target-cpu optimization**\n\nIf you are building for your current CPU platform (for example, build and run on your personal computer), it is recommended to set `target-cpu=native` feature to let `rustc` generate and optimize code for the CPU running the compiler.\n\n```bash\nexport RUSTFLAGS=\"-C target-cpu=native\"\n```\n\n### **Build standalone binaries**\n\nRequirements:\n\n- Docker\n\n```bash\n./build/build-release\n```\n\nThen `sslocal`, `ssserver`, `ssmanager`, `ssservice` and `ssurl` will be packaged in\n\n- `./build/shadowsocks-${VERSION}-stable.x86_64-unknown-linux-musl.tar.xz`\n- `./build/shadowsocks-${VERSION}-stable.x86_64-pc-windows-gnu.zip`\n\nRead `Cargo.toml` for more details.\n\nFor Linux with low GLIBC versions, set `CROSS_CONFIG` to CentOS based image:\n\n```bash\nexport CROSS_CONFIG=Cross-centos.toml\n```\n\n## Getting Started\n\nGenerate a safe and secured password for a specific encryption method (`aes-128-gcm` in the example) with:\n\n```bash\nssservice genkey -m \"aes-128-gcm\"\n```\n\nCreate a ShadowSocks' configuration file. Example\n\n```jsonc\n{\n    \"server\": \"my_server_ip\",\n    \"server_port\": 8388,\n    \"password\": \"rwQc8qPXVsRpGx3uW+Y3Lj4Y42yF9Bs0xg1pmx8/+bo=\",\n    \"method\": \"aes-256-gcm\",\n    // ONLY FOR `sslocal`\n    // Delete these lines if you are running `ssserver` or `ssmanager`\n    \"local_address\": \"127.0.0.1\",\n    \"local_port\": 1080\n}\n```\n\nDetailed explanation of the configuration file could be found in [shadowsocks' documentation](https://github.com/shadowsocks/shadowsocks/wiki). (Link to original project, not maintained anymore !)\n\n> :warning: For snap installations, configuration file is most probably located in `/var/snap/shadowsocks-rust/common/etc/shadowsocks-rust/config.json` (see <https://github.com/shadowsocks/shadowsocks-rust/issues/621> / <https://github.com/shadowsocks/shadowsocks-rust/issues/1146>)\n\nIn shadowsocks-rust, we also have an extended configuration file format, which is able to define more than one server. You can also disable individual servers.\n\n```jsonc\n{\n    \"servers\": [\n        {\n            \"server\": \"127.0.0.1\",\n            \"server_port\": 8388,\n            \"password\": \"rwQc8qPXVsRpGx3uW+Y3Lj4Y42yF9Bs0xg1pmx8/+bo=\",\n            \"method\": \"aes-256-gcm\",\n            \"timeout\": 7200\n        },\n        {\n            \"server\": \"127.0.0.1\",\n            \"server_port\": 8389,\n            \"password\": \"/dliNXn5V4jg6vBW4MnC1I8Jljg9x7vSihmk6UZpRBM=\",\n            \"method\": \"chacha20-ietf-poly1305\"\n        },\n        {\n            \"disabled\": true,\n            \"server\": \"eg.disable.me\",\n            \"server_port\": 8390,\n            \"password\": \"mGvbWWay8ueP9IHnV5F1uWGN2BRToiVCAWJmWOTLU24=\",\n            \"method\": \"chacha20-ietf-poly1305\"\n        }\n    ],\n    // ONLY FOR `sslocal`\n    // Delete these lines if you are running `ssserver` or `ssmanager`\n    \"local_port\": 1080,\n    \"local_address\": \"127.0.0.1\"\n}\n```\n\n`sslocal` automatically selects the best server with the lowest latency and the highest availability.\n\nStart Shadowsocks client and server with:\n\n```bash\nsslocal -c config.json\nssserver -c config.json\n```\n\nIf you Build it with Cargo:\n\n```bash\ncargo run --bin sslocal -- -c config.json\ncargo run --bin ssserver -- -c config.json\n```\n\nList all available arguments with `-h`.\n\n## Usage\n\nStart local client with configuration file\n\n```bash\n# Read local client configuration from file\nsslocal -c /path/to/shadowsocks.json\n```\n\n### Socks5 Local client\n\n```bash\n# Pass all parameters via command line\nsslocal -b \"127.0.0.1:1080\" -s \"[::1]:8388\" -m \"aes-256-gcm\" -k \"hello-kitty\" --plugin \"v2ray-plugin\" --plugin-opts \"server;tls;host=github.com\"\n\n# Pass server with SIP002 URL\nsslocal -b \"127.0.0.1:1080\" --server-url \"ss://YWVzLTI1Ni1nY206cGFzc3dvcmQ@127.0.0.1:8388/?plugin=v2ray-plugin%3Bserver%3Btls%3Bhost%3Dgithub.com\"\n```\n\n### HTTP Local client\n\n```bash\nsslocal -b \"127.0.0.1:3128\" --protocol http -s \"[::1]:8388\" -m \"aes-256-gcm\" -k \"hello-kitty\"\n```\n\nAll parameters are the same as Socks5 client, except `--protocol http`.\n\n### Tunnel Local client\n\n```bash\n# Set 127.0.0.1:8080 as the target for forwarding to\nsslocal --protocol tunnel -b \"127.0.0.1:3128\" -f \"127.0.0.1:8080\" -s \"[::1]:8388\" -m \"aes-256-gcm\" -k \"hello-kitty\"\n```\n\n- `--protocol tunnel` enables local client Tunnel mode\n- `-f \"127.0.0.1:8080` sets the tunnel target address\n\n### Transparent Proxy Local client\n\n**NOTE**: It currently only supports\n\n- Linux (with `iptables` targets `REDIRECT` and `TPROXY`)\n- BSDs (with `pf`), such as OS X 10.10+, FreeBSD, ...\n\n```bash\nsslocal -b \"127.0.0.1:60080\" --protocol redir -s \"[::1]:8388\" -m \"aes-256-gcm\" -k \"hello-kitty\" --tcp-redir \"redirect\" --udp-redir \"tproxy\"\n```\n\nRedirects connections with `iptables` configurations to the port that `sslocal` is listening on.\n\n- `--protocol redir` enables local client Redir mode\n- (optional) `--tcp-redir` sets TCP mode to `REDIRECT` (Linux)\n- (optional) `--udp-redir` sets UDP mode to `TPROXY` (Linux)\n\n### Tun interface client\n\n**NOTE**: It currently only supports\n\n- Linux, Android\n- macOS, iOS\n- Windows\n\n#### Linux\n\nCreate a Tun interface with name `tun0`\n\n```bash\nip tuntap add mode tun tun0\nifconfig tun0 inet 10.255.0.1 netmask 255.255.255.0 up\n```\n\nStart `sslocal` with `--protocol tun` and binds to `tun0`\n\n```bash\nsslocal --protocol tun -s \"[::1]:8388\" -m \"aes-256-gcm\" -k \"hello-kitty\" --outbound-bind-interface lo0 --tun-interface-name tun0\n```\n\n#### macOS\n\n```bash\nsslocal --protocol tun -s \"[::1]:8388\" -m \"aes-256-gcm\" -k \"hello-kitty\" --outbound-bind-interface lo0 --tun-interface-address 10.255.0.1/24\n```\n\nIt will create a Tun interface with address `10.255.0.1` and netmask `255.255.255.0`.\n\n#### Windows\n\nDownload `wintun.dll` from [Wintun](https://www.wintun.net/), and place it in the folder with shadowsocks' runnable binaries, or in the system PATH.\n\n```powershell\nsslocal --protocol tun -s \"[::1]:8388\" -m \"aes-256-gcm\" -k \"hello-kitty\" --outbound-bind-interface \"Ethernet 0\" --tun-interface-name \"shadowsocks\"\n```\n\n### Local client for Windows Service\n\nCompile it by enabling `--features \"winservice\"` (not included in the default build):\n\n```bash\ncargo build --release --bin \"sswinservice\" --features \"winservice\"\n```\n\nInstall it as a Windows Service (PowerShell):\n\n```powershell\nNew-Service -Name \"shadowsocks-local-service\" `\n            -DisplayName \"Shadowsocks Local Service\" `\n            -BinaryPathName \"<Path\\to>\\sswinservice.exe local -c <Path\\to>\\local_config.json\"\n```\n\nThere are other ways to install `sswinservice` as a Windows Service, for example, the `sc` command.\n\nAs you may have noticed that the `-BinaryPathName` contains not only just the `sswinservice.exe`, but `local -c local_config.json`. These command line parameters will be used as the default parameter when the Windows Service starts. You can also start the service with customized parameters.\n\nLearn more from [Microsoft's Document](https://learn.microsoft.com/en-us/dotnet/framework/windows-services/introduction-to-windows-service-applications).\n\nThe `sswinservice`'s parameter works exactly the same as `ssservice`. It supports `local`, `server` and `manager` subcommands.\n\n### Server\n\n```bash\n# Read server configuration from file\nssserver -c /path/to/shadowsocks.json\n\n# Pass all parameters via command line\nssserver -s \"[::]:8388\" -m \"aes-256-gcm\" -k \"hello-kitty\" --plugin \"v2ray-plugin\" --plugin-opts \"server;tls;host=github.com\"\n```\n\n### Server Manager\n\nSupported [Manage Multiple Users](https://github.com/shadowsocks/shadowsocks/wiki/Manage-Multiple-Users) API:\n\n- `add` - Starts a server instance\n- `remove` - Deletes an existing server instance\n- `list` - Lists all current running servers\n- `ping` - Lists all servers' statistic data\n\nNOTE: `stat` command is not supported. Because servers are running in the same process with the manager itself.\n\n```bash\n# Start it just with --manager-address command line parameter\nssmanager --manager-address \"127.0.0.1:6100\"\n\n# For *nix system, manager can bind to unix socket address\nssmanager --manager-address \"/tmp/shadowsocks-manager.sock\"\n\n# You can also provide a configuration file\n#\n# `manager_address` key must be provided in the configuration file\nssmanager -c /path/to/shadowsocks.json\n\n# Create one server by UDP\necho 'add: {\"server_port\":8388,\"password\":\"hello-kitty\"}' | nc -u '127.0.0.1' '6100'\n\n# Close one server by unix socket\necho 'remove: {\"server_port\":8388}' | nc -Uu '/tmp/shadowsocks-manager.sock'\n```\n\nFor manager UI, check more details in the [shadowsocks-manager](https://github.com/shadowsocks/shadowsocks-manager) project.\n\nExample configuration:\n\n```jsonc\n{\n    // Required option\n    // Address that ssmanager is listening on\n    \"manager_address\": \"127.0.0.1\",\n    \"manager_port\": 6100,\n\n    // Or bind to a Unix Domain Socket\n    \"manager_address\": \"/tmp/shadowsocks-manager.sock\",\n\n    \"servers\": [\n        // These servers will be started automatically when ssmanager is started\n    ],\n\n    // Outbound socket binds to this IP address\n    // For choosing different network interface on the same machine\n    \"local_address\": \"xxx.xxx.xxx.xxx\",\n\n    // Other options that may be passed directly to new servers\n}\n```\n\n## Configuration\n\n```jsonc\n{\n    // LOCAL: Listen address. This is exactly the same as `locals[0]`\n    // SERVER: Bind address for remote sockets, mostly used for choosing interface\n    //         Don't set it if you don't know what's this for.\n    \"local_address\": \"127.0.0.1\",\n    \"local_port\": 1080,\n\n    // Extended multiple local configuration\n    \"locals\": [\n        {\n            // Basic configuration, a SOCKS5 local server\n            \"local_address\": \"127.0.0.1\",\n            \"local_port\": 1080,\n            // OPTIONAL. Setting the `mode` for this specific local server instance.\n            // If not set, it will derive from the outer `mode`\n            \"mode\": \"tcp_and_udp\",\n            // OPTIONAL. Authentication configuration file\n            // Configuration file document could be found in the next section.\n            \"socks5_auth_config_path\": \"/path/to/auth.json\",\n            // OPTIONAL. Instance specific ACL\n            \"acl\": \"/path/to/acl/file.acl\",\n            // OPTIONAL. macOS launchd activate socket\n            \"launchd_tcp_socket_name\": \"TCPListener\",\n            \"launchd_udp_socket_name\": \"UDPListener\"\n        },\n        {\n            // SOCKS5, SOCKS4/4a local server\n            \"protocol\": \"socks\",\n            // Listen address\n            \"local_address\": \"127.0.0.1\",\n            \"local_port\": 1081,\n            // OPTIONAL. Enables UDP relay\n            \"mode\": \"tcp_and_udp\",\n            // OPTIONAL. Customizing the UDP's binding address. Depending on `mode`, if\n            // - TCP is enabled, then SOCKS5's UDP Association command will return this address\n            // - UDP is enabled, then SOCKS5's UDP server will listen to this address.\n            \"local_udp_address\": \"127.0.0.1\",\n            \"local_udp_port\": 2081,\n            // OPTIONAL. macOS launchd activate socket\n            \"launchd_tcp_socket_name\": \"TCPListener\",\n            \"launchd_udp_socket_name\": \"UDPListener\"\n        },\n        {\n            // Tunnel local server (feature = \"local-tunnel\")\n            \"protocol\": \"tunnel\",\n            // Listen address\n            \"local_address\": \"127.0.0.1\",\n            \"local_port\": 5353,\n            // Forward address, the target of this tunnel\n            // In this example, this will build a `127.0.0.1:5353` -> `8.8.8.8:53` tunnel\n            \"forward_address\": \"8.8.8.8\",\n            \"forward_port\": 53,\n            // OPTIONAL. Customizing whether to start TCP and UDP tunnel\n            \"mode\": \"tcp_only\",\n            // OPTIONAL. macOS launchd activate socket\n            \"launchd_tcp_socket_name\": \"TCPListener\",\n            \"launchd_udp_socket_name\": \"UDPListener\"\n        },\n        {\n            // HTTP local server (feature = \"local-http\")\n            \"protocol\": \"http\",\n            // Listen address\n            \"local_address\": \"127.0.0.1\",\n            \"local_port\": 3128,\n            // OPTIONAL. macOS launchd activate socket\n            \"launchd_tcp_socket_name\": \"TCPListener\",\n            // OPTIONAL. Authentication configuration file\n            // Configuration file document could be found in the next section.\n            \"http_auth_config_path\": \"/path/to/auth.json\",\n        },\n        {\n            // DNS local server (feature = \"local-dns\")\n            // This DNS works like China-DNS, it will send requests to `local_dns` and `remote_dns` and choose by ACL rules\n            \"protocol\": \"dns\",\n            // Listen address\n            \"local_address\": \"127.0.0.1\",\n            \"local_port\": 53,\n            // OPTIONAL. DNS local server uses `tcp_and_udp` mode by default\n            \"mode\": \"udp_only\",\n            // Local DNS address, DNS queries will be sent directly to this address\n            \"local_dns_address\": \"114.114.114.114\",\n            // OPTIONAL. Local DNS's port, 53 by default\n            \"local_dns_port\": 53,\n            // Remote DNS address, DNS queries will be sent through ssserver to this address\n            \"remote_dns_address\": \"8.8.8.8\",\n            // OPTIONAL. Remote DNS's port, 53 by default\n            \"remote_dns_port\": 53,\n            // OPTIONAL. dns client cache size for fetching dns queries.\n            \"client_cache_size\": 5,\n            // OPTIONAL. macOS launchd activate socket\n            \"launchd_tcp_socket_name\": \"TCPListener\",\n            \"launchd_udp_socket_name\": \"UDPListener\"\n        },\n        {\n            // Tun local server (feature = \"local-tun\")\n            \"protocol\": \"tun\",\n            // Tun interface name\n            \"tun_interface_name\": \"tun0\",\n            // Tun interface address\n            //\n            // It has to be a host address in CIDR form\n            \"tun_interface_address\": \"10.255.0.1/24\"\n        },\n        {\n            // Transparent Proxy (redir) local server (feature = \"local-redir\")\n            \"protocol\": \"redir\",\n            // OPTIONAL: TCP type, may be different between platforms\n            // Linux/Android: redirect (default), tproxy\n            // FreeBSD/OpenBSD: pf (default), ipfw\n            // NetBSD/macOS/Solaris: pf (default), ipfw\n            \"tcp_redir\": \"tproxy\",\n            // OPTIONAL: UDP type, may be different between platforms\n            // Linux/Android: tproxy (default)\n            // FreeBSD/OpenBSD: pf (default)\n            \"udp_redir\": \"tproxy\"\n        },\n        {\n            // FakeDNS local server (feature = \"local-fake-dns\")\n            // FakeDNS is a DNS server that allocates an IPv4 / IPv6 address in a specific pool for each queries.\n            // Subsequence requests from the other local interfaces that the target addresses includes those allocated IP addresses,\n            // will be substituted back to their original domain name addresses.\n            // This feature is useful mostly for transparent proxy, which will allow the proxied domain names to be resolved remotely.\n            \"protocol\": \"fake-dns\",\n            // Listen address\n            \"local_address\": \"127.0.0.1\",\n            \"local_port\": 10053,\n            // IPv4 address pool (for A records)\n            \"fake_dns_ipv4_network\": \"10.255.0.0/16\",\n            // IPv6 address pool (for AAAA records)\n            \"fake_dns_ipv6_network\": \"fdf2:e786:ab40:9d2f::/64\",\n            // Persistent storage for all allocated DNS records\n            \"fake_dns_database_path\": \"/var/shadowsocks/fakedns.db\",\n            // OPTIONAL: Record expire duration in seconds, 10s by default\n            \"fake_dns_record_expire_duration\": 10\n        }\n    ],\n\n    // Server configuration\n    // listen on :: for dual stack support, no need add [] around.\n    \"server\": \"::\",\n    // Change to use your custom port number\n    \"server_port\": 8388,\n    \"method\": \"aes-256-gcm\",\n    \"password\": \"your-password\",\n    \"plugin\": \"v2ray-plugin\",\n    \"plugin_opts\": \"mode=quic;host=github.com\",\n    \"plugin_args\": [\n        // Each line is an argument passed to \"plugin\"\n        \"--verbose\"\n    ],\n    \"plugin_mode\": \"tcp_and_udp\", // SIP003u, default is \"tcp_only\"\n    // Server: TCP socket timeout in seconds.\n    // Client: TCP connection timeout in seconds.\n    // Omit this field if you don't have specific needs.\n    \"timeout\": 7200,\n\n    // Extended multiple server configuration\n    // LOCAL: Choosing the best server to connect dynamically\n    // SERVER: Creating multiple servers in one process\n    \"servers\": [\n        {\n            // Fields are the same as the single server's configuration\n\n            // Individual servers can be disabled\n            // \"disabled\": true,\n            \"address\": \"0.0.0.0\",\n            \"port\": 8389,\n            \"method\": \"aes-256-gcm\",\n            \"password\": \"your-password\",\n            \"plugin\": \"...\",\n            \"plugin_opts\": \"...\",\n            \"plugin_args\": [],\n            \"plugin_mode\": \"...\",\n            \"timeout\": 7200,\n\n            // Customized weight for local server's balancer\n            //\n            // Weight must be in [0, 1], default is 1.0.\n            // The higher weight, the server may rank higher.\n            \"tcp_weight\": 1.0,\n            \"udp_weight\": 1.0,\n\n            // OPTIONAL. Instance specific ACL\n            \"acl\": \"/path/to/acl/file.acl\",\n        },\n        {\n            // Same key as basic format \"server\" and \"server_port\"\n            \"server\": \"0.0.0.0\",\n            \"server_port\": 8388,\n            \"method\": \"chacha20-ietf-poly1305\",\n            // Read the actual password from environment variable PASSWORD_FROM_ENV\n            \"password\": \"${PASSWORD_FROM_ENV}\"\n        },\n        {\n            // AEAD-2022\n            \"server\": \"::\",\n            \"server_port\": 8390,\n            \"method\": \"2022-blake3-aes-256-gcm\",\n            \"password\": \"3SYJ/f8nmVuzKvKglykRQDSgg10e/ADilkdRWrrY9HU=\",\n            // For Server (OPTIONAL)\n            // Support multiple users with Extensible Identity Header\n            // https://github.com/Shadowsocks-NET/shadowsocks-specs/blob/main/2022-2-shadowsocks-2022-extensible-identity-headers.md\n            \"users\": [\n                {\n                    \"name\": \"username\",\n                    // User's password must have the same length as server's password\n                    \"password\": \"4w0GKJ9U3Ox7CIXGU4A3LDQAqP6qrp/tUi/ilpOR9p4=\"\n                }\n            ],\n            // For Client (OPTIONAL)\n            // If EIH enabled, then \"password\" should have the following format: iPSK:iPSK:iPSK:uPSK\n            // - iPSK is one of the middle relay servers' PSK, for the last `ssserver`, it must be server's PSK (\"password\")\n            // - uPSK is the user's PSK (\"password\")\n            // Example:\n            // \"password\": \"3SYJ/f8nmVuzKvKglykRQDSgg10e/ADilkdRWrrY9HU=:4w0GKJ9U3Ox7CIXGU4A3LDQAqP6qrp/tUi/ilpOR9p4=\"\n        },\n        {\n            \"...\": \"Any other fields\",\n\n            // Some optional fields for this specific server\n\n            // Outbound socket options\n            // Linux Only (SO_MARK)\n            \"outbound_fwmark\": 255,\n            // FreeBSD only (SO_USER_COOKIE)\n            \"outbound_user_cookie\": 255,\n            // `SO_BINDTODEVICE` (Linux), `IP_BOUND_IF` (BSD), `IP_UNICAST_IF` (Windows) socket option for outbound sockets\n            \"outbound_bind_interface\": \"eth1\",\n            // Outbound socket bind() to this IP (choose a specific interface)\n            \"outbound_bind_addr\": \"11.22.33.44\",\n            // Outbound UDP socket allows IP fragmentation (default false)\n            \"outbound_udp_allow_fragmentation\": false,\n        }\n    ],\n\n    // Global configurations for UDP associations\n    \"udp_timeout\": 300, // Timeout for UDP associations (in seconds), 5 minutes by default\n    \"udp_max_associations\": 512, // Maximum UDP associations to be kept in one server, unlimited by default\n\n    // Options for Manager\n    \"manager_address\": \"127.0.0.1\", // Could be a path to UNIX socket, /tmp/shadowsocks-manager.sock\n    \"manager_port\": 5300, // Not needed for UNIX socket\n\n    // DNS server's address for resolving domain names\n    // For *NIX and Windows, it uses system's configuration by default\n    //\n    // Value could be IP address of DNS server, for example, \"8.8.8.8\".\n    // DNS client will automatically request port 53 with both TCP and UDP protocol.\n    //\n    // - system, uses system provided API (`getaddrinfo` on *NIX)\n    //\n    // It also allows some pre-defined well-known public DNS servers:\n    // - google (TCP, UDP)\n    // - cloudflare (TCP, UDP)\n    // - cloudflare_tls (TLS), enable by feature \"dns-over-tls\"\n    // - cloudflare_https (HTTPS), enable by feature \"dns-over-https\"\n    // - quad9 (TCP, UDP)\n    // - quad9_tls (TLS), enable by feature \"dns-over-tls\"\n    //\n    // The field is only effective if feature \"hickory-dns\" is enabled.\n    \"dns\": \"google\",\n    // Configure `cache_size` for \"hickory-dns\" ResolverOpts. Set to \"0\" to disable DNS cache.\n    \"dns_cache_size\": 0,\n\n    // Mode, could be one of the\n    // - tcp_only\n    // - tcp_and_udp\n    // - udp_only\n    \"mode\": \"tcp_only\",\n\n    // TCP_NODELAY\n    \"no_delay\": false,\n\n    // Enables `SO_KEEPALIVE` and set `TCP_KEEPIDLE`, `TCP_KEEPINTVL` to the specified seconds\n    \"keep_alive\": 15,\n\n    // Soft and Hard limit of file descriptors on *NIX systems\n    \"nofile\": 10240,\n\n    // Try to resolve domain name to IPv6 (AAAA) addresses first\n    \"ipv6_first\": false,\n    // Set IPV6_V6ONLY for all IPv6 listener sockets\n    // Only valid for locals and servers listening on `::`\n    \"ipv6_only\": false,\n\n    // Outbound socket options\n    // Linux Only (SO_MARK)\n    \"outbound_fwmark\": 255,\n    // FreeBSD only (SO_USER_COOKIE)\n    \"outbound_user_cookie\": 255,\n    // `SO_BINDTODEVICE` (Linux), `IP_BOUND_IF` (BSD), `IP_UNICAST_IF` (Windows) socket option for outbound sockets\n    \"outbound_bind_interface\": \"eth1\",\n    // Outbound socket bind() to this IP (choose a specific interface)\n    \"outbound_bind_addr\": \"11.22.33.44\",\n    // Outbound UDP socket allows IP fragmentation (default false)\n    \"outbound_udp_allow_fragmentation\": false,\n\n    // Balancer customization\n    \"balancer\": {\n        // MAX Round-Trip-Time (RTT) of servers\n        // The timeout seconds of each individual checks\n        \"max_server_rtt\": 5,\n        // Interval seconds between each check\n        \"check_interval\": 10,\n        // Interval seconds between each check for the best server\n        // Optional. Specify to enable shorter checking interval for the best server only.\n        \"check_best_interval\": 5\n    },\n\n    // SIP008 Online Configuration Delivery\n    // https://shadowsocks.org/doc/sip008.html\n    \"online_config\": {\n        \"config_url\": \"https://path-to-online-sip008-configuration\",\n        // Optional. Seconds between each update to config_url. Default to 3600s\n        \"update_interval\": 3600,\n        // Optional. Whitelist of plugins (RECOMMENDED for all users)\n        // SECURITY: To avoid executing untrusted commands loaded from config_url\n        \"allowed_plugins\": [\n            \"v2ray-plugin\"\n        ]\n    },\n\n    // Service configurations\n    // Logger configuration\n    \"log\": {\n        // Default log level to use, if not overridden by `writers`, default is `0`\n        // Equivalent to `-v` command line option\n        \"level\": 1,\n        // Default log format to use, if not overridden by `writers`\n        \"format\": {\n            // Euiqvalent to `--log-without-time`, default is `false`\n            \"without_time\": false,\n        },\n        // Advanced logging configuration for configuring multiple writers\n        // A console writer will be configured by default.\n        // Set this to empty array `[]` to disable logging completely\n        \"writers\": [\n            {\n                // Configure a console writer\n                // The inner fields are optional, if not set, it will use the default values\n                // To minimally configure a console writer, simply write `\"console\": {}`.\n                \"console\": {\n                    \"level\": 2,\n                    \"format\": {\n                        \"without_time\": false,\n                    }\n                }\n            },\n            {\n                // Configure a file writer, useful when running as a Windows Service\n                \"file\": {\n                    // `level` and `format` can also be set here, if not set, it will use the default values\n                    \n                    // Required. Directory to store log files\n                    \"directory\": \"/var/log/shadowsocks-rust\",\n                    // Optional. Log rotation frequency, must be one of the following:\n                    // - never (default): This will result in log file located at `directory/prefix.suffix`\n                    // - daily: A new log file in the format of `directory/prefix.yyyy-MM-dd.suffix` will be created daily\n                    // - hourly: A new log file in the format of `directory/prefix.yyyy-MM-dd-HH.suffix` will be created hourly\n                    \"rotation\": \"never\",\n                    // Optional. Prefix of log file, default is one of `sslocal`, `ssserver`, `ssmanager` depending on the service being run.\n                    \"prefix\": \"shadowsocks-rust\",\n                    // Optional. Suffix of log file, default is `log`\n                    \"suffix\": \"log\",\n                    // Optional. If set, keeps the last N log files\n                    \"max_files\": 5\n                }\n            },\n            {\n                // Configure a syslog writer, only supported on *nix system\n                \"syslog\": {\n                    // `level` and `format` can also be set here, if not set, it will use the default values\n\n                    // Optional. Set the \"identity\" when calling openlog(). Use current service name by default.\n                    \"identity\": \"identity_name\",\n                    // Optional. Set the \"facility\" when calling openlog(). 1 (user-level messages) by default. See RFC5424.\n                    \"facility\": 1\n                }\n            }\n        ]\n    },\n    // Runtime configuration\n    \"runtime\": {\n        // `single_thread` or `multi_thread`\n        \"mode\": \"multi_thread\",\n        // Worker threads that are used in multi-thread runtime\n        \"worker_count\": 10\n    }\n}\n```\n\n### SOCKS5 Authentication Configuration\n\nThe configuration file is set by `socks5_auth_config_path` in `locals`.\n\n```jsonc\n{\n    // Password/Username Authentication (RFC1929)\n    \"password\": {\n        \"users\": [\n            {\n                \"user_name\": \"USERNAME in UTF-8\",\n                \"password\": \"PASSWORD in UTF-8\"\n            }\n        ]\n    }\n}\n```\n\n### HTTP Authentication Configuration\n\nThe configuration file is set by `http_auth_config_path` in `locals`.\n\n```jsonc\n{\n    // Basic Authentication (RFC9110)\n    \"basic\": {\n        \"users\": [\n            {\n                \"user_name\": \"USERNAME in UTF-8\",\n                \"password\": \"PASSWORD in UTF-8\"\n            }\n        ]\n    }\n}\n```\n\n### Environment Variables\n\n- `SS_SERVER_PASSWORD`: A default password for servers that created from command line argument (`--server-addr`)\n- `SS_SYSTEM_DNS_RESOLVER_FORCE_BUILTIN`: `\"system\"` DNS resolver force use system's builtin (`getaddrinfo` in *NIX)\n\n## Supported Ciphers\n\n### AEAD 2022 Ciphers\n\n- `2022-blake3-aes-128-gcm`, `2022-blake3-aes-256-gcm`\n- `2022-blake3-chacha20-poly1305`, `2022-blake3-chacha8-poly1305`\n\nThese Ciphers require `\"password\"` to be a Base64 string of key that have **exactly the same length** of Cipher's Key Size. It is recommended to use `ssservice genkey -m \"METHOD_NAME\"` to generate a secured and safe key.\n\n### AEAD Ciphers\n\n- `chacha20-ietf-poly1305`\n- `aes-128-gcm`, `aes-256-gcm`\n\n### Stream Ciphers\n\n- `plain` or `none` (No encryption, only used for debugging or with plugins that ensure transport security)\n\n<details><summary>Deprecated</summary>\n<p>\n\n- `table`\n- `aes-128-cfb`, `aes-128-cfb1`, `aes-128-cfb8`, `aes-128-cfb128`\n- `aes-192-cfb`, `aes-192-cfb1`, `aes-192-cfb8`, `aes-192-cfb128`\n- `aes-256-cfb`, `aes-256-cfb1`, `aes-256-cfb8`, `aes-256-cfb128`\n- `aes-128-ctr`\n- `aes-192-ctr`\n- `aes-256-ctr`\n- `camellia-128-cfb`, `camellia-128-cfb1`, `camellia-128-cfb8`, `camellia-128-cfb128`\n- `camellia-192-cfb`, `camellia-192-cfb1`, `camellia-192-cfb8`, `camellia-192-cfb128`\n- `camellia-256-cfb`, `camellia-256-cfb1`, `camellia-256-cfb8`, `camellia-256-cfb128`\n- `rc4-md5`\n- `chacha20-ietf`\n\n</p>\n</details>\n\n## ACL\n\n`sslocal`, `ssserver`, and `ssmanager` support ACL file with syntax like [shadowsocks-libev](https://github.com/shadowsocks/shadowsocks-libev). Some examples could be found in [here](https://github.com/shadowsocks/shadowsocks-libev/tree/master/acl).\n\n### Available sections\n\n- For local servers (`sslocal`, `ssredir`, ...)\n  - Modes:\n    - `[bypass_all]` - ACL runs in `WhiteList` mode. Bypasses all addresses except those matching any rules.\n    - `[proxy_all]` - ACL runs in `BlackList` mode. Proxies all addresses except those matching any rules. (default)\n  - Rules:\n    - `[bypass_list]` - Rules for connecting directly\n    - `[proxy_list]` - Rules for connecting through proxies\n- For remote servers (`ssserver`)\n  - Modes:\n    - `[reject_all]` - ACL runs in `WhiteList` mode. Rejects all clients except those matching any rules.\n    - `[accept_all]` - ACL runs in `BlackList` mode. Accepts all clients except those matching any rules. (default)\n    - `[outbound_block_all]` - Outbound ACL runs in `WhiteList` mode. Blocks all outbound addresses except those matching any rules.\n    - `[outbound_allow_all]` - Outbound ACL runs in `BlackList` mode. Allows all outbound addresses except those matching any rules. (default)\n  - Rules:\n    - `[white_list]` - Rules for accepted clients\n    - `[black_list]` - Rules for rejected clients\n    - `[outbound_block_list]` - Rules for blocking outbound addresses.\n    - `[outbound_allow_list]` - Rules for allowing outbound addresses.\n\n### Example\n\n```ini\n# SERVERS\n# For ssserver, accepts requests from all clients by default\n[accept_all]\n\n# Blocks these clients\n[black_list]\n1.2.3.4\n127.0.0.1/8\n\n# Disallow these outbound addresses\n[outbound_block_list]\n127.0.0.1/8\n::1\n# Using regular expression\n^[a-z]{5}\\.baidu\\.com\n# Match exactly\n|baidu.com\n# Match with subdomains\n||google.com\n# An internationalized domain name should be converted to punycode\n# |☃-⌘.com - WRONG\n|xn----dqo34k.com\n# ||джpумлатест.bрфa - WRONG\n||xn--p-8sbkgc5ag7bhce.xn--ba-lmcq\n\n# CLIENTS\n# For sslocal, ..., bypasses all targets by default\n[bypass_all]\n\n# Proxy these addresses\n[proxy_list]\n||google.com\n8.8.8.8\n```\n\n## Useful Tools\n\n1. `ssurl` is for encoding and decoding ShadowSocks URLs (SIP002). Example:\n\n  ```plain\n  ss://YWVzLTI1Ni1jZmI6cGFzc3dvcmQ@127.0.0.1:8388/?plugin=obfs-local%3Bobfs%3Dhttp%3Bobfs-host%3Dwww.baidu.com\n  ```\n\n## Notes\n\nIt supports the following features:\n\n- [x] SOCKS5 CONNECT command\n- [x] SOCKS5 UDP ASSOCIATE command (partial)\n- [x] SOCKS4/4a CONNECT command\n- [x] Various crypto algorithms\n- [x] Load balancing (multiple servers) and server delay checking\n- [x] [SIP004](https://github.com/shadowsocks/shadowsocks-org/issues/30) AEAD ciphers\n- [x] [SIP003](https://github.com/shadowsocks/shadowsocks-org/issues/28) Plugins\n- [x] [SIP003u](https://github.com/shadowsocks/shadowsocks-org/issues/180) Plugin with UDP support\n- [x] [SIP002](https://github.com/shadowsocks/shadowsocks-org/issues/27) Extension ss URLs\n- [x] [SIP022](https://github.com/shadowsocks/shadowsocks-org/issues/196) AEAD 2022 ciphers\n- [x] HTTP Proxy Supports ([RFC 7230](http://tools.ietf.org/html/rfc7230) and [CONNECT](https://tools.ietf.org/html/draft-luotonen-web-proxy-tunneling-01))\n- [x] Defend against replay attacks, [shadowsocks/shadowsocks-org#44](https://github.com/shadowsocks/shadowsocks-org/issues/44)\n- [x] Manager APIs, supporting [Manage Multiple Users](https://github.com/shadowsocks/shadowsocks/wiki/Manage-Multiple-Users)\n- [x] ACL (Access Control List)\n- [x] Support HTTP/HTTPS Proxy protocol\n\n## TODO\n\n- [x] Documentation\n- [x] Extend configuration format\n- [x] Improved logging format (waiting for the new official log crate)\n- [x] Support more ciphers without depending on `libcrypto` (waiting for an acceptable Rust crypto lib implementation)\n- [x] Windows support.\n- [x] Build with stable `rustc` ~~(blocking by `crypto2`)~~.\n- [x] Support HTTP Proxy protocol\n- [x] AEAD ciphers. (proposed in [SIP004](https://github.com/shadowsocks/shadowsocks-org/issues/30), still under discussion)\n- [x] Choose server based on delay #152\n\n## License\n\n[The MIT License (MIT)](https://opensource.org/licenses/MIT)\n\nCopyright (c) 2014 Y. T. CHUNG\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n## Stargazers over time\n\n[![Stargazers over time](https://starchart.cc/shadowsocks/shadowsocks-rust.svg)](https://starchart.cc/shadowsocks/shadowsocks-rust)\n"
  },
  {
    "path": "acl/genacl_proxy_gfw_bypass_china_ip.py",
    "content": "#!/usr/bin/env python3\n\nfrom urllib import request, parse\nimport logging\nimport sys\nimport json\nfrom datetime import datetime\n\nlogging.basicConfig(level=logging.INFO)\nlogger = logging.getLogger(__name__)\n\nGFW_TRANSLATED_URL = \"https://raw.githubusercontent.com/NateScarlet/gfwlist.acl/master/gfwlist.acl.json\"\nCHINA_IP_LIST_URL = \"https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt\"\nCUSTOM_BYPASS = [\n    \"127.0.0.1\",\n    \"10.0.0.0/8\",\n    \"172.16.0.0/12\",\n    \"192.168.0.0/16\",\n    \"fd00::/8\",\n]\nCUSTOM_PROXY = [\n\n]\n\n\ndef fetch_url_content(url):\n    logger.info(\"FETCHING {}\".format(url))\n    r = request.urlopen(url)\n    return r.read()\n\n\ndef write_gfw_list(fp):\n    gfw_json = fetch_url_content(GFW_TRANSLATED_URL)\n    gfw_obj = json.loads(gfw_json)\n    for line in gfw_obj[\"blacklist\"]:\n        fp.write(line.encode(\"utf-8\"))\n        fp.write(b\"\\n\")\n\n\ndef write_china_ip(fp):\n    china_ip_list = fetch_url_content(CHINA_IP_LIST_URL)\n    fp.write(china_ip_list)\n    fp.write(b\"\\n\")\n\n\ntry:\n    output_file_path = sys.argv[1]\nexcept:\n    output_file_path = \"shadowsocks.acl\"\n\nlogger.info(\"WRITING {}\".format(output_file_path))\n\nwith open(output_file_path, 'wb') as fp:\n    now = datetime.now()\n\n    fp.write(b\"# Generated by genacl.py\\n\")\n    fp.write(\"# Time: {}\\n\".format(now.isoformat()).encode(\"utf-8\"))\n    fp.write(b\"\\n\")\n\n    fp.write(b\"[proxy_all]\\n\")\n    fp.write(b\"\\n[proxy_list]\\n\")\n    write_gfw_list(fp)\n    fp.write(b\"\\n[bypass_list]\\n\")\n    write_china_ip(fp)\n\n    if len(CUSTOM_BYPASS) > 0:\n        logger.info(\"CUSTOM_BYPASS {} lines\".format(len(CUSTOM_BYPASS)))\n        fp.write(b\"\\n[bypass_list]\\n\")\n        for a in CUSTOM_BYPASS:\n            fp.write(a.encode(\"utf-8\"))\n            fp.write(b\"\\n\")\n\n    if len(CUSTOM_PROXY) > 0:\n        logger.info(\"CUSTOM_PROXY {} lines\".format(len(CUSTOM_PROXY)))\n        fp.write(b\"\\n[proxy_list]\\n\")\n        for a in CUSTOM_PROXY:\n            fp.write(a.encode(\"utf-8\"))\n            fp.write(b\"\\n\")\n\nlogger.info(\"DONE\")\n"
  },
  {
    "path": "appveyor.yml",
    "content": "environment:\n  SSL_CERT_FILE: \"C:\\\\OpenSSL\\\\cacert.pem\"\n\n  matrix:\n    - TARGET: x86_64-pc-windows-msvc\n      BITS: 64\n      MSYS2: 1\n      OPENSSL_DIR: C:\\OpenSSL-Win64\n      RUST_BACKTRACE: 1\n    # - TARGET: i686-pc-windows-gnu\n    #   BITS: 32\n    #   OPENSSL_DIR: C:\\OpenSSL-Win32\n    #   MSYS2: 1\n    #   SODIUM_BUILD_STATIC: yes\n    #   RUST_BACKTRACE: 1\ninstall:\n  # Install Rust\n  - appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe\n  - rustup-init.exe -y --default-host %TARGET%\n  - set PATH=%PATH%;%USERPROFILE%\\.cargo\\bin\n  - if defined MSYS2 set PATH=C:\\msys64\\mingw%BITS%\\bin;%PATH%\n\n  # Run tests\n  - rustc -V\n  - cargo -V\n\nbuild: false\n\ntest_script:\n  - cargo test --no-fail-fast\n\ncache:\n  - target\n  - C:\\Users\\appveyor\\.cargo\\registry\n"
  },
  {
    "path": "bin/sslocal.rs",
    "content": "//! This is a binary running in the local environment\n//!\n//! You have to provide all needed configuration attributes via command line parameters,\n//! or you could specify a configuration file. The format of configuration file is defined\n//! in mod `config`.\n\nuse std::process::ExitCode;\n\nuse clap::Command;\nuse shadowsocks_rust::service::local;\n\nfn main() -> ExitCode {\n    let mut app = Command::new(\"shadowsocks\")\n        .version(shadowsocks_rust::VERSION)\n        .about(\"A fast tunnel proxy that helps you bypass firewalls. (https://shadowsocks.org)\");\n    app = local::define_command_line_options(app);\n\n    let matches = app.get_matches();\n    local::main(&matches)\n}\n"
  },
  {
    "path": "bin/ssmanager.rs",
    "content": "//! This is a binary running in the server environment\n//!\n//! You have to provide all needed configuration attributes via command line parameters,\n//! or you could specify a configuration file. The format of configuration file is defined\n//! in mod `config`.\n//!\n//! *It should be notice that the extended configuration file is not suitable for the server\n//! side.*\n\nuse std::process::ExitCode;\n\nuse clap::Command;\nuse shadowsocks_rust::service::manager;\n\nfn main() -> ExitCode {\n    let mut app = Command::new(\"shadowsocks\")\n        .version(shadowsocks_rust::VERSION)\n        .about(\"A fast tunnel proxy that helps you bypass firewalls. (https://shadowsocks.org)\");\n    app = manager::define_command_line_options(app);\n\n    let matches = app.get_matches();\n    manager::main(&matches)\n}\n"
  },
  {
    "path": "bin/ssserver.rs",
    "content": "//! This is a binary running in the server environment\n//!\n//! You have to provide all needed configuration attributes via command line parameters,\n//! or you could specify a configuration file. The format of configuration file is defined\n//! in mod `config`.\n//!\n//! *It should be notice that the extended configuration file is not suitable for the server\n//! side.*\n\nuse std::process::ExitCode;\n\nuse clap::Command;\nuse shadowsocks_rust::service::server;\n\nfn main() -> ExitCode {\n    let mut app = Command::new(\"shadowsocks\")\n        .version(shadowsocks_rust::VERSION)\n        .about(\"A fast tunnel proxy that helps you bypass firewalls. (https://shadowsocks.org)\");\n    app = server::define_command_line_options(app);\n\n    let matches = app.get_matches();\n    server::main(&matches)\n}\n"
  },
  {
    "path": "bin/ssservice.rs",
    "content": "//! This is a binary running in both local and server environment\n//!\n//! You have to provide all needed configuration attributes via command line parameters,\n//! or you could specify a configuration file. The format of configuration file is defined\n//! in mod `config`.\n//!\n//! *It should be notice that the extended configuration file is not suitable for the server\n//! side.*\n\nuse std::{env, path::Path, process::ExitCode};\n\nuse clap::Command;\nuse shadowsocks_rust::service::{genkey, local, manager, server};\n\nfn main() -> ExitCode {\n    let app = Command::new(\"shadowsocks\")\n        .version(shadowsocks_rust::VERSION)\n        .about(\"A fast tunnel proxy that helps you bypass firewalls. (https://shadowsocks.org)\");\n\n    // Allow running `ssservice` as symlink of `sslocal`, `ssserver` and `ssmanager`\n    if let Some(program_path) = env::args().next()\n        && let Some(program_name) = Path::new(&program_path).file_name()\n    {\n        match program_name.to_str() {\n            Some(\"sslocal\") => return local::main(&local::define_command_line_options(app).get_matches()),\n            Some(\"ssserver\") => return server::main(&server::define_command_line_options(app).get_matches()),\n            Some(\"ssmanager\") => return manager::main(&manager::define_command_line_options(app).get_matches()),\n            _ => {}\n        }\n    }\n\n    let matches = app\n        .subcommand_required(true)\n        .subcommand(local::define_command_line_options(Command::new(\"local\")).about(\"Shadowsocks Local service\"))\n        .subcommand(server::define_command_line_options(Command::new(\"server\")).about(\"Shadowsocks Server service\"))\n        .subcommand(\n            manager::define_command_line_options(Command::new(\"manager\")).about(\"Shadowsocks Server Manager service\"),\n        )\n        .subcommand(\n            genkey::define_command_line_options(Command::new(\"genkey\"))\n                .about(\"Generate shadowsocks encryption key for method\"),\n        )\n        .get_matches();\n\n    match matches.subcommand() {\n        Some((\"local\", matches)) => local::main(matches),\n        Some((\"server\", matches)) => server::main(matches),\n        Some((\"manager\", matches)) => manager::main(matches),\n        Some((\"genkey\", matches)) => genkey::main(matches),\n        _ => unreachable!(\"expecting a subcommand\"),\n    }\n}\n"
  },
  {
    "path": "bin/ssurl.rs",
    "content": "//! SIP002 and SIP008 URL Schemes\n//!\n//! SS-URI = \"ss://\" userinfo \"@\" hostname \":\" port [ \"/\" ] [ \"?\" plugin ] [ \"#\" tag ]\n//! userinfo = websafe-base64-encode-utf8(method  \":\" password)\n\nuse std::process::ExitCode;\n\nuse clap::{Arg, ArgAction, Command, ValueHint};\nuse qrcode::{QrCode, types::Color};\n\nuse shadowsocks_service::{\n    config::{Config, ConfigType, ServerInstanceConfig},\n    shadowsocks::config::ServerConfig,\n};\n\n/// shadowsocks version\nconst VERSION: &str = env!(\"CARGO_PKG_VERSION\");\n\nconst BLACK: &str = \"\\x1b[40m  \\x1b[0m\";\nconst WHITE: &str = \"\\x1b[47m  \\x1b[0m\";\n\nfn print_qrcode(encoded: &str) {\n    let qrcode = QrCode::new(encoded.as_bytes()).unwrap();\n\n    for _ in 0..qrcode.width() + 2 {\n        print!(\"{WHITE}\");\n    }\n    println!();\n\n    for y in 0..qrcode.width() {\n        print!(\"{WHITE}\");\n        for x in 0..qrcode.width() {\n            let color = match qrcode[(x, y)] {\n                Color::Light => WHITE,\n                Color::Dark => BLACK,\n            };\n\n            print!(\"{color}\");\n        }\n        println!(\"{WHITE}\");\n    }\n\n    for _ in 0..qrcode.width() + 2 {\n        print!(\"{WHITE}\");\n    }\n    println!();\n}\n\nfn encode(filename: &str, need_qrcode: bool) {\n    let config = Config::load_from_file(filename, ConfigType::Server).unwrap();\n\n    for svr in config.server {\n        let encoded = svr.config.to_url();\n\n        println!(\"{encoded}\");\n\n        if need_qrcode {\n            let encoded = svr.config.to_qrcode_url();\n            print_qrcode(&encoded);\n        }\n    }\n}\n\nfn decode(encoded: &str, need_qrcode: bool) {\n    let svrconfig = ServerConfig::from_url(encoded).unwrap();\n\n    let mut config = Config::new(ConfigType::Server);\n    config.server.push(ServerInstanceConfig::with_server_config(svrconfig));\n\n    println!(\"{config}\");\n\n    if need_qrcode {\n        print_qrcode(encoded);\n    }\n}\n\n#[cfg(feature = \"utility-url-outline\")]\nfn decode_outline(remote: &str, need_qrcode: bool) {\n    // Protect from using http and other non-ssconf links in reqwest call\n    if !remote.starts_with(\"ssconf\") {\n        println!(\"Incorrect link format\");\n        return;\n    }\n\n    let url = remote.replace(\"ssconf\", \"https\");\n    let svrconfig = ServerConfig::from_url(reqwest::blocking::get(url).unwrap().text().unwrap().as_str()).unwrap();\n\n    let mut config = Config::new(ConfigType::Server);\n    config.server.push(ServerInstanceConfig::with_server_config(svrconfig));\n\n    println!(\"{config}\");\n\n    if need_qrcode {\n        print_qrcode(remote);\n    }\n}\n\nfn main() -> ExitCode {\n    let mut app = Command::new(\"ssurl\")\n        .version(VERSION)\n        .about(\"Encode and decode ShadowSocks URL\")\n        .arg(\n            Arg::new(\"ENCODE_CONFIG_PATH\")\n                .short('e')\n                .long(\"encode\")\n                .action(ArgAction::Set)\n                .value_hint(ValueHint::FilePath)\n                .conflicts_with(\"DECODE_CONFIG_PATH\")\n                .required_unless_present_any([\"DECODE_CONFIG_PATH\", \"OUTLINE_CONFIG_URL\"])\n                .help(\"Encode the server configuration in the provided JSON file\"),\n        )\n        .arg(\n            Arg::new(\"DECODE_CONFIG_PATH\")\n                .short('d')\n                .long(\"decode\")\n                .action(ArgAction::Set)\n                .value_hint(ValueHint::FilePath)\n                .required_unless_present_any([\"ENCODE_CONFIG_PATH\", \"OUTLINE_CONFIG_URL\"])\n                .help(\"Decode the server configuration from the provided ShadowSocks URL\"),\n        )\n        .arg(\n            Arg::new(\"QRCODE\")\n                .short('c')\n                .long(\"qrcode\")\n                .action(ArgAction::SetTrue)\n                .help(\"Generate the QRCode with the provided configuration\"),\n        );\n\n    if cfg!(feature = \"utility-url-outline\") {\n        app = app.arg(\n            Arg::new(\"OUTLINE_CONFIG_URL\")\n                .short('o')\n                .long(\"outline\")\n                .value_hint(ValueHint::Url)\n                .required_unless_present_any([\"ENCODE_CONFIG_PATH\", \"DECODE_CONFIG_PATH\"])\n                .help(\"Fetch and decode config from ssconf URL used by Outline\"),\n        );\n    }\n\n    let matches = app.get_matches();\n\n    let need_qrcode = matches.get_flag(\"QRCODE\");\n\n    if let Some(file) = matches.get_one::<String>(\"ENCODE_CONFIG_PATH\") {\n        encode(file, need_qrcode);\n        return ExitCode::SUCCESS;\n    }\n\n    if let Some(encoded) = matches.get_one::<String>(\"DECODE_CONFIG_PATH\") {\n        decode(encoded, need_qrcode);\n        return ExitCode::SUCCESS;\n    }\n\n    #[cfg(feature = \"utility-url-outline\")]\n    if let Some(remote) = matches.get_one::<String>(\"OUTLINE_CONFIG_URL\") {\n        decode_outline(remote, need_qrcode);\n        return ExitCode::SUCCESS;\n    }\n\n    println!(\"Use -h for more detail\");\n    ExitCode::FAILURE\n}\n"
  },
  {
    "path": "bin/sswinservice.rs",
    "content": "use std::{\n    ffi::OsString,\n    future::Future,\n    sync::atomic::{AtomicU32, Ordering},\n    time::Duration,\n};\n\nuse clap::Command;\nuse log::{error, info};\nuse shadowsocks_rust::{\n    error::ShadowsocksResult,\n    service::{local, manager, server},\n};\nuse tokio::{runtime::Runtime, sync::oneshot};\nuse windows_service::{\n    define_windows_service,\n    service::{ServiceControl, ServiceControlAccept, ServiceExitCode, ServiceState, ServiceStatus, ServiceType},\n    service_control_handler::{self, ServiceControlHandlerResult, ServiceStatusHandle},\n    service_dispatcher,\n};\n\nconst SERVICE_NAME: &str = \"ssservice\";\nconst SERVICE_EXIT_CODE_ARGUMENT_ERROR: u32 = 100;\nconst SERVICE_EXIT_CODE_EXITED_UNEXPECTEDLY: u32 = 101;\nconst SERVICE_EXIT_CODE_CREATE_FAILED: u32 = 102;\n\n#[inline]\nfn set_service_status(\n    handle: &ServiceStatusHandle,\n    current_state: ServiceState,\n    exit_code: ServiceExitCode,\n    wait_hint: Duration,\n) -> Result<(), windows_service::Error> {\n    static SERVICE_STATE_CHECKPOINT: AtomicU32 = AtomicU32::new(0);\n\n    let next_status = ServiceStatus {\n        service_type: ServiceType::OWN_PROCESS,\n        current_state,\n        controls_accepted: if current_state == ServiceState::StartPending {\n            ServiceControlAccept::empty()\n        } else {\n            ServiceControlAccept::STOP\n        },\n        exit_code,\n        checkpoint: if matches!(current_state, ServiceState::Running | ServiceState::Stopped) {\n            SERVICE_STATE_CHECKPOINT.fetch_add(1, Ordering::AcqRel)\n        } else {\n            0\n        },\n        wait_hint,\n        process_id: None,\n    };\n    handle.set_service_status(next_status)\n}\n\nfn handle_create_service_result<F>(\n    status_handle: ServiceStatusHandle,\n    create_service_result: ShadowsocksResult<(Runtime, F)>,\n    stop_receiver: oneshot::Receiver<()>,\n) -> Result<(), windows_service::Error>\nwhere\n    F: Future<Output = ShadowsocksResult>,\n{\n    match create_service_result {\n        Ok((runtime, main_fut)) => {\n            // Successfully create runtime and future\n\n            // Report running state\n            set_service_status(\n                &status_handle,\n                ServiceState::Running,\n                ServiceExitCode::Win32(0),\n                Duration::default(),\n            )?;\n\n            // Run it right now.\n            let exited_by_ctrl = runtime.block_on(async move {\n                tokio::pin!(main_fut);\n                tokio::pin!(stop_receiver);\n\n                loop {\n                    tokio::select! {\n                        _ = stop_receiver => {\n                            break true;\n                        }\n                        exit_code = main_fut => {\n                            info!(\"service exited unexpectedly with code: {:?}\", exit_code);\n                            break false;\n                        }\n                    }\n                }\n            });\n\n            // Report stopped state\n            set_service_status(\n                &status_handle,\n                ServiceState::Stopped,\n                if exited_by_ctrl {\n                    ServiceExitCode::Win32(0)\n                } else {\n                    ServiceExitCode::ServiceSpecific(SERVICE_EXIT_CODE_EXITED_UNEXPECTEDLY)\n                },\n                Duration::default(),\n            )?;\n        }\n        Err(err) => {\n            error!(\"failed to create service, exit code: {:?}\", err.exit_code());\n\n            // Report running state\n            set_service_status(\n                &status_handle,\n                ServiceState::Stopped,\n                ServiceExitCode::ServiceSpecific(SERVICE_EXIT_CODE_CREATE_FAILED),\n                Duration::default(),\n            )?;\n        }\n    }\n\n    Ok(())\n}\n\nfn service_main(arguments: Vec<OsString>) -> Result<(), windows_service::Error> {\n    // Create a Oneshot channel for receiving Stop event\n    let (stop_sender, stop_receiver) = oneshot::channel();\n\n    let mut stop_sender_opt = Some(stop_sender);\n    let event_handler = move |control_event| -> ServiceControlHandlerResult {\n        match control_event {\n            ServiceControl::Stop => {\n                if let Some(stop_sender) = stop_sender_opt.take() {\n                    let _ = stop_sender.send(());\n                }\n                ServiceControlHandlerResult::NoError\n            }\n            ServiceControl::Interrogate => ServiceControlHandlerResult::NoError,\n            _ => ServiceControlHandlerResult::NotImplemented,\n        }\n    };\n\n    // Register system service event handler\n    let status_handle = service_control_handler::register(SERVICE_NAME, event_handler)?;\n\n    // Report SERVICE_START_PENDING\n    // https://learn.microsoft.com/en-us/windows/win32/services/writing-a-servicemain-function\n    set_service_status(\n        &status_handle,\n        ServiceState::StartPending,\n        ServiceExitCode::Win32(0),\n        Duration::from_secs(30),\n    )?;\n\n    let app = Command::new(\"shadowsocks service\")\n        .version(shadowsocks_rust::VERSION)\n        .about(\"A fast tunnel proxy that helps you bypass firewalls. (https://shadowsocks.org)\");\n\n    let app = app\n        .subcommand_required(true)\n        .subcommand(local::define_command_line_options(Command::new(\"local\")).about(\"Shadowsocks Local service\"))\n        .subcommand(server::define_command_line_options(Command::new(\"server\")).about(\"Shadowsocks Server service\"))\n        .subcommand(\n            manager::define_command_line_options(Command::new(\"manager\")).about(\"Shadowsocks Server Manager service\"),\n        );\n\n    let matches_result = if arguments.len() <= 1 {\n        app.try_get_matches()\n    } else {\n        app.try_get_matches_from(arguments)\n    };\n\n    let matches = match matches_result {\n        Ok(m) => m,\n        Err(err) => {\n            error!(\"failed to parse command line arguments, error: {}\", err);\n            set_service_status(\n                &status_handle,\n                ServiceState::Stopped,\n                ServiceExitCode::ServiceSpecific(SERVICE_EXIT_CODE_ARGUMENT_ERROR),\n                Duration::default(),\n            )?;\n            return Err(windows_service::Error::LaunchArgumentsNotSupported);\n        }\n    };\n\n    match matches.subcommand() {\n        Some((\"local\", matches)) => handle_create_service_result(status_handle, local::create(matches), stop_receiver),\n        Some((\"server\", matches)) => {\n            handle_create_service_result(status_handle, server::create(matches), stop_receiver)\n        }\n        Some((\"manager\", matches)) => {\n            handle_create_service_result(status_handle, manager::create(matches), stop_receiver)\n        }\n        _ => Err(windows_service::Error::LaunchArgumentsNotSupported),\n    }\n}\n\nfn service_entry(arguments: Vec<OsString>) {\n    if let Err(err) = service_main(arguments) {\n        error!(\"service main exited with error: {}\", err);\n    }\n}\n\ndefine_windows_service!(ffi_service_entry, service_entry);\n\nfn main() -> Result<(), windows_service::Error> {\n    service_dispatcher::start(SERVICE_NAME, ffi_service_entry)?;\n    Ok(())\n}\n"
  },
  {
    "path": "build/README.md",
    "content": "## Build Standalone Binaries\n\n### Build with `cross`\n\n- Install [`cross`](https://github.com/rust-embedded/cross)\n\n```bash\ncargo install cross\n```\n\n- Build with cross\n\n```bash\ncross build --target x86_64-unknown-linux-musl\n```\n\n### Predefined build routines\n\n- `build-release`: Build binaries with `cross` and packages outputs into `release` folder\n- `build-host-release`: Build binaries with host's Rust toolchain. *NIX shell script\n- `build-host-release.ps1`: Build binaries with host's Rust toolchain. PowerShell script\n"
  },
  {
    "path": "build/build-host-release",
    "content": "#!/bin/bash\n\nBUILD_TARGET=\"\"\nBUILD_FEATURES=()\nwhile getopts \"t:f:\" opt; do\n    case $opt in\n        t)\n            BUILD_TARGET=$OPTARG\n            ;;\n        f)\n            BUILD_FEATURES+=($OPTARG)\n            ;;\n        ?)\n            echo \"Usage: $(basename $0) [-t <target-triple>] [-f <feature>]\"\n            ;;\n    esac\ndone\n\nBUILD_FEATURES+=${BUILD_EXTRA_FEATURES}\n\nROOT_DIR=$( cd $( dirname $0 ) && pwd )\nVERSION=$(grep -E '^version' \"${ROOT_DIR}/../Cargo.toml\" | awk '{print $3}' | sed 's/\"//g')\nHOST_TRIPLE=$(rustc -Vv | grep 'host:' | awk '{print $2}')\n\necho \"Started build release ${VERSION} for ${HOST_TRIPLE} (target: ${BUILD_TARGET}) with features \\\"${BUILD_FEATURES}\\\"...\"\n\nif [[ \"${BUILD_TARGET}\" != \"\" ]]; then\n    if [[ \"${BUILD_FEATURES}\" != \"\" ]]; then\n        cargo build --release --features \"${BUILD_FEATURES}\" --target \"${BUILD_TARGET}\"\n    else\n        cargo build --release --target \"${BUILD_TARGET}\"\n    fi\nelse\n    if [[ \"${BUILD_FEATURES}\" != \"\" ]]; then\n        cargo build --release --features \"${BUILD_FEATURES}\"\n    else\n        cargo build --release\n    fi\nfi\n\nif [[ \"$?\" != \"0\" ]]; then\n    exit 1;\nfi\n\nif [[ \"${BUILD_TARGET}\" == \"\" ]]; then\n    BUILD_TARGET=$HOST_TRIPLE\nfi\n\nRELEASE_FOLDER=\"${ROOT_DIR}/release\"\nRELEASE_PACKAGE_NAME=\"shadowsocks-v${VERSION}.${BUILD_TARGET}\"\n\nmkdir -p \"${RELEASE_FOLDER}\"\n\n# Into release folder\nif [[ \"${BUILD_TARGET}\" != \"\" ]]; then\n    cd \"${ROOT_DIR}/../target/${BUILD_TARGET}/release\"\nelse\n    cd \"${ROOT_DIR}/../target/release\"\nfi\n\nTARGET_SUFFIX=\"\"\nif [[ \"${BUILD_TARGET}\" == *\"-windows-\"* ]]; then\n    TARGET_SUFFIX=\".exe\"\nfi\n\nTARGETS=(\"sslocal${TARGET_SUFFIX}\" \"ssserver${TARGET_SUFFIX}\" \"ssurl${TARGET_SUFFIX}\" \"ssmanager${TARGET_SUFFIX}\" \"ssservice${TARGET_SUFFIX}\")\n\nif [ -e \"sswinservice${TARGET_SUFFIX}\" ]; then\n    TARGETS+=(\"sswinservice${TARGET_SUFFIX}\")\nfi\n\nif [[ \"${BUILD_TARGET}\" == *\"-windows-\"* ]]; then\n    # For Windows, use zip\n\n    RELEASE_PACKAGE_FILE_NAME=\"${RELEASE_PACKAGE_NAME}.zip\"\n    RELEASE_PACKAGE_FILE_PATH=\"${RELEASE_FOLDER}/${RELEASE_PACKAGE_FILE_NAME}\"\n    zip \"${RELEASE_PACKAGE_FILE_PATH}\" \"${TARGETS[@]}\"\n\n    if [[ $? != \"0\" ]]; then\n        exit 1\n    fi\n\n    # Checksum\n    cd \"${RELEASE_FOLDER}\"\n    shasum -a 256 \"${RELEASE_PACKAGE_FILE_NAME}\" > \"${RELEASE_PACKAGE_FILE_NAME}.sha256\"\nelse\n    # For others, Linux, OS X, uses tar.xz\n\n    # For Darwin, .DS_Store and other related files should be ignored\n    if [[ \"$(uname -s)\" == \"Darwin\" ]]; then\n        export COPYFILE_DISABLE=1\n    fi\n\n    RELEASE_PACKAGE_FILE_NAME=\"${RELEASE_PACKAGE_NAME}.tar.xz\"\n    RELEASE_PACKAGE_FILE_PATH=\"${RELEASE_FOLDER}/${RELEASE_PACKAGE_FILE_NAME}\"\n    tar -cJf \"${RELEASE_PACKAGE_FILE_PATH}\" \"${TARGETS[@]}\"\n\n    if [[ $? != \"0\" ]]; then\n        exit 1\n    fi\n\n    # Checksum\n    cd \"${RELEASE_FOLDER}\"\n    shasum -a 256 \"${RELEASE_PACKAGE_FILE_NAME}\" > \"${RELEASE_PACKAGE_FILE_NAME}.sha256\"\nfi\n\necho \"Finished build release ${RELEASE_PACKAGE_FILE_PATH}\"\n"
  },
  {
    "path": "build/build-host-release.ps1",
    "content": "#!pwsh\n<#\n    OpenSSL is already installed on windows-latest virtual environment.\n    If you need OpenSSL, consider install it by:\n\n    choco install openssl\n#>\nparam(\n    [Parameter(HelpMessage = \"extra features\")]\n    [Alias('f')]\n    [string]$Features\n)\n\n$ErrorActionPreference = \"Stop\"\n\n$TargetTriple = (rustc -Vv | Select-String -Pattern \"host: (.*)\" | ForEach-Object { $_.Matches.Value }).split()[-1]\n\nWrite-Host \"Started building release for ${TargetTriple} ...\"\n\nif ([string]::IsNullOrEmpty($Features)) {\n    cargo build --release\n}\nelse {\n    cargo build --release --features \"${Features}\"\n}\n\nif (!$?) {\n    exit $LASTEXITCODE\n}\n\n$Version = (Select-String -Pattern '^version *= *\"([^\"]*)\"$' -Path \"${PSScriptRoot}\\..\\Cargo.toml\" | ForEach-Object { $_.Matches.Value }).split()[-1]\n$Version = $Version -replace '\"'\n\n$PackageReleasePath = \"${PSScriptRoot}\\release\"\n$PackageName = \"shadowsocks-v${Version}.${TargetTriple}.zip\"\n$PackagePath = \"${PackageReleasePath}\\${PackageName}\"\n$ReleaseBuildPath = \"${PSScriptRoot}\\..\\target\\release\"\n\nWrite-Host $Version\nWrite-Host $PackageReleasePath\nWrite-Host $PackageName\nWrite-Host $PackagePath\nWrite-Host $ReleaseBuildPath\n\nPush-Location $ReleaseBuildPath\n\n$ProgressPreference = \"SilentlyContinue\"\nNew-Item \"${PackageReleasePath}\" -ItemType Directory -ErrorAction SilentlyContinue\n$CompressParam = @{\n    LiteralPath     = \"sslocal.exe\", \"ssserver.exe\", \"ssurl.exe\", \"ssmanager.exe\", \"ssservice.exe\"\n    DestinationPath = \"${PackagePath}\"\n}\nif ([System.IO.File]::Exists(\"$ReleaseBuildPath\\sswinservice.exe\")) {\n    $CompressParam.LiteralPath += \"sswinservice.exe\"\n}\nCompress-Archive @CompressParam\n\nWrite-Host \"Created release packet ${PackagePath}\"\n\n$PackageChecksumPath = \"${PackagePath}.sha256\"\n$PackageHash = (Get-FileHash -Path \"${PackagePath}\" -Algorithm SHA256).Hash\n\"${PackageHash}  ${PackageName}\" | Out-File -FilePath \"${PackageChecksumPath}\"\n\nWrite-Host \"Created release packet checksum ${PackageChecksumPath}\"\n\nPop-Location\n"
  },
  {
    "path": "build/build-release",
    "content": "#!/bin/bash\n\nCUR_DIR=$( cd $( dirname $0 ) && pwd )\nVERSION=$(grep -E '^version' ${CUR_DIR}/../Cargo.toml | awk '{print $3}' | sed 's/\"//g')\n\n## Disable macos ACL file\nif [[ \"$(uname -s)\" == \"Darwin\" ]]; then\n    export COPYFILE_DISABLE=1\nfi\n\ntargets=()\nfeatures=()\nuse_upx=false\nuse_nightly=false\ncargo_flags=\"\"\n\nwhile getopts \"t:f:unZ:\" opt; do\n    case $opt in\n        t)\n            targets+=($OPTARG)\n            ;;\n        f)\n            features+=($OPTARG)\n            ;;\n        u)\n            use_upx=true\n            ;;\n        n)\n            use_nightly=true\n            ;;\n        Z)\n            cargo_flags=\"-Z $OPTARG\"\n            ;;\n        ?)\n            echo \"Usage: $(basename $0) [-t <target-triple>] [-f features] [-u] [-n]\"\n            ;;\n    esac\ndone\n\nfeatures+=${EXTRA_FEATURES}\n\nif [[ \"${#targets[@]}\" == \"0\" ]]; then\n    echo \"Specifying compile target with -t <target-triple>\"\n    exit 1\nfi\n\nif [[ \"${use_upx}\" = true ]]; then\n    if [[ -z \"$upx\" ]] && command -v upx &> /dev/null; then\n        upx=\"upx -9\"\n    fi\n\n    if [[ \"x$upx\" == \"x\" ]]; then\n        echo \"Couldn't find upx in PATH, consider specifying it with variable \\$upx\"\n        exit 1\n    fi\nfi\n\nbuild_command=\"cross\"\nif [[ \"${use_nightly}\" = true ]]; then\n    build_command=\"$build_command +nightly\"\nfi\n\n\nfunction build() {\n    cd \"$CUR_DIR/..\"\n\n    TARGET=$1\n\n    RELEASE_DIR=\"target/${TARGET}/release\"\n    TARGET_FEATURES=\"${features[@]}\"\n\n    if [[ \"${TARGET_FEATURES}\" != \"\" ]]; then\n        echo \"* Building ${TARGET} package ${VERSION} with features \\\"${TARGET_FEATURES}\\\" ...\"\n\n        $build_command build --target \"${TARGET}\" \\\n                             --features \"${TARGET_FEATURES}\" \\\n                             --release \\\n                             ${cargo_flags}\n    else\n        echo \"* Building ${TARGET} package ${VERSION} ...\"\n\n        $build_command build --target \"${TARGET}\" \\\n                             --release \\\n                             ${cargo_flags}\n    fi\n\n    if [[ $? != \"0\" ]]; then\n        exit 1\n    fi\n\n    PKG_DIR=\"${CUR_DIR}/release\"\n    mkdir -p \"${PKG_DIR}\"\n\n    if [[ \"$TARGET\" == *\"-linux-\"* || \"$TARGET\" == *\"-freebsd\" || \"$TARGET\" == *\"-netbsd\" ]]; then\n        PKG_NAME=\"shadowsocks-v${VERSION}.${TARGET}.tar.xz\"\n        PKG_PATH=\"${PKG_DIR}/${PKG_NAME}\"\n\n        cd ${RELEASE_DIR}\n\n        if [[ \"${use_upx}\" = true ]]; then\n            # Enable upx for MIPS.\n            $upx sslocal ssserver ssurl ssmanager ssservice #>/dev/null\n        fi\n\n        echo \"* Packaging XZ in ${PKG_PATH} ...\"\n        tar -cJf ${PKG_PATH} \\\n            \"sslocal\" \\\n            \"ssserver\" \\\n            \"ssurl\" \\\n            \"ssmanager\" \\\n            \"ssservice\"\n\n        if [[ $? != \"0\" ]]; then\n            exit 1\n        fi\n\n        cd \"${PKG_DIR}\"\n        shasum -a 256 \"${PKG_NAME}\" > \"${PKG_NAME}.sha256\"\n    elif [[ \"$TARGET\" == *\"-windows-\"* ]]; then\n        PKG_NAME=\"shadowsocks-v${VERSION}.${TARGET}.zip\"\n        PKG_PATH=\"${PKG_DIR}/${PKG_NAME}\"\n\n        echo \"* Packaging ZIP in ${PKG_PATH} ...\"\n        cd ${RELEASE_DIR}\n\n        sswinservice=\"\"\n        if [ -e \"sswinservice.exe\" ]; then\n            sswinservice=\"sswinservice.exe\"\n        fi\n\n        zip ${PKG_PATH} \\\n            \"sslocal.exe\" \\\n            \"ssserver.exe\" \\\n            \"ssurl.exe\" \\\n            \"ssmanager.exe\" \\\n            \"ssservice.exe\" \\\n            \"${sswinservice}\"\n\n        if [[ $? != \"0\" ]]; then\n            exit 1\n        fi\n\n        cd \"${PKG_DIR}\"\n        shasum -a 256 \"${PKG_NAME}\" > \"${PKG_NAME}.sha256\"\n    fi\n\n    echo \"* Done build package ${PKG_NAME}\"\n}\n\nfor target in \"${targets[@]}\"; do\n    build \"$target\";\ndone\n"
  },
  {
    "path": "cargo-publish.sh",
    "content": "#!/bin/bash -e\n\nset -x\n\nROOT_DIR=$(dirname $0)\ncd ${ROOT_DIR:?}\n\npackage_ordered=\"crates/shadowsocks crates/shadowsocks-service .\"\n\n## dry-run\ncargo check\n\nfor p in ${package_ordered:?}; do\n    cargo update -p shadowsocks\n    cargo update -p shadowsocks-service\n    #echo \"====> dry-run publish $p\"\n    #cargo publish --verbose --locked --dry-run --manifest-path \"${p:?}/Cargo.toml\"\n    echo \"====> publishing $p\"\n    cargo publish --verbose --locked --manifest-path \"${p:?}/Cargo.toml\"\n\n    # this seems to be enough time to let crates.io update\n    sleep 10\ndone\n"
  },
  {
    "path": "clippy.toml",
    "content": "msrv = \"1.88\"\n"
  },
  {
    "path": "configs/genipset.py",
    "content": "#!/usr/bin/env python3\n# -*- coding:utf-8 -*-\nimport sys\nimport time\n\n\nAPNIC_DELEGATED_LATEST = \"https://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest\"\n\n\ndef get_apnic_delegated():\n    from urllib import request\n\n    u = request.urlopen(APNIC_DELEGATED_LATEST)\n    return u.read().decode('utf-8')\n\n\ndef generate_ipset(content, name, location_set, type_set, output_file):\n\n    if 'ipv4' in type_set:\n        cidr_trans = {}\n        for i in range(0, 32):\n            cidr_trans[2 ** (32 - i - 1)] = i + 1\n\n    for line in content.splitlines():\n        if line.startswith('#'):\n            continue\n\n        splits = line.split('|')\n        if len(splits) == 7:\n            '''\n            This is a Record with 7 fields\n            '''\n\n            registry, cc, type_, start, value, _, _ = splits\n            if registry != 'apnic':\n                continue\n\n            if cc in location_set and type_ in type_set:\n\n                if type_ == 'ipv4':\n                    '''\n                    In the case of IPv4 address the count of hosts for this range. This count does not have to represent a CIDR range.\n\n                    But. It seems that it is always a CIDR range in this particular file.\n                    '''\n                    mask = cidr_trans[int(value)]\n                    output_file.write(\n                        'add {} {}/{} -exist\\n'.format(name, start, mask))\n\n                elif type_ == 'ipv6':\n                    '''\n                    In the case of an IPv6 address the value will be the CIDR prefix length from the ‘first address’ value of <start>.\n                    '''\n                    output_file.write(\n                        'add {} {}/{} -exist\\n'.format(name, start, value))\n\n\nif __name__ == '__main__':\n    import argparse\n\n    parser = argparse.ArgumentParser()\n    parser.add_argument('--name', '-n', help='Name of ipset',\n                        type=str, required=True)\n    parser.add_argument('--location', '-l', help='Location to be filtered, like CN',\n                        nargs='+', type=str, required=True)\n    parser.add_argument('--address-type', '-t', help='Address type, like ipv4, ipv6',\n                        nargs='+', type=str, required=True, choices=['ipv4', 'ipv6'])\n    parser.add_argument(\n        '--output', '-o', help='Output file, default to stdout', type=str, required=False)\n\n    args = parser.parse_args()\n\n    name = args.name\n    location_set = set(args.location)\n    type_set = set(args.address_type)\n\n    start_time = time.time()\n    data = get_apnic_delegated()\n\n    if hasattr(args, 'output'):\n        with open(args.output, 'w') as fp:\n            generate_ipset(data, name, location_set, type_set, fp)\n    else:\n        generate_ipset(data, name, location_set, type_set, sys.stdout)\n"
  },
  {
    "path": "configs/iptables_mixed.sh",
    "content": "#!/bin/bash\n\niptables-save | grep -v shadowsocks- | iptables-restore\nip6tables-save | grep -v shadowsocks- | ip6tables-restore\n\n### IPv4 RULES\n\n# Create chnip ipset\nipset create chnip hash:net family inet -exist\nipset restore < /usr/local/etc/chnip.ipset\n\n# Create gfwlist ipset\nipset create gfwlist hash:ip family inet timeout 7200 -exist\nipset create bypasslist hash:ip family inet timeout 7200 -exist\n\nSHADOWSOCKS_REDIR_IP=0.0.0.0\nSHADOWSOCKS_REDIR_PORT=60080\n\nreadonly IPV4_RESERVED_IPADDRS=\"\\\n0/8 \\\n10/8 \\\n100.64/10 \\\n127/8 \\\n169.254/16 \\\n172.16/12 \\\n192/24 \\\n192.0.2.0/24 \\\n192.88.99/24 \\\n192.168/16 \\\n198.18/15 \\\n198.51.100/24 \\\n203.0.113/24 \\\n224/4 \\\n240/4 \\\n255.255.255.255/32 \\\n\"\n\n## TCP\n# NAT PREROUTING\niptables -t nat -N shadowsocks-nat\n# Skip LoopBack, Reserved\nfor addr in ${IPV4_RESERVED_IPADDRS}; do\n   iptables -t nat -A shadowsocks-nat -d \"${addr}\" -j RETURN\ndone\n# Bypass sslocal's outbound data\niptables -t nat -A shadowsocks-nat -m mark --mark 0xff/0xff -j RETURN\niptables -t nat -A shadowsocks-nat -m owner --uid-owner shadowsocks -j RETURN\n# Proxy gfwlist\niptables -t nat -A shadowsocks-nat -m set --match-set gfwlist dst -p tcp -j REDIRECT --to-ports ${SHADOWSOCKS_REDIR_PORT}\n# Bypass CN IPs\niptables -t nat -A shadowsocks-nat -m set --match-set chnip dst -p tcp -j RETURN\niptables -t nat -A shadowsocks-nat -m set --match-set bypasslist dst -p tcp -j RETURN\n# Redirect TCP to 60080\niptables -t nat -A shadowsocks-nat -p tcp -j REDIRECT --to-ports ${SHADOWSOCKS_REDIR_PORT}\n# Local TCP -> shadowsocks-nat\niptables -t nat -A OUTPUT -p tcp -j shadowsocks-nat\n# LAN TCP -> shadowsocks-nat\niptables -t nat -A PREROUTING -p tcp -j shadowsocks-nat\n\n## UDP\n# Strategy Route\nip -4 rule del fwmark 0x1 table 803\nip -4 rule add fwmark 0x1 table 803\nip -4 route del local 0.0.0.0/0 dev lo table 803\nip -4 route add local 0.0.0.0/0 dev lo table 803\n\n# TPROXY for LAN\niptables -t mangle -N shadowsocks-tproxy\n# Skip LoopBack, Reserved\nfor addr in ${IPV4_RESERVED_IPADDRS}; do\n   iptables -t mangle -A shadowsocks-tproxy -d \"${addr}\" -j RETURN\ndone\n\n# Bypass sslocal's outbound data\niptables -t mangle -A shadowsocks-tproxy -m mark --mark 0xff/0xff -j RETURN\n# Proxy gfwlist\niptables -t mangle -A shadowsocks-tproxy -m set --match-set gfwlist dst -p udp -j TPROXY --on-ip ${SHADOWSOCKS_REDIR_IP} --on-port ${SHADOWSOCKS_REDIR_PORT} --tproxy-mark 0x01/0x01\n# Bypass CN IPs\niptables -t mangle -A shadowsocks-tproxy -m set --match-set chnip dst -p udp -j RETURN\niptables -t mangle -A shadowsocks-tproxy -m set --match-set bypasslist dst -p udp -j RETURN\n# TPROXY UDP to 60080\niptables -t mangle -A shadowsocks-tproxy -p udp -j TPROXY --on-ip ${SHADOWSOCKS_REDIR_IP} --on-port ${SHADOWSOCKS_REDIR_PORT} --tproxy-mark 0x01/0x01\n\n# TPROXY for Local\niptables -t mangle -N shadowsocks-tproxy-mark\n# Skip LoopBack, Reserved\nfor addr in ${IPV4_RESERVED_IPADDRS}; do\n   iptables -t mangle -A shadowsocks-tproxy-mark -d \"${addr}\" -j RETURN\ndone\n\n# Bypass sslocal's outbound data\niptables -t mangle -A shadowsocks-tproxy-mark -m mark --mark 0xff/0xff -j RETURN\niptables -t mangle -A shadowsocks-tproxy-mark -m owner --uid-owner shadowsocks -j RETURN\n# Proxy gfwlist\niptables -t mangle -A shadowsocks-tproxy-mark -m set --match-set gfwlist dst -j MARK --set-xmark 0x01/0xffffffff\n# Bypass CN IPs\niptables -t mangle -A shadowsocks-tproxy-mark -m set --match-set chnip dst -j RETURN\n# Set MARK and reroute\niptables -t mangle -A shadowsocks-tproxy-mark -p udp -j MARK --set-xmark 0x01/0xffffffff\n#iptables -t mangle -A shadowsocks-tproxy-mark -p tcp -j MARK --set-xmark 1\n\n# Apply TPROXY to LAN\niptables -t mangle -A PREROUTING -p udp -j shadowsocks-tproxy\n#iptables -t mangle -A PREROUTING -p udp -m addrtype ! --src-type LOCAL ! --dst-type LOCAL -j shadowsocks-tproxy\n# Apply TPROXY for Local\niptables -t mangle -A OUTPUT -p udp -j shadowsocks-tproxy-mark\n#iptables -t mangle -A OUTPUT -p udp -m addrtype --src-type LOCAL ! --dst-type LOCAL -j shadowsocks-tproxy-mark\n\n# DIVERT rules\n# For optimizing TCP\n# iptables -t mangle -N shadowsocks-divert\n# iptables -t mangle -A shadowsocks-divert -j MARK --set-mark 1\n# iptables -t mangle -A shadowsocks-divert -j ACCEPT\n# iptables -t mangle -I PREROUTING -p tcp -m socket -j shadowsocks-divert\n\n### IPv6 RULES\n\n# Create chnip6 ipset\nipset create chnip6 hash:net family inet6 -exist\nipset restore < /usr/local/etc/chnip6.ipset\n\n# Create gfwlist6 ipset\nipset create gfwlist6 hash:ip family inet6 timeout 7200 -exist\nipset create bypasslist6 hash:ip family inet6 timeout 7200 -exist\n\nSHADOWSOCKS6_REDIR_IP=::\nSHADOWSOCKS6_REDIR_PORT=60081\n\nreadonly IPV6_RESERVED_IPADDRS=\"\\\n::/128 \\\n::1/128 \\\n::ffff:0:0/96 \\\n::ffff:0:0:0/96 \\\n64:ff9b::/96 \\\n100::/64 \\\n2001::/32 \\\n2001:20::/28 \\\n2001:db8::/32 \\\n2002::/16 \\\nfc00::/7 \\\nfe80::/10 \\\nff00::/8 \\\n\"\n\n## TCP\n# NAT PREROUTING\nip6tables -t nat -N shadowsocks-nat\n# Skip LoopBack, Reserved\nfor addr in ${IPV6_RESERVED_IPADDRS}; do\n   ip6tables -t nat -A shadowsocks-nat -d \"${addr}\" -j RETURN\ndone\n# Bypass sslocal's outbound data\nip6tables -t nat -A shadowsocks-nat -m mark --mark 0xff/0xff -j RETURN\nip6tables -t nat -A shadowsocks-nat -m owner --uid-owner shadowsocks -j RETURN\n# Proxy gfwlist6\nip6tables -t nat -A shadowsocks-nat -m set --match-set gfwlist6 dst -p tcp -j REDIRECT --to-ports ${SHADOWSOCKS6_REDIR_PORT}\n# Bypass CN IPs\nip6tables -t nat -A shadowsocks-nat -m set --match-set chnip6 dst -p tcp -j RETURN\nip6tables -t nat -A shadowsocks-nat -m set --match-set bypasslist6 dst -p tcp -j RETURN\n# Redirect TCP to 60081\nip6tables -t nat -A shadowsocks-nat -p tcp -j REDIRECT --to-ports ${SHADOWSOCKS6_REDIR_PORT}\n# Local TCP -> shadowsocks-nat\nip6tables -t nat -A OUTPUT -p tcp -j shadowsocks-nat\n# LAN TCP -> shadowsocks-nat\nip6tables -t nat -A PREROUTING -p tcp -j shadowsocks-nat\n\n## UDP\n# Strategy Route\nip -6 rule del fwmark 0x1 table 803\nip -6 rule add fwmark 0x1 table 803\nip -6 route del local ::/0 dev lo table 803\nip -6 route add local ::/0 dev lo table 803\n\n# TPROXY for LAN\nip6tables -t mangle -N shadowsocks-tproxy\n# Skip LoopBack, Reserved\nfor addr in ${IPV6_RESERVED_IPADDRS}; do\n   ip6tables -t mangle -A shadowsocks-tproxy -d \"${addr}\" -j RETURN\ndone\n\n# Bypass sslocal's outbound data\nip6tables -t mangle -A shadowsocks-tproxy -m mark --mark 0xff/0xff -j RETURN\n# Proxy gfwlist6\nip6tables -t mangle -A shadowsocks-tproxy -m set --match-set gfwlist6 dst -p udp -j TPROXY --on-ip ${SHADOWSOCKS6_REDIR_IP} --on-port ${SHADOWSOCKS6_REDIR_PORT} --tproxy-mark 0x01/0x01\n# Bypass CN IPs\nip6tables -t mangle -A shadowsocks-tproxy -m set --match-set chnip6 dst -p udp -j RETURN\nip6tables -t mangle -A shadowsocks-tproxy -m set --match-set bypasslist6 dst -p udp -j RETURN\n# TPROXY UDP to 60081\nip6tables -t mangle -A shadowsocks-tproxy -p udp -j TPROXY --on-ip ${SHADOWSOCKS6_REDIR_IP} --on-port ${SHADOWSOCKS6_REDIR_PORT} --tproxy-mark 0x01/0x01\n\n# TPROXY for Local\nip6tables -t mangle -N shadowsocks-tproxy-mark\n# Skip LoopBack, Reserved\nfor addr in ${IPV6_RESERVED_IPADDRS}; do\n   ip6tables -t mangle -A shadowsocks-tproxy-mark -d \"${addr}\" -j RETURN\ndone\n\n# Bypass sslocal's outbound data\nip6tables -t mangle -A shadowsocks-tproxy-mark -m mark --mark 0xff/0xff -j RETURN\nip6tables -t mangle -A shadowsocks-tproxy-mark -m owner --uid-owner shadowsocks -j RETURN\n# Proxy gfwlist6\nip6tables -t mangle -A shadowsocks-tproxy-mark -m set --match-set gfwlist6 dst -j MARK --set-xmark 0x01/0xffffffff\n# Bypass CN IPs\nip6tables -t mangle -A shadowsocks-tproxy-mark -m set --match-set chnip6 dst -j RETURN\n# Set MARK and reroute\nip6tables -t mangle -A shadowsocks-tproxy-mark -p udp -j MARK --set-xmark 0x01/0xffffffff\n#ip6tables -t mangle -A shadowsocks-tproxy-mark -p tcp -j MARK --set-xmark 1\n\n# Apply TPROXY to LAN\nip6tables -t mangle -A PREROUTING -p udp -j shadowsocks-tproxy\n#ip6tables -t mangle -A PREROUTING -p udp -m addrtype ! --src-type LOCAL ! --dst-type LOCAL -j shadowsocks-tproxy\n# Apply TPROXY for Local\nip6tables -t mangle -A OUTPUT -p udp -j shadowsocks-tproxy-mark\n#ip6tables -t mangle -A OUTPUT -p udp -m addrtype --src-type LOCAL ! --dst-type LOCAL -j shadowsocks-tproxy-mark\n\n# DIVERT rules\n# For optimizing TCP\n# ip6tables -t mangle -N shadowsocks-divert\n# ip6tables -t mangle -A shadowsocks-divert -j MARK --set-mark 1\n# ip6tables -t mangle -A shadowsocks-divert -j ACCEPT\n# ip6tables -t mangle -I PREROUTING -p tcp -m socket -j shadowsocks-divert\n"
  },
  {
    "path": "configs/iptables_tproxy.sh",
    "content": "#!/bin/bash\n\niptables-save | grep -v shadowsocks- | iptables-restore\nip6tables-save | grep -v shadowsocks- | ip6tables-restore\n\n### IPv4 RULES\n\n# Create chnip ipset\nipset create chnip hash:net family inet -exist\nipset restore < /usr/local/etc/chnip.ipset\n\n# Create gfwlist ipset\nipset create gfwlist hash:ip family inet timeout 7200 -exist\nipset create bypasslist hash:ip family inet timeout 7200 -exist\n\nSHADOWSOCKS_REDIR_IP=0.0.0.0\nSHADOWSOCKS_REDIR_PORT=60080\n\nreadonly IPV4_RESERVED_IPADDRS=\"\\\n0/8 \\\n10/8 \\\n100.64/10 \\\n127/8 \\\n169.254/16 \\\n172.16/12 \\\n192/24 \\\n192.0.2.0/24 \\\n192.88.99/24 \\\n192.168/16 \\\n198.18/15 \\\n198.51.100/24 \\\n203.0.113/24 \\\n224/4 \\\n240/4 \\\n255.255.255.255/32 \\\n\"\n\n## TCP+UDP\n# Strategy Route\nip -4 rule del fwmark 0x1 table 803\nip -4 rule add fwmark 0x1 table 803\nip -4 route del local 0.0.0.0/0 dev lo table 803\nip -4 route add local 0.0.0.0/0 dev lo table 803\n\n# TPROXY for LAN\niptables -t mangle -N shadowsocks-tproxy\n# Skip LoopBack, Reserved\nfor addr in ${IPV4_RESERVED_IPADDRS}; do\n   iptables -t mangle -A shadowsocks-tproxy -d \"${addr}\" -j RETURN\ndone\n\n# Bypass LAN data\niptables -t mangle -A shadowsocks-tproxy -m addrtype --dst-type LOCAL -j RETURN\n# Bypass sslocal's outbound data\niptables -t mangle -A shadowsocks-tproxy -m mark --mark 0xff/0xff -j RETURN\n# UDP: Proxy gfwlist\niptables -t mangle -A shadowsocks-tproxy -m set --match-set gfwlist dst -p udp -j TPROXY --on-ip ${SHADOWSOCKS_REDIR_IP} --on-port ${SHADOWSOCKS_REDIR_PORT} --tproxy-mark 0x01/0x01\n# UDP: Bypass CN IPs\niptables -t mangle -A shadowsocks-tproxy -m set --match-set chnip dst -p udp -j RETURN\niptables -t mangle -A shadowsocks-tproxy -m set --match-set bypasslist dst -p udp -j RETURN\n# UDP: TPROXY UDP to 60080\niptables -t mangle -A shadowsocks-tproxy -p udp -j TPROXY --on-ip ${SHADOWSOCKS_REDIR_IP} --on-port ${SHADOWSOCKS_REDIR_PORT} --tproxy-mark 0x01/0x01\n# TCP: Proxy gfwlist\niptables -t mangle -A shadowsocks-tproxy -m set --match-set gfwlist dst -p tcp -j TPROXY --on-ip ${SHADOWSOCKS_REDIR_IP} --on-port ${SHADOWSOCKS_REDIR_PORT} --tproxy-mark 0x01/0x01\n# TCP: Bypass CN IPs\niptables -t mangle -A shadowsocks-tproxy -m set --match-set chnip dst -p tcp -j RETURN\niptables -t mangle -A shadowsocks-tproxy -m set --match-set bypasslist dst -p tcp -j RETURN\n# TCP: TPROXY TCP to 60080\niptables -t mangle -A shadowsocks-tproxy -p tcp -j TPROXY --on-ip ${SHADOWSOCKS_REDIR_IP} --on-port ${SHADOWSOCKS_REDIR_PORT} --tproxy-mark 0x01/0x01\n\n\n# TPROXY for Local\niptables -t mangle -N shadowsocks-tproxy-mark\n# Skip LoopBack, Reserved\nfor addr in ${IPV4_RESERVED_IPADDRS}; do\n   iptables -t mangle -A shadowsocks-tproxy-mark -d \"${addr}\" -j RETURN\ndone\n\n# TCP: conntrack\niptables -t mangle -A shadowsocks-tproxy-mark -p tcp -m conntrack --ctdir REPLY -j RETURN\n# Bypass sslocal's outbound data\niptables -t mangle -A shadowsocks-tproxy-mark -m mark --mark 0xff/0xff -j RETURN\niptables -t mangle -A shadowsocks-tproxy-mark -m owner --uid-owner shadowsocks -j RETURN\n# Proxy gfwlist\niptables -t mangle -A shadowsocks-tproxy-mark -m set --match-set gfwlist dst -j MARK --set-xmark 0x01/0xffffffff\n# Bypass CN IPs\niptables -t mangle -A shadowsocks-tproxy-mark -m set --match-set chnip dst -j RETURN\n# UDP: Set MARK and reroute\niptables -t mangle -A shadowsocks-tproxy-mark -p udp -j MARK --set-xmark 0x01/0xffffffff\n# TCP: Set MARK and reroute\niptables -t mangle -A shadowsocks-tproxy-mark -p tcp -j MARK --set-xmark 0x01/0xffffffff\n\n# Apply TPROXY to LAN\niptables -t mangle -A PREROUTING -p udp -j shadowsocks-tproxy\niptables -t mangle -A PREROUTING -p tcp -j shadowsocks-tproxy\n#iptables -t mangle -A PREROUTING -p udp -m addrtype ! --src-type LOCAL ! --dst-type LOCAL -j shadowsocks-tproxy\n# Apply TPROXY for Local\niptables -t mangle -A OUTPUT -p udp -j shadowsocks-tproxy-mark\niptables -t mangle -A OUTPUT -p tcp -j shadowsocks-tproxy-mark\n#iptables -t mangle -A OUTPUT -p udp -m addrtype --src-type LOCAL ! --dst-type LOCAL -j shadowsocks-tproxy-mark\n\n# DIVERT rules\n# For optimizing TCP\n# iptables -t mangle -N shadowsocks-divert\n# iptables -t mangle -A shadowsocks-divert -j MARK --set-mark 1\n# iptables -t mangle -A shadowsocks-divert -j ACCEPT\n# iptables -t mangle -I PREROUTING -p tcp -m socket -j shadowsocks-divert\n\n### IPv6 RULES\n\n# Create chnip6 ipset\nipset create chnip6 hash:net family inet6 -exist\nipset restore < /usr/local/etc/chnip6.ipset\n\n# Create gfwlist6 ipset\nipset create gfwlist6 hash:ip family inet6 timeout 7200 -exist\nipset create bypasslist6 hash:ip family inet6 timeout 7200 -exist\n\nSHADOWSOCKS6_REDIR_IP=::\nSHADOWSOCKS6_REDIR_PORT=60081\n\nreadonly IPV6_RESERVED_IPADDRS=\"\\\n::/128 \\\n::1/128 \\\n::ffff:0:0/96 \\\n::ffff:0:0:0/96 \\\n64:ff9b::/96 \\\n100::/64 \\\n2001::/32 \\\n2001:20::/28 \\\n2001:db8::/32 \\\n2002::/16 \\\nfc00::/7 \\\nfe80::/10 \\\nff00::/8 \\\n\"\n\n## TCP+UDP\n# Strategy Route\nip -6 rule del fwmark 0x1 table 803\nip -6 rule add fwmark 0x1 table 803\nip -6 route del local ::/0 dev lo table 803\nip -6 route add local ::/0 dev lo table 803\n\n# TPROXY for LAN\nip6tables -t mangle -N shadowsocks-tproxy\n# Skip LoopBack, Reserved\nfor addr in ${IPV6_RESERVED_IPADDRS}; do\n   ip6tables -t mangle -A shadowsocks-tproxy -d \"${addr}\" -j RETURN\ndone\n\n# Bypass LAN data\nip6tables -t mangle -A shadowsocks-tproxy -m addrtype --dst-type LOCAL -j RETURN\n# Bypass sslocal's outbound data\nip6tables -t mangle -A shadowsocks-tproxy -m mark --mark 0xff/0xff -j RETURN\n# UDP: Proxy gfwlist6\nip6tables -t mangle -A shadowsocks-tproxy -m set --match-set gfwlist6 dst -p udp -j TPROXY --on-ip ${SHADOWSOCKS6_REDIR_IP} --on-port ${SHADOWSOCKS6_REDIR_PORT} --tproxy-mark 0x01/0x01\n# UDP: Bypass CN IPs\nip6tables -t mangle -A shadowsocks-tproxy -m set --match-set chnip6 dst -p udp -j RETURN\nip6tables -t mangle -A shadowsocks-tproxy -m set --match-set bypasslist6 dst -p udp -j RETURN\n# UDP: TPROXY UDP to 60081\nip6tables -t mangle -A shadowsocks-tproxy -p udp -j TPROXY --on-ip ${SHADOWSOCKS6_REDIR_IP} --on-port ${SHADOWSOCKS6_REDIR_PORT} --tproxy-mark 0x01/0x01\n# TCP: Proxy gfwlist6\nip6tables -t mangle -A shadowsocks-tproxy -m set --match-set gfwlist6 dst -p tcp -j TPROXY --on-ip ${SHADOWSOCKS6_REDIR_IP} --on-port ${SHADOWSOCKS6_REDIR_PORT} --tproxy-mark 0x01/0x01\n# TCP: Bypass CN IPs\nip6tables -t mangle -A shadowsocks-tproxy -m set --match-set chnip6 dst -p tcp -j RETURN\nip6tables -t mangle -A shadowsocks-tproxy -m set --match-set bypasslist6 dst -p tcp -j RETURN\n# TCP: TPROXY UDP to 60081\nip6tables -t mangle -A shadowsocks-tproxy -p tcp -j TPROXY --on-ip ${SHADOWSOCKS6_REDIR_IP} --on-port ${SHADOWSOCKS6_REDIR_PORT} --tproxy-mark 0x01/0x01\n\n# TPROXY for Local\nip6tables -t mangle -N shadowsocks-tproxy-mark\n# Skip LoopBack, Reserved\nfor addr in ${IPV6_RESERVED_IPADDRS}; do\n   ip6tables -t mangle -A shadowsocks-tproxy-mark -d \"${addr}\" -j RETURN\ndone\n\n# TCP: conntrack\nip6tables -t mangle -A shadowsocks-tproxy-mark -p tcp -m conntrack --ctdir REPLY -j RETURN\n# Bypass sslocal's outbound data\nip6tables -t mangle -A shadowsocks-tproxy-mark -m mark --mark 0xff/0xff -j RETURN\nip6tables -t mangle -A shadowsocks-tproxy-mark -m owner --uid-owner shadowsocks -j RETURN\n# Proxy gfwlist6\nip6tables -t mangle -A shadowsocks-tproxy-mark -m set --match-set gfwlist6 dst -j MARK --set-xmark 0x01/0xffffffff\n# Bypass CN IPs\nip6tables -t mangle -A shadowsocks-tproxy-mark -m set --match-set chnip6 dst -j RETURN\n# Set MARK and reroute\nip6tables -t mangle -A shadowsocks-tproxy-mark -p udp -j MARK --set-xmark 0x01/0xffffffff\nip6tables -t mangle -A shadowsocks-tproxy-mark -p tcp -j MARK --set-xmark 0x01/0xffffffff\n\n# Apply TPROXY to LAN\nip6tables -t mangle -A PREROUTING -p udp -j shadowsocks-tproxy\nip6tables -t mangle -A PREROUTING -p tcp -j shadowsocks-tproxy\n#ip6tables -t mangle -A PREROUTING -p udp -m addrtype ! --src-type LOCAL ! --dst-type LOCAL -j shadowsocks-tproxy\n# Apply TPROXY for Local\nip6tables -t mangle -A OUTPUT -p udp -j shadowsocks-tproxy-mark\nip6tables -t mangle -A OUTPUT -p tcp -j shadowsocks-tproxy-mark\n#ip6tables -t mangle -A OUTPUT -p udp -m addrtype --src-type LOCAL ! --dst-type LOCAL -j shadowsocks-tproxy-mark\n\n# DIVERT rules\n# For optimizing TCP\n# ip6tables -t mangle -N shadowsocks-divert\n# ip6tables -t mangle -A shadowsocks-divert -j MARK --set-mark 1\n# ip6tables -t mangle -A shadowsocks-divert -j ACCEPT\n"
  },
  {
    "path": "configs/log4rs.yaml",
    "content": "refresh_rate: 30 seconds\nappenders:\n  stdout:\n    kind: console\n    encoder:\n      pattern: \"{d} {h({l}):<5} {m}{n}\"\n  file:\n    kind: rolling_file\n    path: shadowsocks.log\n    encoder:\n      kind: pattern\n      pattern: \"{d} {h({l}):<5} {m}{n}\"\n    policy:\n      trigger:\n        kind: size\n        limit: 10 mb\n      roller:\n        kind: fixed_window\n        pattern: shadowsocks.{}.log\n        count: 5\nroot:\n  level: info\n  appenders:\n    - stdout\n    - file\n"
  },
  {
    "path": "configs/org.shadowsocks.shadowsocks-rust.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n    <dict>\n        <key>Disabled</key>\n        <false/>\n\n        <key>Label</key>\n        <string>org.shadowsocks.shadowsocks-rust</string>\n\n        <key>ProgramArguments</key>\n        <array>\n            <string>/usr/local/bin/sslocal</string>\n            <string>-c</string>\n            <string>/usr/local/etc/shadowsocks.json</string>\n        </array>\n\n        <key>RunAtLoad</key>\n        <true/>\n\n        <key>KeepAlive</key>\n        <dict>\n            <key>NetworkState</key>\n            <true/>\n        </dict>\n\n        <key>WorkingDirectory</key>\n        <string>/</string>\n\n        <key>StandardErrorPath</key>\n        <string>/tmp/shadowsocks-rust.stderr.log</string>\n\n        <key>StandardOutPath</key>\n        <string>/tmp/shadowsocks-rust.stdout.log</string>\n\n        <key>SoftResourceLimits</key>\n        <dict>\n            <key>NumberOfFiles</key>\n            <integer>10240</integer>\n        </dict>\n    </dict>\n</plist>\n"
  },
  {
    "path": "configs/shadowsocks.procd.sh",
    "content": "#!/bin/sh /etc/rc.common\n\nSTART=30\n\nUSE_PROCD=1\n\nEXTRA_COMMANDS=\"set_firewall destroy\"\nEXTRA_HELP=<<EOF\n\tset_firewall Set firewall (iptable) rules\n\tdestroy Remove all resources (ipset, firewall rules, ...)\nEOF\n\nset_firewall() {\n    uci add firewall include\n    uci rename 'firewall.@include[-1]=shadowsocks'\n    uci set 'firewall.@include[-1].path=/usr/local/etc/iptables_mixed.include'\n    uci set 'firewall.@include[-1].type=script'\n    uci set 'firewall.@include[-1].reload=1'\n    uci commit firewall\n\n    # Initialize iptables rules\n    /etc/init.d/firewall restart\n}\n\ndestroy() {\n    ipset destroy chnip\n    ipset destroy gfwlist\n    ipset destroy bypasslist\n    ipset destroy chnip6\n    ipset destroy gfwlist6\n    ipset destroy bypasslist6\n\n    uci delete 'firewall.shadowsocks'\n    uci commit firewall\n\n    # Delete iptables rules\n    /etc/init.d/firewall restart\n\n    # Delete strategy route rules\n    ip -4 rule del fwmark 0x1 table 803\n    ip -4 route del local 0.0.0.0/0 dev lo table 803\n    ip -6 rule del fwmark 0x1 table 803\n    ip -6 route del local ::/0 dev lo table 803\n}\n\nstart_service() {\n    SHADOWSOCKS_CAPABILITIES_CONFIG_PATH=\"/etc/capabilities/shadowsocks.json\"\n    SHADOWSOCKS_LOG_FILE_PATH=\"/var/log/shadowsocks\"\n\n    mkdir -p ${SHADOWSOCKS_LOG_FILE_PATH}\n    if id \"shadowsocks\" &>/dev/null; then\n        chown shadowsocks:shadowsocks -R ${SHADOWSOCKS_LOG_FILE_PATH}\n    fi\n\n    SHADOWSOCKS_CONFIG_PATH=\"/usr/local/etc/shadowsocks.json\"\n    SHADOWSOCKS_EXECUTABLE=\"/usr/local/bin/sslocal\"\n    SHADOWSOCKS_PARAMETERS=\"-c ${SHADOWSOCKS_CONFIG_PATH} --log-without-time --udp-max-associations 4192 --outbound-fwmark 255\"\n    SHADOWSOCKS_COMMAND=\"${SHADOWSOCKS_EXECUTABLE} ${SHADOWSOCKS_PARAMETERS}\"\n\n    procd_open_instance shadowsocks\n    procd_set_param env RUST_BACKTRACE=1\n    procd_set_param env NO_COLOR=1\n\n    procd_set_param file ${SHADOWSOCKS_CONFIG_PATH}\n    procd_set_param respawn\n    procd_set_param reload_signal USR1\n    procd_set_param limits nofile=\"10240 10240\"\n    procd_set_param limits core=\"unlimited\"\n    procd_set_param stdout 1\n    procd_set_param stderr 1\n\n    if id \"shadowsocks\" &>/dev/null; then\n        if [ -x /sbin/ujail -a -e ${SHADOWSOCKS_CAPABILITIES_CONFIG_PATH} ]; then\n            procd_add_jail shadowsocks requirejail\n            procd_add_jail_mount ${SHADOWSOCKS_CONFIG_PATH}\n            procd_set_param user shadowsocks\n            procd_set_param group shadowsocks\n            procd_set_param capabilities ${SHADOWSOCKS_CAPABILITIES_CONFIG_PATH}\n            procd_set_param no_new_privs 1\n            procd_set_param command ${SHADOWSOCKS_COMMAND}\n        else\n            procd_set_param user root\n            procd_set_param command /usr/sbin/capsh --caps=\"cap_setpcap,cap_setuid,cap_setgid+ep cap_net_admin,cap_net_raw,cap_net_bind_service+eip\" --keep=1 \\\n                                    --user=\"shadowsocks\" --addamb=\"cap_net_admin,cap_net_raw,cap_net_bind_service\" \\\n                                    --shell=\"${SHADOWSOCKS_EXECUTABLE}\" -- ${SHADOWSOCKS_PARAMETERS}\n        fi\n    else\n        procd_set_param user root\n        procd_set_param command ${SHADOWSOCKS_COMMAND}\n    fi\n\n    SHADOWSOCKS6_CONFIG_PATH=\"/usr/local/etc/shadowsocks6.json\"\n    SHADOWSOCKS6_EXECUTABLE=\"/usr/local/bin/sslocal\"\n    SHADOWSOCKS6_PARAMETERS=\"-c ${SHADOWSOCKS6_CONFIG_PATH} --log-without-time --udp-max-associations 4192 --outbound-fwmark 255\"\n    SHADOWSOCKS6_COMMAND=\"${SHADOWSOCKS6_EXECUTABLE} ${SHADOWSOCKS6_PARAMETERS}\"\n\n    procd_set_param pidfile /var/run/shadowsocks.pid\n    procd_close_instance\n\n    procd_open_instance shadowsocks6\n    procd_set_param env RUST_BACKTRACE=1\n    procd_set_param env NO_COLOR=1\n\n    procd_set_param file ${SHADOWSOCKS6_CONFIG_PATH}\n    procd_set_param respawn\n    procd_set_param reload_signal USR1\n    procd_set_param limits nofile=\"10240 10240\"\n    procd_set_param limits core=\"unlimited\"\n    procd_set_param stdout 1\n    procd_set_param stderr 1\n\n    if id \"shadowsocks\" &>/dev/null; then\n        if [ -x /sbin/ujail -a -e ${SHADOWSOCKS_CAPABILITIES_CONFIG_PATH} ]; then\n            procd_add_jail shadowsocks6 requirejail\n            procd_add_jail_mount ${SHADOWSOCKS6_CONFIG_PATH}\n            procd_set_param user shadowsocks\n            procd_set_param group shadowsocks\n            procd_set_param capabilities ${SHADOWSOCKS_CAPABILITIES_CONFIG_PATH}\n            procd_set_param no_new_privs 1\n            procd_set_param command ${SHADOWSOCKS6_COMMAND}\n        else\n            procd_set_param user root\n            procd_set_param command /usr/sbin/capsh --caps=\"cap_setpcap,cap_setuid,cap_setgid+ep cap_net_admin,cap_net_raw,cap_net_bind_service+eip\" --keep=1 \\\n                                    --user=\"shadowsocks\" --addamb=\"cap_net_admin,cap_net_raw,cap_net_bind_service\" \\\n                                    --shell=\"${SHADOWSOCKS6_EXECUTABLE}\" -- ${SHADOWSOCKS6_PARAMETERS}\n        fi\n    else\n        procd_set_param user root\n        procd_set_param command ${SHADOWSOCKS6_COMMAND}\n    fi\n\n    procd_set_param pidfile /var/run/shadowsocks6.pid\n    procd_close_instance\n\n    echo 'Started shadowsocks service'\n}\n\nservice_stopped() {\n    echo 'Stopped shadowsocks service'\n}\n\nservice_triggers() {\n    #procd_add_reload_interface_trigger \"pppoe-wan\"\n    procd_add_interface_trigger \"interface.*\" \"pppoe-wan\" /etc/init.d/shadowsocks restart\n}\n"
  },
  {
    "path": "crates/shadowsocks/Cargo.toml",
    "content": "[package]\nname = \"shadowsocks\"\nversion = \"1.24.0\"\nauthors = [\"Shadowsocks Contributors\"]\ndescription = \"shadowsocks is a fast tunnel proxy that helps you bypass firewalls.\"\nrepository = \"https://github.com/shadowsocks/shadowsocks-rust\"\nreadme = \"README.md\"\ndocumentation = \"https://docs.rs/shadowsocks-core\"\nkeywords = [\"shadowsocks\", \"proxy\", \"socks\", \"socks5\", \"firewall\"]\nlicense = \"MIT\"\nedition = \"2024\"\nrust-version = \"1.88\"\n\n[badges]\nmaintenance = { status = \"passively-maintained\" }\n\n[features]\ndefault = [\"hickory-dns\", \"aead-cipher\"]\n\n# Uses Hickory-DNS instead of tokio's builtin DNS resolver\nhickory-dns = [\"hickory-resolver\", \"arc-swap\", \"notify\"]\n# Hickory-DNS was renamed from Trust-DNS, keep compatibility.\ntrust-dns = [\"hickory-dns\"]\n\n# Enable Stream Cipher Protocol\n# WARN: Stream Cipher Protocol is proved to be insecure\n# https://github.com/shadowsocks/shadowsocks-rust/issues/373\n# Users should always avoid using these ciphers in practice\nstream-cipher = [\"shadowsocks-crypto/v1-stream\", \"shadowsocks-crypto/ring\"]\n\n# Enable AEAD ciphers\naead-cipher = [\"shadowsocks-crypto/v1-aead\", \"shadowsocks-crypto/ring\"]\n\n# Enable extra AEAD ciphers\n# WARN: These non-standard AEAD ciphers are not officially supported by shadowsocks community\naead-cipher-extra = [\"aead-cipher\", \"shadowsocks-crypto/v1-aead-extra\"]\n\naead-cipher-2022 = [\n    \"shadowsocks-crypto/v2\",\n    \"shadowsocks-crypto/ring\",\n    \"rand\",\n    \"aes\",\n    \"lru_time_cache\",\n] # Enable AEAD 2022\n# Enable AEAD 2022 with extra ciphers\naead-cipher-2022-extra = [\"aead-cipher-2022\", \"shadowsocks-crypto/v2-extra\"]\n\n# Enable detection against replay attack\nsecurity-replay-attack-detect = [\"bloomfilter\"]\n\n[dependencies]\nlog = \"0.4\"\n\nlibc = \"~0.2.141\"\nbytes = \"1.7\"\ncfg-if = \"1\"\nbyte_string = \"1.0\"\nbase64 = \"0.22\"\nurl = \"2.5\"\nspin = { version = \"0.10\", features = [\"std\"] }\npin-project = \"1.1\"\nbloomfilter = { version = \"3.0.0\", optional = true }\nthiserror = \"2.0\"\nrand = { version = \"0.10\", optional = true }\nlru_time_cache = { version = \"0.11\", optional = true }\n\nserde = { version = \"1.0\", features = [\"derive\"] }\nserde_urlencoded = \"0.7\"\nserde_json = \"1.0\"\npercent-encoding = \"2.1\"\n\nfutures = \"0.3\"\ntrait-variant = \"0.1\"\ndynosaur = \"0.3.0\"\nsealed = \"0.6\"\n\nsocket2 = { version = \"0.6\", features = [\"all\"] }\ntokio = { version = \"1.9.0\", features = [\n    \"io-util\",\n    \"macros\",\n    \"net\",\n    \"parking_lot\",\n    \"process\",\n    \"rt\",\n    \"sync\",\n    \"time\",\n] }\n\nhickory-resolver = { version = \"0.25\", optional = true }\narc-swap = { version = \"1.7\", optional = true }\nnotify = { version = \"8.0\", optional = true }\n\naes = { version = \"0.8\", optional = true }\nblake3 = \"1.5\"\nshadowsocks-crypto = { version = \"0.6.0\", default-features = false }\n\n[target.'cfg(any(windows, target_os = \"linux\", target_os = \"android\", target_os = \"freebsd\", target_os = \"macos\", target_os = \"ios\", target_os = \"watchos\", target_os = \"tvos\"))'.dependencies]\ntokio-tfo = \"0.4.3\"\n\n[target.'cfg(windows)'.dependencies]\nwindows-sys = { version = \"0.61\", features = [\n    \"Win32_Foundation\",\n    \"Win32_NetworkManagement_IpHelper\",\n    \"Win32_NetworkManagement_Ndis\",\n    \"Win32_Networking_WinSock\",\n    \"Win32_System_IO\",\n] }\n\n[target.'cfg(unix)'.dependencies]\nsendfd = { version = \"0.4\", features = [\"tokio\"] }\n\n[dev-dependencies]\nenv_logger = \"0.11\"\n\n[lints.clippy]\nuninlined_format_args = \"allow\"\n"
  },
  {
    "path": "crates/shadowsocks/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2017 Y. T. CHUNG <zonyitoo@gmail.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "crates/shadowsocks/README.md",
    "content": "# shadowsocks\n\n[![License](https://img.shields.io/github/license/zonyitoo/shadowsocks-rust.svg)](https://github.com/zonyitoo/shadowsocks-rust)\n[![crates.io](https://img.shields.io/crates/v/shadowsocks.svg)](https://crates.io/crates/shadowsocks)\n[![docs.rs](https://img.shields.io/docsrs/shadowsocks)](https://docs.rs/shadowsocks)\n\nThis is a port of [shadowsocks](https://github.com/shadowsocks/shadowsocks).\n\nshadowsocks is a fast tunnel proxy that helps you bypass firewalls.\n"
  },
  {
    "path": "crates/shadowsocks/src/config.rs",
    "content": "//! Configuration\n\n#[cfg(unix)]\nuse std::path::PathBuf;\nuse std::{\n    collections::HashMap,\n    fmt::{self, Debug, Display},\n    net::SocketAddr,\n    str::{self, FromStr},\n    sync::Arc,\n    time::Duration,\n};\n\nuse base64::Engine as _;\nuse byte_string::ByteStr;\nuse bytes::Bytes;\nuse cfg_if::cfg_if;\nuse log::{error, warn};\nuse thiserror::Error;\nuse url::{self, Url};\n\n#[cfg(any(feature = \"stream-cipher\", feature = \"aead-cipher\"))]\nuse crate::crypto::v1::openssl_bytes_to_key;\nuse crate::{crypto::CipherKind, plugin::PluginConfig, relay::socks5::Address};\n\nconst USER_KEY_BASE64_ENGINE: base64::engine::GeneralPurpose = base64::engine::GeneralPurpose::new(\n    &base64::alphabet::STANDARD,\n    base64::engine::GeneralPurposeConfig::new()\n        .with_encode_padding(true)\n        .with_decode_padding_mode(base64::engine::DecodePaddingMode::Indifferent),\n);\n\n#[cfg(feature = \"aead-cipher-2022\")]\nconst AEAD2022_PASSWORD_BASE64_ENGINE: base64::engine::GeneralPurpose = base64::engine::GeneralPurpose::new(\n    &base64::alphabet::STANDARD,\n    base64::engine::GeneralPurposeConfig::new()\n        .with_encode_padding(true)\n        .with_decode_padding_mode(base64::engine::DecodePaddingMode::Indifferent),\n);\n\nconst URL_PASSWORD_BASE64_ENGINE: base64::engine::GeneralPurpose = base64::engine::GeneralPurpose::new(\n    &base64::alphabet::URL_SAFE,\n    base64::engine::GeneralPurposeConfig::new()\n        .with_encode_padding(false)\n        .with_decode_padding_mode(base64::engine::DecodePaddingMode::Indifferent),\n);\n\n/// Shadowsocks server type\n#[derive(Debug, Copy, Clone, Eq, PartialEq)]\npub enum ServerType {\n    /// Running as a local service\n    Local,\n\n    /// Running as a shadowsocks server\n    Server,\n}\n\nimpl ServerType {\n    /// Check if it is `Local`\n    pub fn is_local(self) -> bool {\n        self == Self::Local\n    }\n\n    /// Check if it is `Server`\n    pub fn is_server(self) -> bool {\n        self == Self::Server\n    }\n}\n\n/// Server mode\n#[derive(Clone, Copy, Debug)]\npub enum Mode {\n    TcpOnly = 0x01,\n    TcpAndUdp = 0x03,\n    UdpOnly = 0x02,\n}\n\nimpl Mode {\n    /// Check if UDP is enabled\n    pub fn enable_udp(self) -> bool {\n        matches!(self, Self::UdpOnly | Self::TcpAndUdp)\n    }\n\n    /// Check if TCP is enabled\n    pub fn enable_tcp(self) -> bool {\n        matches!(self, Self::TcpOnly | Self::TcpAndUdp)\n    }\n\n    /// Merge with another Mode\n    pub fn merge(&self, mode: Self) -> Self {\n        let me = *self as u8;\n        let fm = mode as u8;\n        match me | fm {\n            0x01 => Self::TcpOnly,\n            0x02 => Self::UdpOnly,\n            0x03 => Self::TcpAndUdp,\n            _ => unreachable!(),\n        }\n    }\n\n    /// String representation of Mode\n    pub fn as_str(&self) -> &'static str {\n        match *self {\n            Self::TcpOnly => \"tcp_only\",\n            Self::TcpAndUdp => \"tcp_and_udp\",\n            Self::UdpOnly => \"udp_only\",\n        }\n    }\n}\n\nimpl fmt::Display for Mode {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        f.write_str(self.as_str())\n    }\n}\n\nimpl FromStr for Mode {\n    type Err = ();\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        match s {\n            \"tcp_only\" => Ok(Self::TcpOnly),\n            \"tcp_and_udp\" => Ok(Self::TcpAndUdp),\n            \"udp_only\" => Ok(Self::UdpOnly),\n            _ => Err(()),\n        }\n    }\n}\n\nstruct ModeVisitor;\n\nimpl serde::de::Visitor<'_> for ModeVisitor {\n    type Value = Mode;\n\n    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n        formatter.write_str(\"Mode\")\n    }\n\n    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>\n    where\n        E: serde::de::Error,\n    {\n        match v.parse::<Mode>() {\n            Ok(m) => Ok(m),\n            Err(_) => Err(serde::de::Error::invalid_value(serde::de::Unexpected::Str(v), &self)),\n        }\n    }\n\n    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>\n    where\n        E: serde::de::Error,\n    {\n        self.visit_str::<E>(v.as_str())\n    }\n\n    fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>\n    where\n        E: serde::de::Error,\n    {\n        match str::from_utf8(v) {\n            Ok(v) => self.visit_str(v),\n            Err(_) => Err(serde::de::Error::invalid_value(serde::de::Unexpected::Bytes(v), &self)),\n        }\n    }\n\n    fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>\n    where\n        E: serde::de::Error,\n    {\n        match String::from_utf8(v) {\n            Ok(v) => self.visit_string(v),\n            Err(e) => Err(serde::de::Error::invalid_value(\n                serde::de::Unexpected::Bytes(&e.into_bytes()),\n                &self,\n            )),\n        }\n    }\n}\n\nimpl<'de> serde::Deserialize<'de> for Mode {\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: serde::Deserializer<'de>,\n    {\n        deserializer.deserialize_string(ModeVisitor)\n    }\n}\n\nimpl serde::Serialize for Mode {\n    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n    where\n        S: serde::Serializer,\n    {\n        serializer.serialize_str(self.as_str())\n    }\n}\n\n/// Server's weight\n///\n/// Commonly for using in balancer\n#[derive(Debug, Clone)]\npub struct ServerWeight {\n    tcp_weight: f32,\n    udp_weight: f32,\n}\n\nimpl Default for ServerWeight {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nimpl ServerWeight {\n    /// Creates a default weight for server, which will have 1.0 for both TCP and UDP\n    pub fn new() -> Self {\n        Self {\n            tcp_weight: 1.0,\n            udp_weight: 1.0,\n        }\n    }\n\n    /// Weight for TCP balancer\n    pub fn tcp_weight(&self) -> f32 {\n        self.tcp_weight\n    }\n\n    /// Set weight for TCP balancer in `[0, 1]`\n    pub fn set_tcp_weight(&mut self, weight: f32) {\n        assert!((0.0..=1.0).contains(&weight));\n        self.tcp_weight = weight;\n    }\n\n    /// Weight for UDP balancer\n    pub fn udp_weight(&self) -> f32 {\n        self.udp_weight\n    }\n\n    /// Set weight for UDP balancer in `[0, 1]`\n    pub fn set_udp_weight(&mut self, weight: f32) {\n        assert!((0.0..=1.0).contains(&weight));\n        self.udp_weight = weight;\n    }\n}\n\n/// Server's user\n#[derive(Clone)]\npub struct ServerUser {\n    name: String,\n    key: Bytes,\n    identity_hash: Bytes,\n}\n\nimpl Debug for ServerUser {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        f.debug_struct(\"ServerUser\")\n            .field(\"name\", &self.name)\n            .field(\"key\", &USER_KEY_BASE64_ENGINE.encode(&self.key))\n            .field(\"identity_hash\", &ByteStr::new(&self.identity_hash))\n            .finish()\n    }\n}\n\nimpl ServerUser {\n    /// Create a user\n    pub fn new<N, K>(name: N, key: K) -> Self\n    where\n        N: Into<String>,\n        K: Into<Bytes>,\n    {\n        let name = name.into();\n        let key = key.into();\n\n        let hash = blake3::hash(&key);\n        let identity_hash = Bytes::from(hash.as_bytes()[0..16].to_owned());\n\n        Self {\n            name,\n            key,\n            identity_hash,\n        }\n    }\n\n    /// Create a user from encoded key\n    pub fn with_encoded_key<N>(name: N, key: &str) -> Result<Self, ServerUserError>\n    where\n        N: Into<String>,\n    {\n        let key = USER_KEY_BASE64_ENGINE.decode(key)?;\n        Ok(Self::new(name, key))\n    }\n\n    /// Name of the user\n    pub fn name(&self) -> &str {\n        self.name.as_str()\n    }\n\n    /// Encryption key of user\n    pub fn key(&self) -> &[u8] {\n        self.key.as_ref()\n    }\n\n    /// Get Base64 encoded key of user\n    pub fn encoded_key(&self) -> String {\n        USER_KEY_BASE64_ENGINE.encode(&self.key)\n    }\n\n    /// User's identity hash\n    ///\n    /// https://github.com/Shadowsocks-NET/shadowsocks-specs/blob/main/2022-2-shadowsocks-2022-extensible-identity-headers.md\n    pub fn identity_hash(&self) -> &[u8] {\n        self.identity_hash.as_ref()\n    }\n\n    /// User's identity hash\n    ///\n    /// https://github.com/Shadowsocks-NET/shadowsocks-specs/blob/main/2022-2-shadowsocks-2022-extensible-identity-headers.md\n    pub fn clone_identity_hash(&self) -> Bytes {\n        self.identity_hash.clone()\n    }\n}\n\n/// ServerUser related errors\n#[derive(Debug, Clone, Error)]\npub enum ServerUserError {\n    /// Invalid User key encoding\n    #[error(\"{0}\")]\n    InvalidKeyEncoding(#[from] base64::DecodeError),\n}\n\n/// Server multi-users manager\n#[derive(Clone, Debug)]\npub struct ServerUserManager {\n    users: HashMap<Bytes, Arc<ServerUser>>,\n}\n\nimpl ServerUserManager {\n    /// Create a new manager\n    pub fn new() -> Self {\n        Self { users: HashMap::new() }\n    }\n\n    /// Add a new user\n    pub fn add_user(&mut self, user: ServerUser) {\n        self.users.insert(user.clone_identity_hash(), Arc::new(user));\n    }\n\n    /// Get user by hash key\n    pub fn get_user_by_hash(&self, user_hash: &[u8]) -> Option<&ServerUser> {\n        self.users.get(user_hash).map(AsRef::as_ref)\n    }\n\n    /// Get user by hash key cloned\n    pub fn clone_user_by_hash(&self, user_hash: &[u8]) -> Option<Arc<ServerUser>> {\n        self.users.get(user_hash).cloned()\n    }\n\n    /// Number of users\n    pub fn user_count(&self) -> usize {\n        self.users.len()\n    }\n\n    /// Iterate users\n    pub fn users_iter(&self) -> impl Iterator<Item = &ServerUser> {\n        self.users.values().map(|v| v.as_ref())\n    }\n}\n\nimpl Default for ServerUserManager {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\n/// The source of the ServerConfig\n#[derive(Debug, Clone, Copy, Eq, PartialEq)]\npub enum ServerSource {\n    Default,       //< Default source, created in code\n    Configuration, //< Created from configuration\n    CommandLine,   //< Created from command line\n    OnlineConfig,  //< Created from online configuration (SIP008)\n}\n\n/// Errors when creating a new ServerConfig\n#[derive(Debug, Clone, Error)]\npub enum ServerConfigError {\n    /// Invalid base64 encoding of password\n    #[error(\"invalid key encoding for {0}, {1}\")]\n    InvalidKeyEncoding(CipherKind, base64::DecodeError),\n\n    /// Invalid user key encoding\n    #[error(\"invalid iPSK encoding for {0}, {1}\")]\n    InvalidUserKeyEncoding(CipherKind, base64::DecodeError),\n\n    /// Key length mismatch\n    #[error(\"invalid key length for {0}, expecting {1} bytes, but found {2} bytes\")]\n    InvalidKeyLength(CipherKind, usize, usize),\n\n    /// User Key (ipsk) length mismatch\n    #[error(\"invalid user key length for {0}, expecting {1} bytes, but found {2} bytes\")]\n    InvalidUserKeyLength(CipherKind, usize, usize),\n}\n\n/// Configuration for a server\n#[derive(Clone, Debug)]\npub struct ServerConfig {\n    /// Server address\n    addr: ServerAddr,\n    /// Encryption password (key)\n    password: String,\n    /// Encryption type (method)\n    method: CipherKind,\n    /// Encryption key\n    enc_key: Box<[u8]>,\n    /// Handshake timeout (connect)\n    timeout: Option<Duration>,\n\n    /// Extensible Identity Headers (AEAD-2022)\n    ///\n    /// For client, assemble EIH headers\n    identity_keys: Arc<Vec<Bytes>>,\n\n    /// Extensible Identity Headers (AEAD-2022)\n    ///\n    /// For server, support multi-users with EIH\n    user_manager: Option<Arc<ServerUserManager>>,\n\n    /// Plugin config\n    plugin: Option<PluginConfig>,\n    /// Plugin address\n    plugin_addr: Option<ServerAddr>,\n\n    /// Remark (Profile Name), normally used as an identifier of this erver\n    remarks: Option<String>,\n    /// ID (SIP008) is a random generated UUID\n    id: Option<String>,\n\n    /// Mode\n    mode: Mode,\n\n    /// Weight\n    weight: ServerWeight,\n\n    /// Source\n    source: ServerSource,\n}\n\n#[inline]\nfn make_derived_key(method: CipherKind, password: &str, enc_key: &mut [u8]) -> Result<(), ServerConfigError> {\n    #[cfg(feature = \"aead-cipher-2022\")]\n    if method.is_aead_2022() {\n        // AEAD 2022 password is a base64 form of enc_key\n        match AEAD2022_PASSWORD_BASE64_ENGINE.decode(password) {\n            Ok(v) => {\n                if v.len() != enc_key.len() {\n                    return Err(ServerConfigError::InvalidKeyLength(method, enc_key.len(), v.len()));\n                }\n                enc_key.copy_from_slice(&v);\n            }\n            Err(err) => {\n                return Err(ServerConfigError::InvalidKeyEncoding(method, err));\n            }\n        }\n\n        return Ok(());\n    }\n\n    cfg_if! {\n        if #[cfg(any(feature = \"stream-cipher\", feature = \"aead-cipher\"))] {\n            let _ = method;\n            openssl_bytes_to_key(password.as_bytes(), enc_key);\n\n            Ok(())\n        } else {\n            // No default implementation.\n            let _ = password;\n            let _ = enc_key;\n            unreachable!(\"{method} don't know how to make a derived key\");\n        }\n    }\n}\n\n/// Check if method supports Extended Identity Header\n///\n/// https://github.com/Shadowsocks-NET/shadowsocks-specs/blob/main/2022-2-shadowsocks-2022-extensible-identity-headers.md\n#[cfg(feature = \"aead-cipher-2022\")]\n#[inline]\npub fn method_support_eih(method: CipherKind) -> bool {\n    matches!(\n        method,\n        CipherKind::AEAD2022_BLAKE3_AES_128_GCM | CipherKind::AEAD2022_BLAKE3_AES_256_GCM\n    )\n}\n\n#[allow(clippy::type_complexity)]\nfn password_to_keys<P>(method: CipherKind, password: P) -> Result<(String, Box<[u8]>, Vec<Bytes>), ServerConfigError>\nwhere\n    P: Into<String>,\n{\n    let password = password.into();\n\n    match method {\n        CipherKind::NONE => {\n            // NONE method's key length is 0\n            debug_assert_eq!(method.key_len(), 0);\n\n            if !password.is_empty() {\n                warn!(\n                    \"method \\\"none\\\" doesn't need a password, which should be set as an empty String, but password.len() = {}\",\n                    password.len()\n                );\n            }\n\n            return Ok((password, Vec::new().into_boxed_slice(), Vec::new()));\n        }\n\n        #[cfg(feature = \"stream-cipher\")]\n        CipherKind::SS_TABLE => {\n            // TABLE cipher doesn't need key derivation.\n            // Reference implementation: shadowsocks-libev, shadowsocks (Python)\n            let enc_key = password.clone().into_bytes().into_boxed_slice();\n            return Ok((password, enc_key, Vec::new()));\n        }\n\n        #[allow(unreachable_patterns)]\n        _ => {}\n    }\n\n    #[cfg(feature = \"aead-cipher-2022\")]\n    if method_support_eih(method) {\n        // Extensible Identity Headers\n        // iPSK1:iPSK2:iPSK3:...:uPSK\n\n        let mut identity_keys = Vec::new();\n\n        let mut split_iter = password.rsplit(':');\n\n        let upsk = split_iter.next().expect(\"uPSK\");\n\n        let mut enc_key = vec![0u8; method.key_len()].into_boxed_slice();\n        make_derived_key(method, upsk, &mut enc_key)?;\n\n        for ipsk in split_iter {\n            match USER_KEY_BASE64_ENGINE.decode(ipsk) {\n                Ok(v) => {\n                    // Double check identity key's length\n                    match method {\n                        CipherKind::AEAD2022_BLAKE3_AES_128_GCM => {\n                            // AES-128\n                            if v.len() != 16 {\n                                return Err(ServerConfigError::InvalidUserKeyLength(method, 16, v.len()));\n                            }\n                        }\n                        CipherKind::AEAD2022_BLAKE3_AES_256_GCM => {\n                            // AES-256\n                            if v.len() != 32 {\n                                return Err(ServerConfigError::InvalidUserKeyLength(method, 32, v.len()));\n                            }\n                        }\n                        _ => unreachable!(\"{} doesn't support EIH\", method),\n                    }\n                    identity_keys.push(Bytes::from(v));\n                }\n                Err(err) => {\n                    return Err(ServerConfigError::InvalidUserKeyEncoding(method, err));\n                }\n            }\n        }\n\n        identity_keys.reverse();\n\n        return Ok((upsk.to_owned(), enc_key, identity_keys));\n    }\n\n    let mut enc_key = vec![0u8; method.key_len()].into_boxed_slice();\n    make_derived_key(method, &password, &mut enc_key)?;\n\n    Ok((password, enc_key, Vec::new()))\n}\n\nimpl ServerConfig {\n    /// Create a new `ServerConfig`\n    pub fn new<A, P>(addr: A, password: P, method: CipherKind) -> Result<Self, ServerConfigError>\n    where\n        A: Into<ServerAddr>,\n        P: Into<String>,\n    {\n        let (password, enc_key, identity_keys) = password_to_keys(method, password)?;\n\n        Ok(Self {\n            addr: addr.into(),\n            password,\n            method,\n            enc_key,\n            identity_keys: Arc::new(identity_keys),\n            user_manager: None,\n            timeout: None,\n            plugin: None,\n            plugin_addr: None,\n            remarks: None,\n            id: None,\n            mode: Mode::TcpAndUdp, // Server serves TCP & UDP by default\n            weight: ServerWeight::new(),\n            source: ServerSource::Default,\n        })\n    }\n\n    /// Set encryption method\n    pub fn set_method<P>(&mut self, method: CipherKind, password: P) -> Result<(), ServerConfigError>\n    where\n        P: Into<String>,\n    {\n        self.method = method;\n\n        let (password, enc_key, identity_keys) = password_to_keys(method, password)?;\n\n        self.password = password;\n        self.enc_key = enc_key;\n        self.identity_keys = Arc::new(identity_keys);\n\n        Ok(())\n    }\n\n    /// Set plugin\n    pub fn set_plugin(&mut self, p: PluginConfig) {\n        self.plugin = Some(p);\n    }\n\n    /// Set server addr\n    pub fn set_addr<A>(&mut self, a: A)\n    where\n        A: Into<ServerAddr>,\n    {\n        self.addr = a.into();\n    }\n\n    /// Get server address\n    pub fn addr(&self) -> &ServerAddr {\n        &self.addr\n    }\n\n    /// Get encryption key\n    pub fn key(&self) -> &[u8] {\n        self.enc_key.as_ref()\n    }\n\n    /// Get password\n    pub fn password(&self) -> &str {\n        self.password.as_str()\n    }\n\n    /// Get identity keys (Client)\n    pub fn identity_keys(&self) -> &[Bytes] {\n        &self.identity_keys\n    }\n\n    /// Clone identity keys (Client)\n    pub fn clone_identity_keys(&self) -> Arc<Vec<Bytes>> {\n        self.identity_keys.clone()\n    }\n\n    /// Set user manager, enable Server's multi-user support with EIH\n    pub fn set_user_manager(&mut self, user_manager: ServerUserManager) {\n        self.user_manager = Some(Arc::new(user_manager));\n    }\n\n    /// Get user manager (Server)\n    pub fn user_manager(&self) -> Option<&ServerUserManager> {\n        self.user_manager.as_deref()\n    }\n\n    /// Clone user manager (Server)\n    pub fn clone_user_manager(&self) -> Option<Arc<ServerUserManager>> {\n        self.user_manager.clone()\n    }\n\n    /// Get method\n    pub fn method(&self) -> CipherKind {\n        self.method\n    }\n\n    /// Get plugin\n    pub fn plugin(&self) -> Option<&PluginConfig> {\n        self.plugin.as_ref()\n    }\n\n    /// Set plugin address\n    pub fn set_plugin_addr(&mut self, a: ServerAddr) {\n        self.plugin_addr = Some(a);\n    }\n\n    /// Get plugin address\n    pub fn plugin_addr(&self) -> Option<&ServerAddr> {\n        self.plugin_addr.as_ref()\n    }\n\n    /// Get server's TCP external address\n    pub fn tcp_external_addr(&self) -> &ServerAddr {\n        if let Some(plugin) = self.plugin()\n            && plugin.plugin_mode.enable_tcp()\n        {\n            return self.plugin_addr.as_ref().unwrap_or(&self.addr);\n        }\n        &self.addr\n    }\n\n    /// Get server's UDP external address\n    pub fn udp_external_addr(&self) -> &ServerAddr {\n        if let Some(plugin) = self.plugin()\n            && plugin.plugin_mode.enable_udp()\n        {\n            return self.plugin_addr.as_ref().unwrap_or(&self.addr);\n        }\n        &self.addr\n    }\n\n    /// Set timeout\n    pub fn set_timeout(&mut self, timeout: Duration) {\n        self.timeout = Some(timeout);\n    }\n\n    /// Timeout\n    pub fn timeout(&self) -> Option<Duration> {\n        self.timeout\n    }\n\n    /// Get server's remark\n    pub fn remarks(&self) -> Option<&str> {\n        self.remarks.as_ref().map(AsRef::as_ref)\n    }\n\n    /// Set server's remark\n    pub fn set_remarks<S>(&mut self, remarks: S)\n    where\n        S: Into<String>,\n    {\n        self.remarks = Some(remarks.into());\n    }\n\n    /// Get server's ID (SIP008)\n    pub fn id(&self) -> Option<&str> {\n        self.id.as_ref().map(AsRef::as_ref)\n    }\n\n    /// Set server's ID (SIP008)\n    pub fn set_id<S>(&mut self, id: S)\n    where\n        S: Into<String>,\n    {\n        self.id = Some(id.into())\n    }\n\n    /// Get server's `Mode`\n    pub fn mode(&self) -> Mode {\n        self.mode\n    }\n\n    /// Set server's `Mode`\n    pub fn set_mode(&mut self, mode: Mode) {\n        self.mode = mode;\n    }\n\n    /// Get server's balancer weight\n    pub fn weight(&self) -> &ServerWeight {\n        &self.weight\n    }\n\n    /// Set server's balancer weight\n    pub fn set_weight(&mut self, weight: ServerWeight) {\n        self.weight = weight;\n    }\n\n    /// Get server's source\n    pub fn source(&self) -> ServerSource {\n        self.source\n    }\n\n    /// Set server's source\n    pub fn set_source(&mut self, source: ServerSource) {\n        self.source = source;\n    }\n\n    /// Get URL for QRCode\n    /// ```plain\n    /// ss:// + base64(method:password@host:port)\n    /// ```\n    pub fn to_qrcode_url(&self) -> String {\n        let param = format!(\"{}:{}@{}\", self.method(), self.password(), self.addr());\n        format!(\"ss://{}\", URL_PASSWORD_BASE64_ENGINE.encode(param))\n    }\n\n    /// Get [SIP002](https://github.com/shadowsocks/shadowsocks-org/issues/27) URL\n    pub fn to_url(&self) -> String {\n        cfg_if! {\n            if #[cfg(feature = \"aead-cipher-2022\")] {\n                let user_info = if !self.method().is_aead_2022() {\n                    let user_info = format!(\"{}:{}\", self.method(), self.password());\n                    URL_PASSWORD_BASE64_ENGINE.encode(user_info)\n                } else {\n                    format!(\"{}:{}\", self.method(), percent_encoding::utf8_percent_encode(self.password(), percent_encoding::NON_ALPHANUMERIC))\n                };\n            } else {\n                let mut user_info = format!(\"{}:{}\", self.method(), self.password());\n                user_info = URL_PASSWORD_BASE64_ENGINE.encode(&user_info)\n            }\n        }\n\n        let mut url = format!(\"ss://{}@{}\", user_info, self.addr());\n        if let Some(c) = self.plugin() {\n            let mut plugin = c.plugin.clone();\n            if let Some(ref opt) = c.plugin_opts {\n                plugin += \";\";\n                plugin += opt;\n            }\n\n            url += \"/?plugin=\";\n            for c in percent_encoding::utf8_percent_encode(&plugin, percent_encoding::NON_ALPHANUMERIC) {\n                url.push_str(c);\n            }\n        }\n\n        if let Some(remark) = self.remarks() {\n            url += \"#\";\n            for c in percent_encoding::utf8_percent_encode(remark, percent_encoding::NON_ALPHANUMERIC) {\n                url.push_str(c);\n            }\n        }\n\n        url\n    }\n\n    /// Parse from [SIP002](https://github.com/shadowsocks/shadowsocks-org/issues/27) URL\n    ///\n    /// Extended formats:\n    ///\n    /// 1. QRCode URL supported by shadowsocks-android, https://github.com/shadowsocks/shadowsocks-android/issues/51\n    /// 2. Plain userinfo:password format supported by go2-shadowsocks2\n    pub fn from_url(encoded: &str) -> Result<Self, UrlParseError> {\n        let parsed = Url::parse(encoded).map_err(UrlParseError::from)?;\n\n        if parsed.scheme() != \"ss\" {\n            return Err(UrlParseError::InvalidScheme);\n        }\n\n        let user_info = parsed.username();\n        if user_info.is_empty() {\n            // This maybe a QRCode URL, which is ss://BASE64-URL-ENCODE(pass:encrypt@hostname:port)\n\n            let encoded = match parsed.host_str() {\n                Some(e) => e,\n                None => return Err(UrlParseError::MissingHost),\n            };\n\n            let mut decoded_body = match URL_PASSWORD_BASE64_ENGINE.decode(encoded) {\n                Ok(b) => match String::from_utf8(b) {\n                    Ok(b) => b,\n                    Err(..) => return Err(UrlParseError::InvalidServerAddr),\n                },\n                Err(err) => {\n                    error!(\"failed to parse legacy ss://ENCODED with Base64, err: {}\", err);\n                    return Err(UrlParseError::InvalidServerAddr);\n                }\n            };\n\n            decoded_body.insert_str(0, \"ss://\");\n            // Parse it like ss://method:password@host:port\n            return Self::from_url(&decoded_body);\n        }\n\n        let (method, pwd) = match parsed.password() {\n            Some(password) => {\n                // Plain method:password without base64 encoded\n\n                let m = match percent_encoding::percent_decode_str(user_info).decode_utf8() {\n                    Ok(m) => m,\n                    Err(err) => {\n                        error!(\"failed to parse percent-encoded method in userinfo, err: {}\", err);\n                        return Err(UrlParseError::InvalidAuthInfo);\n                    }\n                };\n\n                let p = match percent_encoding::percent_decode_str(password).decode_utf8() {\n                    Ok(m) => m,\n                    Err(err) => {\n                        error!(\"failed to parse percent-encoded password in userinfo, err: {}\", err);\n                        return Err(UrlParseError::InvalidAuthInfo);\n                    }\n                };\n\n                (m, p)\n            }\n            None => {\n                // userinfo is not required to be percent encoded, but some implementation did.\n                // If the base64 library have padding = added to the encoded string, then it will become %3D.\n\n                let decoded_user_info = match percent_encoding::percent_decode_str(user_info).decode_utf8() {\n                    Ok(m) => m,\n                    Err(err) => {\n                        error!(\"failed to parse percent-encoded userinfo, err: {}\", err);\n                        return Err(UrlParseError::InvalidAuthInfo);\n                    }\n                };\n\n                // reborrow to fit AsRef<[u8]>\n                let decoded_user_info: &str = &decoded_user_info;\n\n                // Some implementation, like outline,\n                // or those with Python (base64 in Python will still have '=' padding for URL safe encode)\n                let account = match URL_PASSWORD_BASE64_ENGINE.decode(decoded_user_info) {\n                    Ok(account) => match String::from_utf8(account) {\n                        Ok(ac) => ac,\n                        Err(..) => return Err(UrlParseError::InvalidAuthInfo),\n                    },\n                    Err(err) => {\n                        error!(\"failed to parse UserInfo with Base64, err: {}\", err);\n                        return Err(UrlParseError::InvalidUserInfo);\n                    }\n                };\n\n                let mut sp2 = account.splitn(2, ':');\n                let (m, p) = match (sp2.next(), sp2.next()) {\n                    (Some(m), Some(p)) => (m, p),\n                    _ => return Err(UrlParseError::InvalidUserInfo),\n                };\n\n                (m.to_owned().into(), p.to_owned().into())\n            }\n        };\n\n        let host = match parsed.host_str() {\n            Some(host) => host,\n            None => return Err(UrlParseError::MissingHost),\n        };\n\n        let port = parsed.port().unwrap_or(8388);\n        let addr = format!(\"{host}:{port}\");\n\n        let addr = match addr.parse::<ServerAddr>() {\n            Ok(a) => a,\n            Err(err) => {\n                error!(\"failed to parse \\\"{}\\\" to ServerAddr, err: {:?}\", addr, err);\n                return Err(UrlParseError::InvalidServerAddr);\n            }\n        };\n\n        let method = match method.parse::<CipherKind>() {\n            Ok(m) => m,\n            Err(err) => {\n                error!(\"failed to parse \\\"{}\\\" to CipherKind, err: {:?}\", method, err);\n                return Err(UrlParseError::InvalidMethod);\n            }\n        };\n        let mut svrconfig = Self::new(addr, pwd, method)?;\n\n        if let Some(q) = parsed.query() {\n            let query = match serde_urlencoded::from_bytes::<Vec<(String, String)>>(q.as_bytes()) {\n                Ok(q) => q,\n                Err(err) => {\n                    error!(\"failed to parse QueryString, err: {}\", err);\n                    return Err(UrlParseError::InvalidQueryString);\n                }\n            };\n\n            for (key, value) in query {\n                if key != \"plugin\" {\n                    continue;\n                }\n\n                let mut vsp = value.splitn(2, ';');\n                match vsp.next() {\n                    None => {}\n                    Some(p) => {\n                        let plugin = PluginConfig {\n                            plugin: p.to_owned(),\n                            plugin_opts: vsp.next().map(ToOwned::to_owned),\n                            plugin_args: Vec::new(), // SIP002 doesn't have arguments for plugins\n                            plugin_mode: Mode::TcpOnly, // SIP002 doesn't support SIP003u\n                        };\n                        svrconfig.set_plugin(plugin);\n                    }\n                }\n            }\n        }\n\n        if let Some(frag) = parsed.fragment() {\n            match percent_encoding::percent_decode_str(frag).decode_utf8() {\n                Ok(m) => svrconfig.set_remarks(m),\n                Err(..) => svrconfig.set_remarks(frag),\n            }\n        }\n\n        Ok(svrconfig)\n    }\n\n    /// Check if it is a basic format server\n    pub fn is_basic(&self) -> bool {\n        self.remarks.is_none() && self.id.is_none()\n    }\n}\n\n/// Shadowsocks URL parsing Error\n#[derive(Debug, Clone, Error)]\npub enum UrlParseError {\n    #[error(\"{0}\")]\n    ParseError(#[from] url::ParseError),\n    #[error(\"URL must have \\\"ss://\\\" scheme\")]\n    InvalidScheme,\n    #[error(\"unknown encryption method\")]\n    InvalidMethod,\n    #[error(\"invalid user info\")]\n    InvalidUserInfo,\n    #[error(\"missing host\")]\n    MissingHost,\n    #[error(\"invalid authentication info\")]\n    InvalidAuthInfo,\n    #[error(\"invalid server address\")]\n    InvalidServerAddr,\n    #[error(\"invalid query string\")]\n    InvalidQueryString,\n    #[error(\"{0}\")]\n    ServerConfigError(#[from] ServerConfigError),\n}\n\nimpl FromStr for ServerConfig {\n    type Err = UrlParseError;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        Self::from_url(s)\n    }\n}\n\n/// Server address\n#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]\npub enum ServerAddr {\n    /// IP Address\n    SocketAddr(SocketAddr),\n    /// Domain name address, eg. example.com:8080\n    DomainName(String, u16),\n}\n\nimpl ServerAddr {\n    /// Get string representation of domain\n    pub fn host(&self) -> String {\n        match *self {\n            Self::SocketAddr(ref s) => s.ip().to_string(),\n            Self::DomainName(ref dm, _) => dm.clone(),\n        }\n    }\n\n    /// Get port\n    pub fn port(&self) -> u16 {\n        match *self {\n            Self::SocketAddr(ref s) => s.port(),\n            Self::DomainName(_, p) => p,\n        }\n    }\n}\n\n/// Parse `ServerAddr` error\n#[derive(Debug)]\npub struct ServerAddrError;\n\nimpl Display for ServerAddrError {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.write_str(\"invalid ServerAddr\")\n    }\n}\n\nimpl FromStr for ServerAddr {\n    type Err = ServerAddrError;\n\n    fn from_str(s: &str) -> Result<Self, ServerAddrError> {\n        match s.parse::<SocketAddr>() {\n            Ok(addr) => Ok(Self::SocketAddr(addr)),\n            Err(..) => {\n                let mut sp = s.split(':');\n                match (sp.next(), sp.next()) {\n                    (Some(dn), Some(port)) => {\n                        if dn.is_empty() {\n                            return Err(ServerAddrError);\n                        }\n                        match port.parse::<u16>() {\n                            Ok(port) => Ok(Self::DomainName(dn.to_owned(), port)),\n                            Err(..) => Err(ServerAddrError),\n                        }\n                    }\n                    _ => Err(ServerAddrError),\n                }\n            }\n        }\n    }\n}\n\nimpl Display for ServerAddr {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        match *self {\n            Self::SocketAddr(ref a) => write!(f, \"{a}\"),\n            Self::DomainName(ref d, port) => write!(f, \"{d}:{port}\"),\n        }\n    }\n}\n\nstruct ServerAddrVisitor;\n\nimpl serde::de::Visitor<'_> for ServerAddrVisitor {\n    type Value = ServerAddr;\n\n    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n        formatter.write_str(\"ServerAddr\")\n    }\n\n    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>\n    where\n        E: serde::de::Error,\n    {\n        match v.parse::<ServerAddr>() {\n            Ok(m) => Ok(m),\n            Err(_) => Err(serde::de::Error::invalid_value(serde::de::Unexpected::Str(v), &self)),\n        }\n    }\n\n    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>\n    where\n        E: serde::de::Error,\n    {\n        self.visit_str::<E>(v.as_str())\n    }\n\n    fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>\n    where\n        E: serde::de::Error,\n    {\n        match str::from_utf8(v) {\n            Ok(v) => self.visit_str(v),\n            Err(_) => Err(serde::de::Error::invalid_value(serde::de::Unexpected::Bytes(v), &self)),\n        }\n    }\n\n    fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>\n    where\n        E: serde::de::Error,\n    {\n        match String::from_utf8(v) {\n            Ok(v) => self.visit_string(v),\n            Err(e) => Err(serde::de::Error::invalid_value(\n                serde::de::Unexpected::Bytes(&e.into_bytes()),\n                &self,\n            )),\n        }\n    }\n}\n\nimpl<'de> serde::Deserialize<'de> for ServerAddr {\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: serde::Deserializer<'de>,\n    {\n        deserializer.deserialize_string(ServerAddrVisitor)\n    }\n}\n\nimpl serde::Serialize for ServerAddr {\n    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n    where\n        S: serde::Serializer,\n    {\n        serializer.serialize_str(self.to_string().as_str())\n    }\n}\n\nimpl From<SocketAddr> for ServerAddr {\n    fn from(addr: SocketAddr) -> Self {\n        Self::SocketAddr(addr)\n    }\n}\n\nimpl<I: Into<String>> From<(I, u16)> for ServerAddr {\n    fn from((dname, port): (I, u16)) -> Self {\n        Self::DomainName(dname.into(), port)\n    }\n}\n\nimpl From<Address> for ServerAddr {\n    fn from(addr: Address) -> Self {\n        match addr {\n            Address::SocketAddress(sa) => Self::SocketAddr(sa),\n            Address::DomainNameAddress(dn, port) => Self::DomainName(dn, port),\n        }\n    }\n}\n\nimpl From<&Address> for ServerAddr {\n    fn from(addr: &Address) -> Self {\n        match *addr {\n            Address::SocketAddress(sa) => Self::SocketAddr(sa),\n            Address::DomainNameAddress(ref dn, port) => Self::DomainName(dn.clone(), port),\n        }\n    }\n}\n\nimpl From<ServerAddr> for Address {\n    fn from(addr: ServerAddr) -> Self {\n        match addr {\n            ServerAddr::SocketAddr(sa) => Self::SocketAddress(sa),\n            ServerAddr::DomainName(dn, port) => Self::DomainNameAddress(dn, port),\n        }\n    }\n}\n\nimpl From<&ServerAddr> for Address {\n    fn from(addr: &ServerAddr) -> Self {\n        match *addr {\n            ServerAddr::SocketAddr(sa) => Self::SocketAddress(sa),\n            ServerAddr::DomainName(ref dn, port) => Self::DomainNameAddress(dn.clone(), port),\n        }\n    }\n}\n\n/// Address for Manager server\n#[derive(Debug, Clone)]\npub enum ManagerAddr {\n    /// IP address\n    SocketAddr(SocketAddr),\n    /// Domain name address\n    DomainName(String, u16),\n    /// Unix socket path\n    #[cfg(unix)]\n    UnixSocketAddr(PathBuf),\n}\n\n/// Error for parsing `ManagerAddr`\n#[derive(Debug)]\npub struct ManagerAddrError;\n\nimpl Display for ManagerAddrError {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.write_str(\"invalid ManagerAddr\")\n    }\n}\n\nimpl FromStr for ManagerAddr {\n    type Err = ManagerAddrError;\n\n    fn from_str(s: &str) -> Result<Self, ManagerAddrError> {\n        match s.find(':') {\n            Some(pos) => {\n                // Contains a ':' in address, must be IP:Port or Domain:Port\n                match s.parse::<SocketAddr>() {\n                    Ok(saddr) => Ok(Self::SocketAddr(saddr)),\n                    Err(..) => {\n                        // Splits into Domain and Port\n                        let (sdomain, sport) = s.split_at(pos);\n                        let (sdomain, sport) = (sdomain.trim(), sport[1..].trim());\n\n                        match sport.parse::<u16>() {\n                            Ok(port) => Ok(Self::DomainName(sdomain.to_owned(), port)),\n                            Err(..) => Err(ManagerAddrError),\n                        }\n                    }\n                }\n            }\n            #[cfg(unix)]\n            None => {\n                // Must be a unix socket path\n                Ok(Self::UnixSocketAddr(PathBuf::from(s)))\n            }\n            #[cfg(not(unix))]\n            None => Err(ManagerAddrError),\n        }\n    }\n}\n\nimpl Display for ManagerAddr {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        match *self {\n            Self::SocketAddr(ref saddr) => fmt::Display::fmt(saddr, f),\n            Self::DomainName(ref dname, port) => write!(f, \"{dname}:{port}\"),\n            #[cfg(unix)]\n            Self::UnixSocketAddr(ref path) => fmt::Display::fmt(&path.display(), f),\n        }\n    }\n}\n\nstruct ManagerAddrVisitor;\n\nimpl serde::de::Visitor<'_> for ManagerAddrVisitor {\n    type Value = ManagerAddr;\n\n    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n        formatter.write_str(\"ManagerAddr\")\n    }\n\n    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>\n    where\n        E: serde::de::Error,\n    {\n        match v.parse::<ManagerAddr>() {\n            Ok(m) => Ok(m),\n            Err(_) => Err(serde::de::Error::invalid_value(serde::de::Unexpected::Str(v), &self)),\n        }\n    }\n\n    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>\n    where\n        E: serde::de::Error,\n    {\n        self.visit_str::<E>(v.as_str())\n    }\n\n    fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>\n    where\n        E: serde::de::Error,\n    {\n        match str::from_utf8(v) {\n            Ok(v) => self.visit_str(v),\n            Err(_) => Err(serde::de::Error::invalid_value(serde::de::Unexpected::Bytes(v), &self)),\n        }\n    }\n\n    fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>\n    where\n        E: serde::de::Error,\n    {\n        match String::from_utf8(v) {\n            Ok(v) => self.visit_string(v),\n            Err(e) => Err(serde::de::Error::invalid_value(\n                serde::de::Unexpected::Bytes(&e.into_bytes()),\n                &self,\n            )),\n        }\n    }\n}\n\nimpl<'de> serde::Deserialize<'de> for ManagerAddr {\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: serde::Deserializer<'de>,\n    {\n        deserializer.deserialize_string(ManagerAddrVisitor)\n    }\n}\n\nimpl serde::Serialize for ManagerAddr {\n    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n    where\n        S: serde::Serializer,\n    {\n        serializer.serialize_str(self.to_string().as_str())\n    }\n}\n\nimpl From<SocketAddr> for ManagerAddr {\n    fn from(addr: SocketAddr) -> Self {\n        Self::SocketAddr(addr)\n    }\n}\n\nimpl<'a> From<(&'a str, u16)> for ManagerAddr {\n    fn from((dname, port): (&'a str, u16)) -> Self {\n        Self::DomainName(dname.to_owned(), port)\n    }\n}\n\nimpl From<(String, u16)> for ManagerAddr {\n    fn from((dname, port): (String, u16)) -> Self {\n        Self::DomainName(dname, port)\n    }\n}\n\n#[cfg(unix)]\nimpl From<PathBuf> for ManagerAddr {\n    fn from(p: PathBuf) -> Self {\n        Self::UnixSocketAddr(p)\n    }\n}\n\n/// Policy for handling replay attack requests\n#[derive(Debug, Clone, Copy, Eq, PartialEq, Default)]\npub enum ReplayAttackPolicy {\n    /// Default strategy based on protocol\n    ///\n    /// SIP022 (AEAD-2022): Reject\n    /// SIP004 (AEAD): Ignore\n    /// Stream: Ignore\n    #[default]\n    Default,\n    /// Ignore it completely\n    Ignore,\n    /// Try to detect replay attack and warn about it\n    Detect,\n    /// Try to detect replay attack and reject the request\n    Reject,\n}\n\nimpl Display for ReplayAttackPolicy {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        match *self {\n            Self::Default => f.write_str(\"default\"),\n            Self::Ignore => f.write_str(\"ignore\"),\n            Self::Detect => f.write_str(\"detect\"),\n            Self::Reject => f.write_str(\"reject\"),\n        }\n    }\n}\n\n/// Error while parsing ReplayAttackPolicy from string\n#[derive(Debug, Clone, Copy)]\npub struct ReplayAttackPolicyError;\n\nimpl Display for ReplayAttackPolicyError {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.write_str(\"invalid ReplayAttackPolicy\")\n    }\n}\n\nimpl FromStr for ReplayAttackPolicy {\n    type Err = ReplayAttackPolicyError;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        match s {\n            \"default\" => Ok(Self::Default),\n            \"ignore\" => Ok(Self::Ignore),\n            \"detect\" => Ok(Self::Detect),\n            \"reject\" => Ok(Self::Reject),\n            _ => Err(ReplayAttackPolicyError),\n        }\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n\n    #[test]\n    fn test_server_config_from_url() {\n        let server_config = ServerConfig::from_url(\"ss://foo:bar@127.0.0.1:9999\");\n        assert!(matches!(server_config, Err(UrlParseError::InvalidMethod)));\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/context.rs",
    "content": "//! Shadowsocks service context\n\nuse std::{io, net::SocketAddr, sync::Arc};\n\nuse byte_string::ByteStr;\nuse log::warn;\n\nuse crate::{\n    config::{ReplayAttackPolicy, ServerType},\n    crypto::CipherKind,\n    dns_resolver::DnsResolver,\n    security::replay::ReplayProtector,\n};\n\n/// Service context\n#[derive(Debug)]\npub struct Context {\n    // Protector against replay attack\n    // The actual replay detection behavior is implemented in ReplayProtector\n    replay_protector: ReplayProtector,\n    // Policy against replay attack\n    replay_policy: ReplayAttackPolicy,\n\n    // hickory-dns resolver, which supports REAL asynchronous resolving, and also customizable\n    dns_resolver: Arc<DnsResolver>,\n\n    // Connect IPv6 address first\n    ipv6_first: bool,\n}\n\n/// `Context` for sharing between services\npub type SharedContext = Arc<Context>;\n\nimpl Context {\n    /// Create a new `Context` for `Client` or `Server`\n    pub fn new(config_type: ServerType) -> Self {\n        Self {\n            replay_protector: ReplayProtector::new(config_type),\n            replay_policy: ReplayAttackPolicy::Default,\n            dns_resolver: Arc::new(DnsResolver::system_resolver()),\n            ipv6_first: false,\n        }\n    }\n\n    /// Create a new `Context` shared\n    pub fn new_shared(config_type: ServerType) -> SharedContext {\n        SharedContext::new(Self::new(config_type))\n    }\n\n    /// Check if nonce exist or not\n    ///\n    /// If not, set into the current bloom filter\n    #[cfg(any(feature = \"stream-cipher\", feature = \"aead-cipher\", feature = \"aead-cipher-2022\"))]\n    #[inline(always)]\n    fn check_nonce_and_set(&self, method: CipherKind, nonce: &[u8]) -> bool {\n        match self.replay_policy {\n            ReplayAttackPolicy::Ignore => false,\n            _ => self.replay_protector.check_nonce_and_set(method, nonce),\n        }\n    }\n\n    /// Generate nonce (IV or SALT)\n    pub fn generate_nonce(&self, method: CipherKind, nonce: &mut [u8], unique: bool) {\n        if nonce.is_empty() {\n            return;\n        }\n\n        #[cfg(any(feature = \"stream-cipher\", feature = \"aead-cipher\", feature = \"aead-cipher-2022\"))]\n        loop {\n            use crate::crypto::utils::random_iv_or_salt;\n\n            random_iv_or_salt(nonce);\n\n            // Salt already exists, generate a new one.\n            if unique && self.check_nonce_and_set(method, nonce) {\n                continue;\n            }\n\n            break;\n        }\n\n        #[cfg(not(any(feature = \"stream-cipher\", feature = \"aead-cipher\", feature = \"aead-cipher-2022\")))]\n        if !nonce.is_empty() {\n            let _ = unique;\n            panic!(\"{method} don't know how to generate nonce\");\n        }\n    }\n\n    /// Check nonce replay\n    pub fn check_nonce_replay(&self, method: CipherKind, nonce: &[u8]) -> io::Result<()> {\n        if nonce.is_empty() {\n            return Ok(());\n        }\n\n        #[allow(unused_mut)]\n        let mut replay_policy = self.replay_policy;\n\n        #[cfg(feature = \"aead-cipher-2022\")]\n        if method.is_aead_2022() {\n            // AEAD-2022 can't be ignored.\n            replay_policy = ReplayAttackPolicy::Reject;\n        }\n\n        match replay_policy {\n            ReplayAttackPolicy::Default | ReplayAttackPolicy::Ignore => Ok(()),\n            ReplayAttackPolicy::Detect => {\n                if self.replay_protector.check_nonce_and_set(method, nonce) {\n                    warn!(\"detected repeated nonce (iv/salt) {:?}\", ByteStr::new(nonce));\n                }\n                Ok(())\n            }\n            ReplayAttackPolicy::Reject => {\n                if self.replay_protector.check_nonce_and_set(method, nonce) {\n                    let err = io::Error::other(\"detected repeated nonce (iv/salt)\");\n                    Err(err)\n                } else {\n                    Ok(())\n                }\n            }\n        }\n    }\n\n    /// Set a DNS resolver\n    ///\n    /// The resolver should be wrapped in an `Arc`, because it could be shared with the other servers\n    pub fn set_dns_resolver(&mut self, resolver: Arc<DnsResolver>) {\n        self.dns_resolver = resolver;\n    }\n\n    /// Get the DNS resolver\n    pub fn dns_resolver(&self) -> &Arc<DnsResolver> {\n        &self.dns_resolver\n    }\n\n    /// Resolves DNS address to `SocketAddr`s\n    pub async fn dns_resolve<'a>(\n        &self,\n        addr: &'a str,\n        port: u16,\n    ) -> io::Result<impl Iterator<Item = SocketAddr> + 'a + use<'a>> {\n        self.dns_resolver.resolve(addr, port).await\n    }\n\n    /// Try to connect IPv6 addresses first if hostname could be resolved to both IPv4 and IPv6\n    pub fn set_ipv6_first(&mut self, ipv6_first: bool) {\n        self.ipv6_first = ipv6_first;\n    }\n\n    /// Try to connect IPv6 addresses first if hostname could be resolved to both IPv4 and IPv6\n    pub fn ipv6_first(&self) -> bool {\n        self.ipv6_first\n    }\n\n    /// Set policy against replay attack\n    pub fn set_replay_attack_policy(&mut self, replay_policy: ReplayAttackPolicy) {\n        self.replay_policy = replay_policy;\n    }\n\n    /// Get policy against replay attack\n    pub fn replay_attack_policy(&self) -> ReplayAttackPolicy {\n        self.replay_policy\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/dns_resolver/hickory_dns_resolver.rs",
    "content": "//! Asynchronous DNS resolver\n\nuse std::{\n    future::Future,\n    io,\n    net::SocketAddr,\n    ops::Deref,\n    pin::Pin,\n    task::{Context, Poll},\n    time::Duration,\n};\n\nuse futures::ready;\nuse hickory_resolver::{\n    ResolveError, Resolver,\n    config::{LookupIpStrategy, ResolverConfig, ResolverOpts},\n    name_server::GenericConnector,\n    proto::{\n        runtime::{RuntimeProvider, TokioHandle, TokioTime, iocompat::AsyncIoTokioAsStd},\n        udp::DnsUdpSocket,\n    },\n};\nuse log::{error, trace};\nuse tokio::{io::ReadBuf, net::UdpSocket};\n\nuse crate::net::{ConnectOpts, tcp::TcpStream as ShadowTcpStream, udp::UdpSocket as ShadowUdpSocket};\n\n/// Shadowsocks hickory-dns Runtime Provider\n#[derive(Clone)]\npub struct ShadowDnsRuntimeProvider {\n    handle: TokioHandle,\n    connect_opts: ConnectOpts,\n}\n\nimpl ShadowDnsRuntimeProvider {\n    fn new(connect_opts: ConnectOpts) -> Self {\n        Self {\n            handle: TokioHandle::default(),\n            connect_opts,\n        }\n    }\n}\n\nimpl DnsUdpSocket for ShadowUdpSocket {\n    type Time = TokioTime;\n\n    #[inline]\n    fn poll_recv_from(&self, cx: &mut Context<'_>, buf: &mut [u8]) -> Poll<io::Result<(usize, SocketAddr)>> {\n        let udp: &UdpSocket = self.deref();\n\n        let mut read_buf = ReadBuf::new(buf);\n        let recv_addr = ready!(udp.poll_recv_from(cx, &mut read_buf))?;\n        Ok((read_buf.filled().len(), recv_addr)).into()\n    }\n\n    #[inline]\n    fn poll_send_to(&self, cx: &mut Context<'_>, buf: &[u8], target: SocketAddr) -> Poll<io::Result<usize>> {\n        let udp: &UdpSocket = self.deref();\n        udp.poll_send_to(cx, buf, target)\n    }\n}\n\nimpl RuntimeProvider for ShadowDnsRuntimeProvider {\n    type Handle = TokioHandle;\n    type Tcp = AsyncIoTokioAsStd<ShadowTcpStream>;\n    type Timer = TokioTime;\n    type Udp = ShadowUdpSocket;\n\n    fn create_handle(&self) -> Self::Handle {\n        self.handle.clone()\n    }\n\n    fn connect_tcp(\n        &self,\n        server_addr: SocketAddr,\n        bind_addr: Option<SocketAddr>,\n        wait_for: Option<Duration>,\n    ) -> Pin<Box<dyn Send + Future<Output = io::Result<Self::Tcp>>>> {\n        let mut connect_opts = self.connect_opts.clone();\n\n        if let Some(bind_addr) = bind_addr {\n            connect_opts.bind_local_addr = Some(bind_addr);\n        }\n\n        let wait_for = wait_for.unwrap_or_else(|| Duration::from_secs(5));\n\n        Box::pin(async move {\n            trace!(\n                \"hickory-dns RuntimeProvider tcp connecting to {} with {:?}\",\n                server_addr, connect_opts\n            );\n\n            let tcp = match tokio::time::timeout(\n                wait_for,\n                ShadowTcpStream::connect_with_opts(&server_addr, &connect_opts),\n            )\n            .await\n            {\n                Ok(Ok(s)) => s,\n                Ok(Err(err)) => return Err(err),\n                Err(_) => return Err(io::ErrorKind::TimedOut.into()),\n            };\n\n            trace!(\n                \"hickory-dns RuntimeProvider tcp connected to {}, {:?}\",\n                server_addr, connect_opts\n            );\n            Ok(AsyncIoTokioAsStd(tcp))\n        })\n    }\n\n    fn bind_udp(\n        &self,\n        local_addr: SocketAddr,\n        _server_addr: SocketAddr,\n    ) -> Pin<Box<dyn Send + Future<Output = std::io::Result<Self::Udp>>>> {\n        let connect_opts = self.connect_opts.clone();\n        Box::pin(async move {\n            trace!(\n                \"hickory-dns RuntimeProvider udp binding to {} with {:?}\",\n                local_addr, connect_opts\n            );\n            let udp = ShadowUdpSocket::bind_with_opts(&local_addr, &connect_opts).await?;\n            trace!(\n                \"hickory-dns RuntimeProvider udp bound to {}, {:?}\",\n                local_addr, connect_opts\n            );\n            Ok(udp)\n        })\n    }\n}\n\n/// Shadowsocks DNS ConnectionProvider\npub type ShadowDnsConnectionProvider = GenericConnector<ShadowDnsRuntimeProvider>;\n\n/// Shadowsocks DNS resolver\n///\n/// A customized hickory-dns-resolver\npub type DnsResolver = Resolver<ShadowDnsConnectionProvider>;\n\n/// Create a `hickory-dns` asynchronous DNS resolver\npub async fn create_resolver(\n    dns: Option<ResolverConfig>,\n    opts: Option<ResolverOpts>,\n    connect_opts: ConnectOpts,\n) -> Result<DnsResolver, ResolveError> {\n    // Customized dns resolution\n    match dns {\n        Some(conf) => {\n            trace!(\"initializing DNS resolver with config {:?}\", conf,);\n\n            let mut builder = DnsResolver::builder_with_config(\n                conf,\n                ShadowDnsConnectionProvider::new(ShadowDnsRuntimeProvider::new(connect_opts)),\n            );\n            if let Some(opts) = opts {\n                *builder.options_mut() = opts;\n            }\n            let resolver_opts = builder.options_mut();\n\n            // Use Ipv4AndIpv6 strategy. Because Ipv4ThenIpv6 or Ipv6ThenIpv4 will return if the first query returned.\n            // Since we want to use Happy Eyeballs to connect to both IPv4 and IPv6 addresses, we need both A and AAAA records.\n            resolver_opts.ip_strategy = LookupIpStrategy::Ipv4AndIpv6;\n\n            // Enable EDNS0 for large records\n            resolver_opts.edns0 = true;\n\n            trace!(\"initializing DNS resolver with opts {:?}\", resolver_opts);\n\n            Ok(builder.build())\n        }\n\n        // To make this independent, if targeting macOS, BSD, Linux, or Windows, we can use the system's configuration\n        // Android doesn't have /etc/resolv.conf.\n        None => {\n            match DnsResolver::builder(ShadowDnsConnectionProvider::new(ShadowDnsRuntimeProvider::new(\n                connect_opts,\n            ))) {\n                Ok(mut builder) => {\n                    let opts = builder.options_mut();\n                    // NOTE: timeout will be set by config (for example, /etc/resolv.conf on UNIX-like system)\n                    //\n                    // Only ip_strategy should be changed. Why Ipv4AndIpv6? See comments above.\n                    opts.ip_strategy = LookupIpStrategy::Ipv4AndIpv6;\n\n                    // Enable EDNS0 for large records\n                    opts.edns0 = true;\n\n                    trace!(\"initializing DNS resolver with system-config opts {:?}\", opts);\n\n                    Ok(builder.build())\n                }\n                Err(err) => {\n                    error!(\"initialize DNS resolver with system-config failed, error: {}\", err);\n                    Err(ResolveError::from(\n                        \"current platform doesn't support hickory-dns resolver with system configured\".to_owned(),\n                    ))\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/dns_resolver/mod.rs",
    "content": "//! Asynchronous DNS resolver\n#![macro_use]\n\npub use self::resolver::{DnsResolve, DnsResolver};\n\n#[cfg(feature = \"hickory-dns\")]\nmod hickory_dns_resolver;\nmod resolver;\n\n/// Helper macro for resolving host and then process each addresses\n#[macro_export]\nmacro_rules! lookup_then {\n    ($context:expr_2021, $addr:expr_2021, $port:expr_2021, |$resolved_addr:ident| $body:block) => {{\n        use std::net::SocketAddr;\n\n        let ipv6_first = $context.ipv6_first();\n\n        let mut v4_addrs = Vec::new();\n        let mut v6_addrs = Vec::new();\n\n        for addr in $context.dns_resolve($addr, $port).await? {\n            match addr {\n                SocketAddr::V4(..) => v4_addrs.push(addr),\n                SocketAddr::V6(..) => v6_addrs.push(addr),\n            }\n        }\n\n        let has_v4 = !v4_addrs.is_empty();\n        let has_v6 = !v6_addrs.is_empty();\n\n        assert!(has_v4 || has_v6, \"resolved empty address\");\n\n        if !has_v4 && has_v6 {\n            lookup_then!(RESOLVE @ v6_addrs, $resolved_addr, $body)\n        } else if has_v4 && !has_v6 {\n            lookup_then!(RESOLVE @ v4_addrs, $resolved_addr, $body)\n        } else {\n            if ipv6_first {\n                match lookup_then!(RESOLVE @ v6_addrs, $resolved_addr, $body) {\n                    Ok(r) => Ok(r),\n                    Err(_v6_err) => lookup_then!(RESOLVE @ v4_addrs, $resolved_addr, $body),\n                }\n            } else {\n                match lookup_then!(RESOLVE @ v4_addrs, $resolved_addr, $body) {\n                    Ok(r) => Ok(r),\n                    Err(_v4_err) => lookup_then!(RESOLVE @ v6_addrs, $resolved_addr, $body),\n                }\n            }\n        }\n    }};\n\n    (RESOLVE @ $addrs:expr_2021, $resolved_addr:ident, $body:block) => {{\n        let mut result = None;\n\n        for $resolved_addr in $addrs {\n            match $body {\n                Ok(r) => {\n                    result = Some(Ok(($resolved_addr, r)));\n                    break;\n                }\n                Err(err) => {\n                    result = Some(Err(err));\n                }\n            }\n        }\n\n        result.expect(\"resolved empty address\")\n    }};\n}\n\n#[macro_export]\nmacro_rules! lookup_then_connect {\n    ($context:expr_2021, $addr:expr_2021, $port:expr_2021, |$resolved_addr:ident| $body:block) => {{\n        use futures::future::{self, Either};\n        use log::trace;\n        use std::{net::SocketAddr, time::Duration};\n        use tokio::time;\n\n        let ipv6_first = $context.ipv6_first();\n\n        let mut v4_addrs = Vec::new();\n        let mut v6_addrs = Vec::new();\n\n        for addr in $context.dns_resolve($addr, $port).await? {\n            match addr {\n                SocketAddr::V4(..) => v4_addrs.push(addr),\n                SocketAddr::V6(..) => v6_addrs.push(addr),\n            }\n        }\n\n        let has_v4 = !v4_addrs.is_empty();\n        let has_v6 = !v6_addrs.is_empty();\n\n        assert!(has_v4 || has_v6, \"resolved empty address\");\n\n        // Happy Eyeballs, RFC6555, RFC8305\n        //\n        // RFC6555 gives an example that Chrome and Firefox uses 300ms\n        const FIXED_DELAY: Duration = Duration::from_millis(300);\n\n        // Connects every addresses synchronously.\n        // TODO: Try another address after FIXED_DELAY if one of the IPs is unreachable.\n        //\n        // This would require `future::select_ok`, which will require futures to be `Unpin`\n        // (boxed future, excessive memory allocation).\n\n        let connect_v4 = async {\n            // use futures::FutureExt;\n            //\n            // let mut vfut = Vec::new();\n            //\n            // let mut delay = Duration::from_millis(0);\n            //\n            // for $resolved_addr in v4_addrs {\n            //     vfut.push(\n            //         async move {\n            //             if delay != Duration::from_millis(0) {\n            //                 time::sleep(delay).await;\n            //             }\n            //\n            //             trace!(\"trying connect {}:{} {}\", $addr, $port, $resolved_addr);\n            //\n            //             match $body {\n            //                 Ok(r) => Ok(($resolved_addr, r)),\n            //                 Err(err) => Err(err),\n            //             }\n            //         }\n            //         .boxed(),\n            //     );\n            //\n            //     delay += FIXED_DELAY;\n            // }\n            //\n            // match future::select_ok(vfut).await {\n            //     Ok((r, _)) => Ok(r),\n            //     Err(err) => Err(err),\n            // }\n\n            let mut result = None;\n\n            for $resolved_addr in v4_addrs {\n                trace!(\"trying connect {}:{} {}\", $addr, $port, $resolved_addr);\n\n                match $body {\n                    Ok(r) => {\n                        trace!(\"connected {}:{} {}\", $addr, $port, $resolved_addr);\n                        result = Some(Ok(($resolved_addr, r)));\n                        break;\n                    }\n                    Err(err) => {\n                        result = Some(Err(err));\n                    }\n                }\n            }\n\n            result.expect(\"impossible\")\n        };\n\n        let connect_v6 = async {\n            let mut result = None;\n\n            for $resolved_addr in v6_addrs {\n                trace!(\"trying connect {}:{} {}\", $addr, $port, $resolved_addr);\n\n                match $body {\n                    Ok(r) => {\n                        trace!(\"connected {}:{} {}\", $addr, $port, $resolved_addr);\n                        result = Some(Ok(($resolved_addr, r)));\n                        break;\n                    }\n                    Err(err) => {\n                        result = Some(Err(err));\n                    }\n                }\n            }\n\n            result.expect(\"impossible\")\n        };\n\n        if has_v4 && !has_v6 {\n            connect_v4.await\n        } else if !has_v4 && has_v6 {\n            connect_v6.await\n        } else {\n            if ipv6_first {\n                let v4_fut = async move {\n                    time::sleep(FIXED_DELAY).await;\n                    connect_v4.await\n                };\n                let v6_fut = connect_v6;\n\n                tokio::pin!(v4_fut);\n                tokio::pin!(v6_fut);\n\n                match future::select(v4_fut, v6_fut).await {\n                    Either::Left((v4_res, v6_fut)) => match v4_res {\n                        Ok(res) => Ok(res),\n                        Err(_v4_err) => v6_fut.await,\n                    },\n                    Either::Right((v6_res, v4_fut)) => match v6_res {\n                        Ok(res) => Ok(res),\n                        Err(_v6_err) => v4_fut.await,\n                    },\n                }\n            } else {\n                let v6_fut = async move {\n                    time::sleep(FIXED_DELAY).await;\n                    connect_v6.await\n                };\n                let v4_fut = connect_v4;\n\n                tokio::pin!(v4_fut);\n                tokio::pin!(v6_fut);\n\n                match future::select(v4_fut, v6_fut).await {\n                    Either::Left((v4_res, v6_fut)) => match v4_res {\n                        Ok(res) => Ok(res),\n                        Err(_v4_err) => v6_fut.await,\n                    },\n                    Either::Right((v6_res, v4_fut)) => match v6_res {\n                        Ok(res) => Ok(res),\n                        Err(_v6_err) => v4_fut.await,\n                    },\n                }\n            }\n        }\n    }};\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/dns_resolver/resolver.rs",
    "content": "//! Resolver Alternatives\n\n#[cfg(feature = \"hickory-dns\")]\nuse std::sync::Arc;\nuse std::{\n    fmt::{self, Debug},\n    io::{self, Error},\n    net::SocketAddr,\n    time::Instant,\n};\n\n#[cfg(feature = \"hickory-dns\")]\nuse arc_swap::ArcSwap;\nuse cfg_if::cfg_if;\n#[cfg(feature = \"hickory-dns\")]\nuse hickory_resolver::config::ResolverConfig;\n#[cfg(feature = \"hickory-dns\")]\nuse hickory_resolver::config::ResolverOpts;\n#[cfg(all(feature = \"hickory-dns\", unix, not(target_os = \"android\")))]\nuse log::error;\nuse log::{Level, log_enabled, trace};\nuse tokio::net::lookup_host;\n#[cfg(all(feature = \"hickory-dns\", unix, not(target_os = \"android\")))]\nuse tokio::task::JoinHandle;\n\n#[cfg(feature = \"hickory-dns\")]\nuse crate::net::ConnectOpts;\n\n#[cfg(feature = \"hickory-dns\")]\nuse super::hickory_dns_resolver::DnsResolver as HickoryDnsResolver;\n\n/// Abstract DNS resolver\n#[trait_variant::make(Send)]\n#[dynosaur::dynosaur(DynDnsResolve = dyn(box) DnsResolve, bridge(dyn))]\npub trait DnsResolve {\n    /// Resolves `addr:port` to a list of `SocketAddr`\n    async fn resolve(&self, addr: &str, port: u16) -> io::Result<Vec<SocketAddr>>;\n}\n\n// Equivalent to (dyn DnsResolve + Send + Sync)\nunsafe impl Send for DynDnsResolve<'_> {}\nunsafe impl Sync for DynDnsResolve<'_> {}\n\n#[cfg(feature = \"hickory-dns\")]\n#[derive(Debug)]\npub struct HickoryDnsSystemResolver {\n    resolver: ArcSwap<HickoryDnsResolver>,\n    #[cfg_attr(any(windows, target_os = \"android\"), allow(dead_code))]\n    connect_opts: ConnectOpts,\n    #[cfg_attr(any(windows, target_os = \"android\"), allow(dead_code))]\n    opts: Option<ResolverOpts>,\n}\n\n/// Collections of DNS resolver\n#[allow(clippy::large_enum_variant)]\npub enum DnsResolver {\n    /// System Resolver, which is tokio's builtin resolver\n    System,\n    /// Trust-DNS's system resolver\n    #[cfg(feature = \"hickory-dns\")]\n    HickoryDnsSystem {\n        inner: Arc<HickoryDnsSystemResolver>,\n        #[cfg(all(feature = \"hickory-dns\", unix, not(target_os = \"android\")))]\n        abortable: JoinHandle<()>,\n    },\n    /// Trust-DNS resolver\n    #[cfg(feature = \"hickory-dns\")]\n    HickoryDns(HickoryDnsResolver),\n    /// Customized Resolver\n    Custom(Box<DynDnsResolve<'static>>),\n}\n\nimpl Default for DnsResolver {\n    fn default() -> Self {\n        Self::system_resolver()\n    }\n}\n\nimpl Debug for DnsResolver {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        match *self {\n            Self::System => f.write_str(\"System\"),\n            #[cfg(feature = \"hickory-dns\")]\n            Self::HickoryDnsSystem { .. } => f.write_str(\"HickoryDnsSystem(..)\"),\n            #[cfg(feature = \"hickory-dns\")]\n            Self::HickoryDns(..) => f.write_str(\"HickoryDns(..)\"),\n            Self::Custom(..) => f.write_str(\"Custom(..)\"),\n        }\n    }\n}\n\n#[cfg(feature = \"hickory-dns\")]\nimpl Drop for DnsResolver {\n    fn drop(&mut self) {\n        #[cfg(all(feature = \"hickory-dns\", unix, not(target_os = \"android\")))]\n        if let Self::HickoryDnsSystem { ref abortable, .. } = *self {\n            abortable.abort();\n        }\n    }\n}\n\ncfg_if! {\n    if #[cfg(feature = \"hickory-dns\")] {\n        /// Resolved result\n        enum EitherResolved<A, B, C, D> {\n            Tokio(A),\n            HickoryDnsSystem(B),\n            HickoryDns(C),\n            Custom(D),\n        }\n\n        impl<A, B, C, D> Iterator for EitherResolved<A, B, C, D>\n        where\n            A: Iterator<Item = SocketAddr>,\n            B: Iterator<Item = SocketAddr>,\n            C: Iterator<Item = SocketAddr>,\n            D: Iterator<Item = SocketAddr>,\n        {\n            type Item = SocketAddr;\n\n            fn next(&mut self) -> Option<SocketAddr> {\n                match *self {\n                    Self::Tokio(ref mut a) => a.next(),\n                    Self::HickoryDnsSystem(ref mut b) => b.next(),\n                    Self::HickoryDns(ref mut c) => c.next(),\n                    Self::Custom(ref mut d) => d.next(),\n                }\n            }\n        }\n    } else {\n        /// Resolved result\n        enum EitherResolved<A, D> {\n            Tokio(A),\n            Custom(D),\n        }\n\n        impl<A, D> Iterator for EitherResolved<A, D>\n        where\n            A: Iterator<Item = SocketAddr>,\n            D: Iterator<Item = SocketAddr>,\n        {\n            type Item = SocketAddr;\n\n            fn next(&mut self) -> Option<SocketAddr> {\n                match *self {\n                    EitherResolved::Tokio(ref mut a) => a.next(),\n                    EitherResolved::Custom(ref mut d) => d.next(),\n                }\n            }\n        }\n    }\n}\n\n#[cfg(all(feature = \"hickory-dns\", unix, not(target_os = \"android\")))]\nasync fn hickory_dns_notify_update_dns(resolver: Arc<HickoryDnsSystemResolver>) -> notify::Result<()> {\n    use std::{path::Path, time::Duration};\n\n    use log::debug;\n    use notify::{Event, EventKind, RecommendedWatcher, RecursiveMode, Result as NotifyResult, Watcher};\n    use tokio::{sync::watch, time};\n\n    use super::hickory_dns_resolver::create_resolver;\n\n    const DNS_RESOLV_FILE_PATH: &str = \"/etc/resolv.conf\";\n\n    if !Path::new(DNS_RESOLV_FILE_PATH).exists() {\n        trace!(\"resolv file {DNS_RESOLV_FILE_PATH} doesn't exist\");\n        return Ok(());\n    }\n\n    let (tx, mut rx) = watch::channel::<Event>(Event::default());\n\n    let mut watcher: RecommendedWatcher =\n        notify::recommended_watcher(move |ev_result: NotifyResult<Event>| match ev_result {\n            Ok(ev) => {\n                trace!(\"received {DNS_RESOLV_FILE_PATH} event {ev:?}\");\n\n                if let EventKind::Modify(..) = ev.kind {\n                    tx.send(ev).expect(\"watcher.send\");\n                }\n            }\n            Err(err) => {\n                error!(\"watching {DNS_RESOLV_FILE_PATH} error: {err}\");\n            }\n        })?;\n\n    // NOTE: It is an undefined behavior if this file get renamed or removed.\n    watcher.watch(Path::new(DNS_RESOLV_FILE_PATH), RecursiveMode::NonRecursive)?;\n\n    // Delayed task\n    let mut update_task: Option<JoinHandle<()>> = None;\n\n    while rx.changed().await.is_ok() {\n        trace!(\"received notify {DNS_RESOLV_FILE_PATH} changed\");\n\n        // Kill the pending task\n        if let Some(t) = update_task.take() {\n            t.abort();\n        }\n\n        let task = {\n            let resolver = resolver.clone();\n            tokio::spawn(async move {\n                // /etc/resolv.conf may be modified multiple time in 1 second\n                // Update once for all those Modify events\n                time::sleep(Duration::from_secs(1)).await;\n\n                match create_resolver(None, resolver.opts.clone(), resolver.connect_opts.clone()).await {\n                    Ok(r) => {\n                        debug!(\"auto-reload {DNS_RESOLV_FILE_PATH}\");\n\n                        resolver.resolver.store(Arc::new(r));\n                    }\n                    Err(err) => {\n                        error!(\"failed to reload {DNS_RESOLV_FILE_PATH}, error: {err}\");\n                    }\n                }\n            })\n        };\n\n        update_task = Some(task);\n    }\n\n    error!(\"auto-reload {DNS_RESOLV_FILE_PATH} task exited unexpectedly\");\n\n    Ok(())\n}\n\nimpl DnsResolver {\n    /// Use system DNS resolver. Tokio will call `getaddrinfo` in blocking pool.\n    pub fn system_resolver() -> Self {\n        Self::System\n    }\n\n    /// Use hickory-dns DNS system resolver (with DNS cache)\n    ///\n    /// On *nix system, it will try to read configurations from `/etc/resolv.conf`.\n    #[cfg(feature = \"hickory-dns\")]\n    pub async fn hickory_dns_system_resolver(\n        opts: Option<ResolverOpts>,\n        connect_opts: ConnectOpts,\n    ) -> io::Result<Self> {\n        use super::hickory_dns_resolver::create_resolver;\n\n        let resolver = create_resolver(None, opts.clone(), connect_opts.clone()).await?;\n\n        let inner = Arc::new(HickoryDnsSystemResolver {\n            resolver: ArcSwap::from(Arc::new(resolver)),\n            connect_opts,\n            opts,\n        });\n\n        cfg_if! {\n            if #[cfg(all(feature = \"hickory-dns\", unix, not(target_os = \"android\")))] {\n                let abortable = {\n                    let inner = inner.clone();\n                    tokio::spawn(async {\n                        if let Err(err) = hickory_dns_notify_update_dns(inner).await {\n                            error!(\"failed to watch DNS system configuration changes, error: {}\", err);\n                        }\n                    })\n                };\n\n                Ok(Self::HickoryDnsSystem { inner, abortable })\n            } else {\n                Ok(DnsResolver::HickoryDnsSystem { inner })\n            }\n        }\n    }\n\n    /// Use hickory-dns DNS resolver (with DNS cache)\n    #[cfg(feature = \"hickory-dns\")]\n    pub async fn hickory_resolver(\n        dns: ResolverConfig,\n        opts: Option<ResolverOpts>,\n        connect_opts: ConnectOpts,\n    ) -> io::Result<Self> {\n        use super::hickory_dns_resolver::create_resolver;\n        Ok(Self::HickoryDns(create_resolver(Some(dns), opts, connect_opts).await?))\n    }\n\n    /// Custom DNS resolver\n    pub fn custom_resolver<R>(custom: R) -> Self\n    where\n        R: DnsResolve + Send + Sync + 'static,\n    {\n        Self::Custom(DynDnsResolve::new_box(custom))\n    }\n\n    /// Resolve address into `SocketAddr`s\n    pub async fn resolve<'a>(\n        &self,\n        addr: &'a str,\n        port: u16,\n    ) -> io::Result<impl Iterator<Item = SocketAddr> + 'a + use<'a>> {\n        struct ResolverLogger<'x, 'y> {\n            resolver: &'x DnsResolver,\n            addr: &'y str,\n            port: u16,\n            start_time: Option<Instant>,\n        }\n\n        impl<'x, 'y> ResolverLogger<'x, 'y> {\n            fn new(resolver: &'x DnsResolver, addr: &'y str, port: u16) -> Self {\n                let start_time = if log_enabled!(Level::Trace) {\n                    Some(Instant::now())\n                } else {\n                    None\n                };\n\n                ResolverLogger {\n                    resolver,\n                    addr,\n                    port,\n                    start_time,\n                }\n            }\n        }\n\n        impl Drop for ResolverLogger<'_, '_> {\n            fn drop(&mut self) {\n                match self.start_time {\n                    Some(start_time) => {\n                        let end_time = Instant::now();\n                        let elapsed = end_time - start_time;\n\n                        match *self.resolver {\n                            DnsResolver::System => {\n                                trace!(\n                                    \"DNS resolved {}:{} with tokio {}s\",\n                                    self.addr,\n                                    self.port,\n                                    elapsed.as_secs_f32()\n                                );\n                            }\n                            #[cfg(feature = \"hickory-dns\")]\n                            DnsResolver::HickoryDnsSystem { .. } | DnsResolver::HickoryDns(..) => {\n                                trace!(\n                                    \"DNS resolved {}:{} with hickory-dns {}s\",\n                                    self.addr,\n                                    self.port,\n                                    elapsed.as_secs_f32()\n                                );\n                            }\n                            DnsResolver::Custom(..) => {\n                                trace!(\n                                    \"DNS resolved {}:{} with customized {}s\",\n                                    self.addr,\n                                    self.port,\n                                    elapsed.as_secs_f32()\n                                );\n                            }\n                        }\n                    }\n                    None => match *self.resolver {\n                        DnsResolver::System => {\n                            trace!(\"DNS resolved {}:{} with tokio\", self.addr, self.port);\n                        }\n                        #[cfg(feature = \"hickory-dns\")]\n                        DnsResolver::HickoryDnsSystem { .. } | DnsResolver::HickoryDns(..) => {\n                            trace!(\"DNS resolved {}:{} with hickory-dns\", self.addr, self.port);\n                        }\n                        DnsResolver::Custom(..) => {\n                            trace!(\"DNS resolved {}:{} with customized\", self.addr, self.port);\n                        }\n                    },\n                }\n            }\n        }\n\n        let _log_guard = ResolverLogger::new(self, addr, port);\n\n        match *self {\n            Self::System => match lookup_host((addr, port)).await {\n                Ok(v) => Ok(EitherResolved::Tokio(v)),\n                Err(err) => {\n                    let err = Error::other(format!(\"dns resolve {addr}:{port} error: {err}\"));\n                    Err(err)\n                }\n            },\n            #[cfg(feature = \"hickory-dns\")]\n            Self::HickoryDnsSystem { ref inner, .. } => match inner.resolver.load().lookup_ip(addr).await {\n                Ok(lookup_result) => Ok(EitherResolved::HickoryDnsSystem(\n                    lookup_result.into_iter().map(move |ip| SocketAddr::new(ip, port)),\n                )),\n                Err(err) => {\n                    let err = Error::other(format!(\"dns resolve {addr}:{port} error: {err}\"));\n                    Err(err)\n                }\n            },\n            #[cfg(feature = \"hickory-dns\")]\n            Self::HickoryDns(ref resolver) => match resolver.lookup_ip(addr).await {\n                Ok(lookup_result) => Ok(EitherResolved::HickoryDns(\n                    lookup_result.into_iter().map(move |ip| SocketAddr::new(ip, port)),\n                )),\n                Err(err) => {\n                    let err = Error::other(format!(\"dns resolve {addr}:{port} error: {err}\"));\n                    Err(err)\n                }\n            },\n            Self::Custom(ref resolver) => match resolver.resolve(addr, port).await {\n                Ok(v) => Ok(EitherResolved::Custom(v.into_iter())),\n                Err(err) => {\n                    let err = Error::other(format!(\"dns resolve {addr}:{port} error: {err}\"));\n                    Err(err)\n                }\n            },\n        }\n    }\n\n    /// Check if currently using system resolver\n    pub fn is_system_resolver(&self) -> bool {\n        matches!(*self, Self::System)\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/lib.rs",
    "content": "//! Shadowsocks Core Library\n\n#![crate_type = \"lib\"]\n\npub use self::{\n    config::{ManagerAddr, ServerAddr, ServerConfig},\n    manager::{ManagerClient, ManagerListener},\n    relay::{\n        tcprelay::{proxy_listener::ProxyListener, proxy_stream::ProxyClientStream},\n        udprelay::proxy_socket::ProxySocket,\n    },\n};\n\npub use shadowsocks_crypto as crypto;\n\npub mod config;\npub mod context;\npub mod dns_resolver;\npub mod manager;\npub mod net;\npub mod plugin;\npub mod relay;\nmod security;\n"
  },
  {
    "path": "crates/shadowsocks/src/manager/client.rs",
    "content": "//! Manager client\n\nuse log::warn;\n\nuse crate::{config::ManagerAddr, context::Context, net::ConnectOpts, relay::udprelay::MAXIMUM_UDP_PAYLOAD_SIZE};\n\nuse super::{\n    datagram::ManagerDatagram,\n    error::Error,\n    protocol::{\n        AddRequest, AddResponse, ListRequest, ListResponse, ManagerProtocol, PingRequest, PingResponse, RemoveRequest,\n        RemoveResponse, StatRequest,\n    },\n};\n\n/// Client for communicating with Manager\npub struct ManagerClient {\n    socket: ManagerDatagram,\n}\n\nmacro_rules! impl_command {\n    ($command:ident, $req:ty, $rsp:ty) => {\n        /// Send command\n        pub async fn $command(&mut self, req: &$req) -> Result<$rsp, Error> {\n            self.request(req).await\n        }\n    };\n}\n\nimpl ManagerClient {\n    impl_command!(add, AddRequest, AddResponse);\n\n    impl_command!(list, ListRequest, ListResponse);\n\n    impl_command!(ping, PingRequest, PingResponse);\n\n    impl_command!(remove, RemoveRequest, RemoveResponse);\n\n    /// Create a `ManagerDatagram` for sending data to manager\n    pub async fn connect(\n        context: &Context,\n        bind_addr: &ManagerAddr,\n        connect_opts: &ConnectOpts,\n    ) -> Result<Self, Error> {\n        ManagerDatagram::connect(context, bind_addr, connect_opts)\n            .await\n            .map(|socket| Self { socket })\n            .map_err(Into::into)\n    }\n\n    /// Send `stat` report\n    pub async fn stat(&mut self, req: &StatRequest) -> Result<(), Error> {\n        let buf = req.to_bytes()?;\n        let n = self.socket.send(&buf).await?;\n        if n != buf.len() {\n            warn!(\"manager send {} bytes != buffer {} bytes\", n, buf.len());\n        }\n        Ok(())\n    }\n\n    async fn request<S, R>(&mut self, req: &S) -> Result<R, Error>\n    where\n        S: ManagerProtocol,\n        R: ManagerProtocol,\n    {\n        let buf = req.to_bytes()?;\n        let n = self.socket.send(&buf).await?;\n        if n != buf.len() {\n            warn!(\"manager send {} bytes != buffer {} bytes\", n, buf.len());\n        }\n\n        let mut buf = [0u8; MAXIMUM_UDP_PAYLOAD_SIZE];\n        let n = self.socket.recv(&mut buf).await?;\n        R::from_bytes(&buf[..n]).map_err(Into::into)\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/manager/datagram.rs",
    "content": "//! Shadowsocks manager connecting interface\n\n#[cfg(unix)]\nuse std::io::ErrorKind;\nuse std::{fmt, io, net::SocketAddr};\n\nuse tokio::net::UdpSocket;\n#[cfg(unix)]\nuse tokio::net::{UnixDatagram, unix::SocketAddr as UnixSocketAddr};\n\nuse crate::{\n    config::ManagerAddr,\n    context::Context,\n    net::{ConnectOpts, UdpSocket as ShadowUdpSocket},\n};\n\n/// Address accepted from Manager\n#[derive(Debug)]\npub enum ManagerSocketAddr {\n    SocketAddr(SocketAddr),\n    #[cfg(unix)]\n    UnixSocketAddr(UnixSocketAddr),\n}\n\nimpl ManagerSocketAddr {\n    /// Check if it is unnamed (not binded to any valid address), only valid for `UnixSocketAddr`\n    pub fn is_unnamed(&self) -> bool {\n        match *self {\n            Self::SocketAddr(..) => false,\n            #[cfg(unix)]\n            Self::UnixSocketAddr(ref s) => s.is_unnamed(),\n        }\n    }\n}\n\nimpl fmt::Display for ManagerSocketAddr {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match *self {\n            Self::SocketAddr(ref saddr) => fmt::Display::fmt(saddr, f),\n            #[cfg(unix)]\n            Self::UnixSocketAddr(ref saddr) => fmt::Debug::fmt(saddr, f),\n        }\n    }\n}\n\n/// Datagram socket for manager\n///\n/// For *nix system, this is a wrapper for both UDP socket and Unix socket\n#[derive(Debug)]\npub enum ManagerDatagram {\n    UdpDatagram(UdpSocket),\n    #[cfg(unix)]\n    UnixDatagram(UnixDatagram),\n}\n\nimpl ManagerDatagram {\n    /// Create a `ManagerDatagram` binding to requested `bind_addr`\n    pub async fn bind(context: &Context, bind_addr: &ManagerAddr) -> io::Result<Self> {\n        match *bind_addr {\n            ManagerAddr::SocketAddr(ref saddr) => Ok(Self::UdpDatagram(ShadowUdpSocket::listen(saddr).await?.into())),\n            ManagerAddr::DomainName(ref dname, port) => {\n                let (_, socket) =\n                    lookup_then!(context, dname, port, |saddr| { ShadowUdpSocket::listen(&saddr).await })?;\n\n                Ok(Self::UdpDatagram(socket.into()))\n            }\n            #[cfg(unix)]\n            ManagerAddr::UnixSocketAddr(ref path) => {\n                use std::fs;\n\n                // Remove it first incase it is already exists\n                let _ = fs::remove_file(path);\n\n                Ok(Self::UnixDatagram(UnixDatagram::bind(path)?))\n            }\n        }\n    }\n\n    /// Create a `ManagerDatagram` for sending data to manager\n    pub async fn connect(context: &Context, bind_addr: &ManagerAddr, connect_opts: &ConnectOpts) -> io::Result<Self> {\n        match *bind_addr {\n            ManagerAddr::SocketAddr(sa) => Self::connect_socket_addr(sa, connect_opts).await,\n\n            ManagerAddr::DomainName(ref dname, port) => {\n                // Try connect to all socket addresses\n                lookup_then!(context, dname, port, |addr| {\n                    Self::connect_socket_addr(addr, connect_opts).await\n                })\n                .map(|(_, d)| d)\n            }\n\n            #[cfg(unix)]\n            // For unix socket, it doesn't need to bind to any valid address\n            // Because manager won't response to you\n            ManagerAddr::UnixSocketAddr(ref path) => {\n                let dgram = UnixDatagram::unbound()?;\n                dgram.connect(path)?;\n                Ok(Self::UnixDatagram(dgram))\n            }\n        }\n    }\n\n    async fn connect_socket_addr(sa: SocketAddr, connect_opts: &ConnectOpts) -> io::Result<Self> {\n        let socket = ShadowUdpSocket::connect_with_opts(&sa, connect_opts).await?;\n        Ok(Self::UdpDatagram(socket.into()))\n    }\n\n    /// Receives data from the socket.\n    pub async fn recv(&mut self, buf: &mut [u8]) -> io::Result<usize> {\n        match *self {\n            Self::UdpDatagram(ref mut udp) => udp.recv(buf).await,\n            #[cfg(unix)]\n            Self::UnixDatagram(ref mut unix) => unix.recv(buf).await,\n        }\n    }\n\n    /// Receives data from the socket.\n    pub async fn recv_from(&mut self, buf: &mut [u8]) -> io::Result<(usize, ManagerSocketAddr)> {\n        match *self {\n            Self::UdpDatagram(ref mut udp) => {\n                let (s, addr) = udp.recv_from(buf).await?;\n                Ok((s, ManagerSocketAddr::SocketAddr(addr)))\n            }\n            #[cfg(unix)]\n            Self::UnixDatagram(ref mut unix) => {\n                let (s, addr) = unix.recv_from(buf).await?;\n                Ok((s, ManagerSocketAddr::UnixSocketAddr(addr)))\n            }\n        }\n    }\n\n    /// Sends data to the socket\n    pub async fn send(&mut self, buf: &[u8]) -> io::Result<usize> {\n        match *self {\n            Self::UdpDatagram(ref mut udp) => udp.send(buf).await,\n            #[cfg(unix)]\n            Self::UnixDatagram(ref mut unix) => unix.send(buf).await,\n        }\n    }\n\n    /// Sends data to the socket to the specified address.\n    pub async fn send_to(&mut self, buf: &[u8], target: &ManagerSocketAddr) -> io::Result<usize> {\n        match *self {\n            Self::UdpDatagram(ref mut udp) => match *target {\n                ManagerSocketAddr::SocketAddr(ref saddr) => udp.send_to(buf, saddr).await,\n                #[cfg(unix)]\n                ManagerSocketAddr::UnixSocketAddr(..) => {\n                    let err = io::Error::new(ErrorKind::InvalidInput, \"udp datagram requires IP address target\");\n                    Err(err)\n                }\n            },\n            #[cfg(unix)]\n            Self::UnixDatagram(ref mut unix) => match *target {\n                ManagerSocketAddr::UnixSocketAddr(ref saddr) => match saddr.as_pathname() {\n                    Some(paddr) => unix.send_to(buf, paddr).await,\n                    None => {\n                        let err = io::Error::new(ErrorKind::InvalidInput, \"target address must not be unnamed\");\n                        Err(err)\n                    }\n                },\n                ManagerSocketAddr::SocketAddr(..) => {\n                    let err = io::Error::new(ErrorKind::InvalidInput, \"unix datagram requires path address target\");\n                    Err(err)\n                }\n            },\n        }\n    }\n\n    /// Sends data on the socket to the specified manager address\n    pub async fn send_to_manager(&mut self, buf: &[u8], context: &Context, target: &ManagerAddr) -> io::Result<usize> {\n        match *self {\n            Self::UdpDatagram(ref mut udp) => match *target {\n                ManagerAddr::SocketAddr(ref saddr) => udp.send_to(buf, saddr).await,\n                ManagerAddr::DomainName(ref dname, port) => {\n                    let (_, n) = lookup_then!(context, dname, port, |saddr| { udp.send_to(buf, saddr).await })?;\n                    Ok(n)\n                }\n                #[cfg(unix)]\n                ManagerAddr::UnixSocketAddr(..) => {\n                    let err = io::Error::new(ErrorKind::InvalidInput, \"udp datagram requires IP address target\");\n                    Err(err)\n                }\n            },\n            #[cfg(unix)]\n            Self::UnixDatagram(ref mut unix) => match *target {\n                ManagerAddr::UnixSocketAddr(ref paddr) => unix.send_to(buf, paddr).await,\n                ManagerAddr::SocketAddr(..) | ManagerAddr::DomainName(..) => {\n                    let err = io::Error::new(ErrorKind::InvalidInput, \"unix datagram requires path address target\");\n                    Err(err)\n                }\n            },\n        }\n    }\n\n    /// Returns the local address that this socket is bound to.\n    pub fn local_addr(&self) -> io::Result<ManagerSocketAddr> {\n        match *self {\n            Self::UdpDatagram(ref socket) => socket.local_addr().map(ManagerSocketAddr::SocketAddr),\n            #[cfg(unix)]\n            Self::UnixDatagram(ref dgram) => dgram.local_addr().map(ManagerSocketAddr::UnixSocketAddr),\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/manager/error.rs",
    "content": "//! Manager API errors\n\nuse std::io;\n\nuse thiserror::Error;\n\nuse super::protocol::Error as ProtocolError;\n\n/// Manager Error\n#[derive(Error, Debug)]\npub enum Error {\n    #[error(\"{0}\")]\n    IoError(#[from] io::Error),\n    #[error(transparent)]\n    ProtocolError(#[from] ProtocolError),\n}\n\nimpl From<Error> for io::Error {\n    fn from(e: Error) -> Self {\n        match e {\n            Error::IoError(e) => e,\n            Error::ProtocolError(e) => From::from(e),\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/manager/listener.rs",
    "content": "//! Manager server listener\n\nuse std::io;\n\nuse log::warn;\n\nuse crate::{config::ManagerAddr, context::Context, relay::udprelay::MAXIMUM_UDP_PAYLOAD_SIZE};\n\nuse super::{\n    datagram::{ManagerDatagram, ManagerSocketAddr},\n    error::Error,\n    protocol::{ManagerProtocol, ManagerRequest},\n};\n\n/// Manager server Listener\n#[derive(Debug)]\npub struct ManagerListener {\n    socket: ManagerDatagram,\n}\n\nimpl ManagerListener {\n    /// Create a `ManagerDatagram` binding to requested `bind_addr`\n    pub async fn bind(context: &Context, bind_addr: &ManagerAddr) -> io::Result<Self> {\n        ManagerDatagram::bind(context, bind_addr)\n            .await\n            .map(|socket| Self { socket })\n    }\n\n    pub async fn recv_from(&mut self) -> Result<(ManagerRequest, ManagerSocketAddr), Error> {\n        let mut buf = [0u8; MAXIMUM_UDP_PAYLOAD_SIZE];\n        let (n, peer_addr) = self.socket.recv_from(&mut buf).await?;\n        Ok((ManagerRequest::from_bytes(&buf[..n])?, peer_addr))\n    }\n\n    pub async fn send_to<P: ManagerProtocol>(&mut self, data: &P, target: &ManagerSocketAddr) -> Result<(), Error> {\n        let buf = data.to_bytes()?;\n        let n = self.socket.send_to(&buf, target).await?;\n        if n != buf.len() {\n            warn!(\"manager send_to {} bytes != buffer {} bytes\", n, buf.len());\n        }\n        Ok(())\n    }\n\n    pub fn local_addr(&self) -> io::Result<ManagerSocketAddr> {\n        self.socket.local_addr()\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/manager/mod.rs",
    "content": "//! Shadowsocks Server manager\n//!\n//! Service for managing multiple relay servers. [Manage Multiple Users](https://github.com/shadowsocks/shadowsocks/wiki/Manage-Multiple-Users)\n\npub use self::{client::ManagerClient, listener::ManagerListener};\n\npub mod client;\npub mod datagram;\npub mod error;\npub mod listener;\npub mod protocol;\n"
  },
  {
    "path": "crates/shadowsocks/src/manager/protocol.rs",
    "content": "//! Shadowsocks server manager protocol\n\nuse std::{collections::HashMap, io, str, string::ToString};\n\nuse serde::{Deserialize, Serialize};\nuse thiserror::Error;\n\n/// Abstract Manager Protocol\npub trait ManagerProtocol: Sized {\n    fn from_bytes(buf: &[u8]) -> Result<Self, Error>;\n    fn to_bytes(&self) -> Result<Vec<u8>, Error>;\n}\n\n/// Server's user configuration\n#[derive(Serialize, Deserialize, Debug, Clone)]\npub struct ServerUserConfig {\n    pub name: String,\n    pub password: String,\n}\n\n/// Server's configuration\n#[derive(Serialize, Deserialize, Debug, Clone)]\npub struct ServerConfig {\n    pub server_port: u16,\n    pub password: String,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub method: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub no_delay: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub plugin: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub plugin_opts: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub plugin_mode: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub mode: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub users: Option<Vec<ServerUserConfig>>,\n}\n\n/// `add` request\npub type AddRequest = ServerConfig;\n\nimpl ManagerProtocol for AddRequest {\n    fn from_bytes(buf: &[u8]) -> Result<Self, Error> {\n        let mut nsplit = buf.splitn(2, |b| *b == b':');\n\n        let cmd = nsplit.next().expect(\"first element shouldn't be None\");\n        let cmd = str::from_utf8(cmd)?.trim();\n        if cmd != \"add\" {\n            return Err(Error::UnrecognizedCommand(cmd.to_owned()));\n        }\n\n        match nsplit.next() {\n            None => Err(Error::MissingParameter),\n            Some(param) => {\n                let req = serde_json::from_slice(param)?;\n                Ok(req)\n            }\n        }\n    }\n\n    fn to_bytes(&self) -> Result<Vec<u8>, Error> {\n        let mut buf = b\"add: \".to_vec();\n        serde_json::to_writer(&mut buf, self)?;\n        buf.push(b'\\n');\n        Ok(buf)\n    }\n}\n\n/// `add` response\n#[derive(Debug, Clone)]\npub struct AddResponse(pub String);\n\nimpl ManagerProtocol for AddResponse {\n    fn from_bytes(buf: &[u8]) -> Result<Self, Error> {\n        Ok(Self(str::from_utf8(buf)?.trim().to_owned()))\n    }\n\n    fn to_bytes(&self) -> Result<Vec<u8>, Error> {\n        let mut v = self.0.as_bytes().to_owned();\n        v.push(b'\\n');\n        Ok(v)\n    }\n}\n\n/// `remove` request\n#[derive(Serialize, Deserialize, Debug, Clone)]\npub struct RemoveRequest {\n    pub server_port: u16,\n}\n\nimpl ManagerProtocol for RemoveRequest {\n    fn from_bytes(buf: &[u8]) -> Result<Self, Error> {\n        let mut nsplit = buf.splitn(2, |b| *b == b':');\n\n        let cmd = nsplit.next().expect(\"first element shouldn't be None\");\n        let cmd = str::from_utf8(cmd)?.trim();\n        if cmd != \"remove\" {\n            return Err(Error::UnrecognizedCommand(cmd.to_owned()));\n        }\n\n        match nsplit.next() {\n            None => Err(Error::MissingParameter),\n            Some(param) => {\n                let req = serde_json::from_slice(param)?;\n                Ok(req)\n            }\n        }\n    }\n\n    fn to_bytes(&self) -> Result<Vec<u8>, Error> {\n        let mut buf = b\"remove: \".to_vec();\n        serde_json::to_writer(&mut buf, self)?;\n        buf.push(b'\\n');\n        Ok(buf)\n    }\n}\n\n/// `remove` response\n#[derive(Debug, Clone)]\npub struct RemoveResponse(pub String);\n\nimpl ManagerProtocol for RemoveResponse {\n    fn from_bytes(buf: &[u8]) -> Result<Self, Error> {\n        Ok(Self(str::from_utf8(buf)?.trim().to_owned()))\n    }\n\n    fn to_bytes(&self) -> Result<Vec<u8>, Error> {\n        let mut v = self.0.as_bytes().to_owned();\n        v.push(b'\\n');\n        Ok(v)\n    }\n}\n\n/// `list` request\n#[derive(Debug, Clone)]\npub struct ListRequest;\n\nimpl ManagerProtocol for ListRequest {\n    fn from_bytes(buf: &[u8]) -> Result<Self, Error> {\n        let cmd = str::from_utf8(buf)?;\n        if cmd != \"list\" {\n            return Err(Error::UnrecognizedCommand(cmd.to_owned()));\n        }\n\n        Ok(Self)\n    }\n\n    fn to_bytes(&self) -> Result<Vec<u8>, Error> {\n        Ok(b\"list\\n\".to_vec())\n    }\n}\n\n/// `list` response\n#[derive(Serialize, Deserialize, Debug, Clone)]\n#[serde(transparent)]\npub struct ListResponse {\n    pub servers: Vec<ServerConfig>,\n}\n\nimpl ManagerProtocol for ListResponse {\n    fn from_bytes(buf: &[u8]) -> Result<Self, Error> {\n        let req = serde_json::from_slice(buf)?;\n        Ok(req)\n    }\n\n    fn to_bytes(&self) -> Result<Vec<u8>, Error> {\n        let mut buf = serde_json::to_vec(self)?;\n        buf.push(b'\\n');\n        Ok(buf)\n    }\n}\n\n/// `ping` request\n#[derive(Debug, Clone)]\npub struct PingRequest;\n\nimpl ManagerProtocol for PingRequest {\n    fn from_bytes(buf: &[u8]) -> Result<Self, Error> {\n        let cmd = str::from_utf8(buf)?;\n        if cmd != \"ping\" {\n            return Err(Error::UnrecognizedCommand(cmd.to_owned()));\n        }\n\n        Ok(Self)\n    }\n\n    fn to_bytes(&self) -> Result<Vec<u8>, Error> {\n        Ok(b\"ping\\n\".to_vec())\n    }\n}\n\n/// `ping` response\n#[derive(Serialize, Deserialize, Debug, Clone)]\n#[serde(transparent)]\npub struct PingResponse {\n    pub stat: HashMap<u16, u64>,\n}\n\nimpl ManagerProtocol for PingResponse {\n    fn from_bytes(buf: &[u8]) -> Result<Self, Error> {\n        let mut nsplit = buf.splitn(2, |b| *b == b':');\n\n        let cmd = nsplit.next().expect(\"first element shouldn't be None\");\n        let cmd = str::from_utf8(cmd)?.trim();\n        if cmd != \"stat\" {\n            return Err(Error::UnrecognizedCommand(cmd.to_owned()));\n        }\n\n        match nsplit.next() {\n            None => Err(Error::MissingParameter),\n            Some(param) => {\n                let req = serde_json::from_slice(param)?;\n                Ok(req)\n            }\n        }\n    }\n\n    fn to_bytes(&self) -> Result<Vec<u8>, Error> {\n        let mut buf = b\"stat: \".to_vec();\n        serde_json::to_writer(&mut buf, self)?;\n        buf.push(b'\\n');\n        Ok(buf)\n    }\n}\n\n/// `stat` request\n#[derive(Serialize, Deserialize, Debug, Clone)]\n#[serde(transparent)]\npub struct StatRequest {\n    pub stat: HashMap<u16, u64>,\n}\n\nimpl ManagerProtocol for StatRequest {\n    fn from_bytes(buf: &[u8]) -> Result<Self, Error> {\n        let mut nsplit = buf.splitn(2, |b| *b == b':');\n\n        let cmd = nsplit.next().expect(\"first element shouldn't be None\");\n        let cmd = str::from_utf8(cmd)?.trim();\n        if cmd != \"stat\" {\n            return Err(Error::UnrecognizedCommand(cmd.to_owned()));\n        }\n\n        match nsplit.next() {\n            None => Err(Error::MissingParameter),\n            Some(param) => {\n                let req = serde_json::from_slice(param)?;\n                Ok(req)\n            }\n        }\n    }\n\n    fn to_bytes(&self) -> Result<Vec<u8>, Error> {\n        let mut buf = b\"stat: \".to_vec();\n        serde_json::to_writer(&mut buf, self)?;\n        buf.push(b'\\n');\n        Ok(buf)\n    }\n}\n\n/// Server's error message\n#[derive(Debug, Clone)]\npub struct ErrorResponse<E: ToString>(pub E);\n\nimpl<E: ToString> ManagerProtocol for ErrorResponse<E> {\n    fn from_bytes(_: &[u8]) -> Result<Self, Error> {\n        panic!(\"ErrorResponse is only for sending errors from manager servers\");\n    }\n\n    fn to_bytes(&self) -> Result<Vec<u8>, Error> {\n        let mut v = self.0.to_string().into_bytes();\n        v.push(b'\\n');\n        Ok(v)\n    }\n}\n\n/// Collections of Manager's request\n#[derive(Debug, Clone)]\npub enum ManagerRequest {\n    Add(AddRequest),\n    Remove(RemoveRequest),\n    List(ListRequest),\n    Ping(PingRequest),\n    Stat(StatRequest),\n}\n\nimpl ManagerRequest {\n    /// Command key\n    pub fn command(&self) -> &'static str {\n        match *self {\n            Self::Add(..) => \"add\",\n            Self::Remove(..) => \"remove\",\n            Self::List(..) => \"list\",\n            Self::Ping(..) => \"ping\",\n            Self::Stat(..) => \"stat\",\n        }\n    }\n}\n\nimpl ManagerProtocol for ManagerRequest {\n    fn to_bytes(&self) -> Result<Vec<u8>, Error> {\n        match *self {\n            Self::Add(ref req) => req.to_bytes(),\n            Self::Remove(ref req) => req.to_bytes(),\n            Self::List(ref req) => req.to_bytes(),\n            Self::Ping(ref req) => req.to_bytes(),\n            Self::Stat(ref req) => req.to_bytes(),\n        }\n    }\n\n    fn from_bytes(buf: &[u8]) -> Result<Self, Error> {\n        let mut nsplit = buf.splitn(2, |b| *b == b':');\n\n        let cmd = nsplit.next().expect(\"first element shouldn't be None\");\n        match str::from_utf8(cmd)?.trim() {\n            \"add\" => match nsplit.next() {\n                None => Err(Error::MissingParameter),\n                Some(param) => {\n                    let req = serde_json::from_slice(param)?;\n                    Ok(Self::Add(req))\n                }\n            },\n            \"remove\" => match nsplit.next() {\n                None => Err(Error::MissingParameter),\n                Some(param) => {\n                    let req = serde_json::from_slice(param)?;\n                    Ok(Self::Remove(req))\n                }\n            },\n            \"list\" => {\n                if nsplit.next().is_some() {\n                    return Err(Error::RedundantParameter);\n                }\n                Ok(Self::List(ListRequest))\n            }\n            \"ping\" => {\n                if nsplit.next().is_some() {\n                    return Err(Error::RedundantParameter);\n                }\n                Ok(Self::Ping(PingRequest))\n            }\n            \"stat\" => match nsplit.next() {\n                None => Err(Error::MissingParameter),\n                Some(param) => {\n                    let req = serde_json::from_slice(param)?;\n                    Ok(Self::Stat(req))\n                }\n            },\n            cmd => Err(Error::UnrecognizedCommand(cmd.to_owned())),\n        }\n    }\n}\n\n/// Manager's Error\n#[derive(Error, Debug)]\npub enum Error {\n    #[error(\"{0}\")]\n    JsonError(#[from] serde_json::Error),\n    #[error(\"{0}\")]\n    FromUtf8Error(#[from] std::str::Utf8Error),\n    #[error(\"missing parameter\")]\n    MissingParameter,\n    #[error(\"redundant parameter\")]\n    RedundantParameter,\n    #[error(\"unrecognized command \\\"{0}\\\"\")]\n    UnrecognizedCommand(String),\n}\n\nimpl From<Error> for io::Error {\n    fn from(err: Error) -> Self {\n        Self::other(err.to_string())\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/net/mod.rs",
    "content": "//! Network wrappers for shadowsocks' specific requirements\n\nuse std::net::SocketAddr;\n\n#[cfg(unix)]\npub use self::sys::uds::{UnixListener, UnixStream};\npub use self::{\n    option::{AcceptOpts, ConnectOpts, TcpSocketOpts, UdpSocketOpts},\n    sys::{IpStackCapabilities, get_ip_stack_capabilities, set_tcp_fastopen, socket_bind_dual_stack},\n    tcp::{TcpListener, TcpStream},\n    udp::UdpSocket,\n};\n\nmod option;\nmod sys;\npub mod tcp;\npub mod udp;\n\n/// Address family `AF_INET`, `AF_INET6`\n#[derive(Clone, Copy, Debug, Eq, PartialEq)]\npub enum AddrFamily {\n    /// `AF_INET`\n    Ipv4,\n    /// `AF_INET6`\n    Ipv6,\n}\n\nimpl From<&SocketAddr> for AddrFamily {\n    fn from(addr: &SocketAddr) -> Self {\n        match *addr {\n            SocketAddr::V4(..) => Self::Ipv4,\n            SocketAddr::V6(..) => Self::Ipv6,\n        }\n    }\n}\n\nimpl From<SocketAddr> for AddrFamily {\n    fn from(addr: SocketAddr) -> Self {\n        match addr {\n            SocketAddr::V4(..) => Self::Ipv4,\n            SocketAddr::V6(..) => Self::Ipv6,\n        }\n    }\n}\n\n/// Check if `SocketAddr` could be used for creating dual-stack sockets\npub fn is_dual_stack_addr(addr: &SocketAddr) -> bool {\n    if let SocketAddr::V6(ref v6) = *addr {\n        let ip = v6.ip();\n        ip.is_unspecified() || ip.to_ipv4_mapped().is_some()\n    } else {\n        false\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/net/option.rs",
    "content": "//! Options for connecting to remote server\n\nuse std::{net::SocketAddr, time::Duration};\n\n/// Options for connecting to TCP remote server\n#[derive(Debug, Clone, Default)]\npub struct TcpSocketOpts {\n    /// TCP socket's `SO_SNDBUF`\n    pub send_buffer_size: Option<u32>,\n\n    /// TCP socket's `SO_RCVBUF`\n    pub recv_buffer_size: Option<u32>,\n\n    /// `TCP_NODELAY`\n    pub nodelay: bool,\n\n    /// `TCP_FASTOPEN`, enables TFO\n    pub fastopen: bool,\n\n    /// `SO_KEEPALIVE` and sets `TCP_KEEPIDLE`, `TCP_KEEPINTVL` and `TCP_KEEPCNT` respectively,\n    /// enables keep-alive messages on connection-oriented sockets\n    pub keepalive: Option<Duration>,\n\n    /// Enable Multipath-TCP (mptcp)\n    /// https://en.wikipedia.org/wiki/Multipath_TCP\n    ///\n    /// Currently only supported on\n    /// - macOS (iOS, watchOS, ...) with Client Support only.\n    /// - Linux (>5.19)\n    pub mptcp: bool,\n}\n\n/// Options for UDP server\n#[derive(Debug, Clone, Default)]\npub struct UdpSocketOpts {\n    /// Maximum Transmission Unit (MTU) for UDP socket `recv`\n    ///\n    /// NOTE: MTU includes IP header, UDP header, UDP payload\n    pub mtu: Option<usize>,\n\n    /// Outbound UDP socket allows IP fragmentation\n    pub allow_fragmentation: bool,\n}\n\n/// Options for connecting to remote server\n#[derive(Debug, Clone, Default)]\npub struct ConnectOpts {\n    /// Linux mark based routing, going to set by `setsockopt` with `SO_MARK` option\n    #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n    pub fwmark: Option<u32>,\n\n    /// FreeBSD SO_USER_COOKIE\n    /// https://www.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2\n    #[cfg(target_os = \"freebsd\")]\n    pub user_cookie: Option<u32>,\n\n    /// An IPC unix socket path for sending file descriptors to call `VpnService.protect`\n    ///\n    /// This is an [Android shadowsocks implementation](https://github.com/shadowsocks/shadowsocks-android) specific feature\n    #[cfg(target_os = \"android\")]\n    pub vpn_protect_path: Option<std::path::PathBuf>,\n    /// A customizable socket protect implementation for Android for calling `VpnService.protect(fd)`\n    ///\n    /// see [`ConnectOpts::set_vpn_socket_protect`]\n    #[cfg(target_os = \"android\")]\n    pub vpn_socket_protect: Option<std::sync::Arc<Box<dyn android::SocketProtect + Send + Sync>>>,\n\n    /// Outbound socket binds to this IP address, mostly for choosing network interfaces\n    ///\n    /// It only affects sockets that trying to connect to addresses with the same family\n    pub bind_local_addr: Option<SocketAddr>,\n\n    /// Outbound socket binds to interface\n    pub bind_interface: Option<String>,\n\n    /// TCP options\n    pub tcp: TcpSocketOpts,\n\n    /// UDP options\n    pub udp: UdpSocketOpts,\n}\n\n/// Inbound connection options\n#[derive(Clone, Debug, Default)]\npub struct AcceptOpts {\n    /// TCP options\n    pub tcp: TcpSocketOpts,\n\n    /// UDP options\n    pub udp: UdpSocketOpts,\n\n    /// Enable IPV6_V6ONLY option for socket\n    pub ipv6_only: bool,\n}\n\n#[cfg(target_os = \"android\")]\nimpl ConnectOpts {\n    /// Set `vpn_protect_path` for Android VPNService.protect implementation\n    ///\n    /// Example:\n    ///\n    /// ```rust\n    /// // Sync function for calling `VpnService.protect(fd)`\n    /// opts.set_vpn_socket_protect(|fd| {\n    ///     // Your implementation here\n    ///     // For example, using `jni` to call Android's VpnService.protect(fd)\n    ///     Ok(())\n    /// });\n    /// ```\n    pub fn set_vpn_socket_protect<F>(&mut self, f: F)\n    where\n        F: android::MakeSocketProtect + Send + Sync + 'static,\n        F::SocketProtectType: android::SocketProtect + Send + Sync + 'static,\n    {\n        self.vpn_socket_protect = Some(std::sync::Arc::new(Box::new(f.make_socket_protect())));\n    }\n}\n\n/// Android specific features\n#[cfg(target_os = \"android\")]\npub mod android {\n    use sealed::sealed;\n    use std::{fmt, io, os::unix::io::RawFd};\n\n    /// Android VPN socket protect implementation\n    #[sealed]\n    pub trait SocketProtect {\n        /// Protects the socket file descriptor by calling `VpnService.protect(fd)`\n        fn protect(&self, fd: RawFd) -> io::Result<()>;\n    }\n\n    impl fmt::Debug for dyn SocketProtect + Send + Sync {\n        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n            f.debug_struct(\"SocketProtect\").finish_non_exhaustive()\n        }\n    }\n\n    /// Creating an instance of `SocketProtect`\n    #[sealed]\n    pub trait MakeSocketProtect {\n        type SocketProtectType: SocketProtect;\n\n        /// Creates an instance of `SocketProtect`\n        fn make_socket_protect(self) -> Self::SocketProtectType;\n    }\n\n    /// A function that implements `SocketProtect` trait\n    pub struct SocketProtectFn<F> {\n        f: F,\n    }\n\n    #[sealed]\n    impl<F> SocketProtect for SocketProtectFn<F>\n    where\n        F: Fn(RawFd) -> io::Result<()> + Send + Sync + 'static,\n    {\n        fn protect(&self, fd: RawFd) -> io::Result<()> {\n            (self.f)(fd)\n        }\n    }\n\n    #[sealed]\n    impl<F> MakeSocketProtect for F\n    where\n        F: Fn(RawFd) -> io::Result<()> + Send + Sync + 'static,\n    {\n        type SocketProtectType = SocketProtectFn<F>;\n\n        fn make_socket_protect(self) -> Self::SocketProtectType {\n            SocketProtectFn { f: self }\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/net/sys/mod.rs",
    "content": "use std::{\n    io::{self, ErrorKind},\n    net::{Ipv4Addr, Ipv6Addr, SocketAddr},\n    sync::LazyLock,\n};\n\nuse cfg_if::cfg_if;\nuse log::{debug, warn};\nuse socket2::{Domain, Protocol, SockAddr, SockRef, Socket, Type};\nuse tokio::net::TcpSocket;\n\nuse super::ConnectOpts;\n\ncfg_if! {\n    if #[cfg(unix)] {\n        mod unix;\n        pub use self::unix::*;\n    } else if #[cfg(windows)] {\n        mod windows;\n        pub use self::windows::*;\n    }\n}\n\nfn set_common_sockopt_for_connect(addr: SocketAddr, socket: &TcpSocket, opts: &ConnectOpts) -> io::Result<()> {\n    // Binds to IP address\n    if let Some(baddr) = opts.bind_local_addr {\n        match (baddr, addr) {\n            (SocketAddr::V4(..), SocketAddr::V4(..)) => {\n                socket.bind(baddr)?;\n            }\n            (SocketAddr::V4(v4baddr), SocketAddr::V6(..)) => {\n                socket.bind(SocketAddr::new(v4baddr.ip().to_ipv6_mapped().into(), v4baddr.port()))?;\n            }\n            (SocketAddr::V6(..), SocketAddr::V6(..)) => {\n                socket.bind(baddr)?;\n            }\n            (SocketAddr::V6(v6baddr), SocketAddr::V4(..)) => match v6baddr.ip().to_ipv4_mapped() {\n                Some(v4baddr) => socket.bind(SocketAddr::new(v4baddr.into(), v6baddr.port()))?,\n                None => {\n                    return Err(io::Error::new(\n                        ErrorKind::InvalidInput,\n                        \"bind_local_addr is not a valid IPv4-mapped IPv6 address\",\n                    ));\n                }\n            },\n        }\n    }\n\n    // Set `SO_SNDBUF`\n    if let Some(buf_size) = opts.tcp.send_buffer_size {\n        socket.set_send_buffer_size(buf_size)?;\n    }\n\n    // Set `SO_RCVBUF`\n    if let Some(buf_size) = opts.tcp.recv_buffer_size {\n        socket.set_recv_buffer_size(buf_size)?;\n    }\n\n    Ok(())\n}\n\n#[cfg(all(not(windows), not(unix)))]\n#[inline]\nfn set_common_sockopt_after_connect_sys(_: &tokio::net::TcpStream, _: &ConnectOpts) -> io::Result<()> {\n    Ok(())\n}\n\n/// Try to call `bind()` with dual-stack enabled.\n///\n/// Users have to ensure that `addr` is a dual-stack inbound address (`::`) when `ipv6_only` is `false`.\n#[cfg(unix)]\npub fn socket_bind_dual_stack<S>(socket: &S, addr: &SocketAddr, ipv6_only: bool) -> io::Result<()>\nwhere\n    S: std::os::unix::io::AsFd,\n{\n    let sock = SockRef::from(socket);\n    socket_bind_dual_stack_inner(&sock, addr, ipv6_only)\n}\n\n/// Try to call `bind()` with dual-stack enabled.\n///\n/// Users have to ensure that `addr` is a dual-stack inbound address (`::`) when `ipv6_only` is `false`.\n#[cfg(windows)]\npub fn socket_bind_dual_stack<S>(socket: &S, addr: &SocketAddr, ipv6_only: bool) -> io::Result<()>\nwhere\n    S: std::os::windows::io::AsSocket,\n{\n    let sock = SockRef::from(socket);\n    socket_bind_dual_stack_inner(&sock, addr, ipv6_only)\n}\n\nfn socket_bind_dual_stack_inner(socket: &Socket, addr: &SocketAddr, ipv6_only: bool) -> io::Result<()> {\n    let saddr = SockAddr::from(*addr);\n\n    if ipv6_only {\n        // Requested to set IPV6_V6ONLY\n        socket.set_only_v6(true)?;\n        socket.bind(&saddr)?;\n    } else {\n        if let Err(err) = socket.set_only_v6(false) {\n            warn!(\"failed to set IPV6_V6ONLY: false for socket, error: {}\", err);\n\n            // This is not a fatal error, just warn and skip\n        }\n\n        match socket.bind(&saddr) {\n            Ok(..) => {}\n            Err(ref err) if err.kind() == ErrorKind::AddrInUse => {\n                // This is probably 0.0.0.0 with the same port has already been occupied\n                debug!(\n                    \"0.0.0.0:{} may have already been occupied, retry with IPV6_V6ONLY\",\n                    addr.port()\n                );\n\n                if let Err(err) = socket.set_only_v6(true) {\n                    warn!(\"failed to set IPV6_V6ONLY: true for socket, error: {}\", err);\n\n                    // This is not a fatal error, just warn and skip\n                }\n                socket.bind(&saddr)?;\n            }\n            Err(err) => return Err(err),\n        }\n    }\n\n    Ok(())\n}\n\n/// IP Stack Capabilities\n#[derive(Debug, Clone, Copy, Default)]\npub struct IpStackCapabilities {\n    /// IP stack supports IPv4\n    pub support_ipv4: bool,\n    /// IP stack supports IPv6\n    pub support_ipv6: bool,\n    /// IP stack supports IPv4-mapped-IPv6\n    pub support_ipv4_mapped_ipv6: bool,\n}\n\nstatic IP_STACK_CAPABILITIES: LazyLock<IpStackCapabilities> = LazyLock::new(|| {\n    // Reference Implementation: https://github.com/golang/go/blob/master/src/net/ipsock_posix.go\n\n    let mut caps = IpStackCapabilities {\n        support_ipv4: false,\n        support_ipv6: false,\n        support_ipv4_mapped_ipv6: false,\n    };\n\n    // Check IPv4\n    if Socket::new(Domain::IPV4, Type::STREAM, Some(Protocol::TCP)).is_ok() {\n        caps.support_ipv4 = true;\n        debug!(\"IpStackCapability support_ipv4=true\");\n    }\n\n    // Check IPv6 (::1)\n    if let Ok(ipv6_socket) = Socket::new(Domain::IPV6, Type::STREAM, Some(Protocol::TCP))\n        && ipv6_socket.set_only_v6(true).is_ok()\n    {\n        let local_host = SockAddr::from(SocketAddr::new(Ipv6Addr::LOCALHOST.into(), 0));\n        if ipv6_socket.bind(&local_host).is_ok() {\n            caps.support_ipv6 = true;\n            debug!(\"IpStackCapability support_ipv6=true\");\n        }\n    }\n\n    // Check IPv4-mapped-IPv6 (127.0.0.1)\n    if check_ipv4_mapped_ipv6_capability().is_ok() {\n        caps.support_ipv4_mapped_ipv6 = true;\n        debug!(\"IpStackCapability support_ipv4_mapped_ipv6=true\");\n    }\n\n    caps\n});\n\nfn check_ipv4_mapped_ipv6_capability() -> io::Result<()> {\n    let socket = Socket::new(Domain::IPV6, Type::STREAM, Some(Protocol::TCP))?;\n    socket.set_only_v6(false)?;\n\n    let local_host = SockAddr::from(SocketAddr::new(Ipv4Addr::LOCALHOST.to_ipv6_mapped().into(), 0));\n    socket.bind(&local_host)?;\n\n    Ok(())\n}\n\n/// Get globally probed `IpStackCapabilities`\npub fn get_ip_stack_capabilities() -> &'static IpStackCapabilities {\n    &IP_STACK_CAPABILITIES\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/net/sys/unix/bsd/freebsd.rs",
    "content": "use std::{\n    io::{self, ErrorKind},\n    mem,\n    net::{Ipv4Addr, Ipv6Addr, SocketAddr},\n    os::unix::io::{AsRawFd, RawFd},\n    pin::Pin,\n    ptr,\n    sync::atomic::{AtomicBool, Ordering},\n    task::{self, Poll},\n};\n\nuse log::{debug, error, warn};\nuse pin_project::pin_project;\nuse socket2::{Domain, Protocol, SockAddr, SockAddrStorage, Socket, Type};\nuse tokio::{\n    io::{AsyncRead, AsyncWrite, ReadBuf},\n    net::{TcpSocket, TcpStream as TokioTcpStream, UdpSocket},\n};\nuse tokio_tfo::TfoStream;\n\nuse crate::net::{\n    AcceptOpts, AddrFamily, ConnectOpts,\n    sys::{set_common_sockopt_after_connect, set_common_sockopt_for_connect, socket_bind_dual_stack},\n    udp::{BatchRecvMessage, BatchSendMessage},\n};\n\n/// A `TcpStream` that supports TFO (TCP Fast Open)\n#[pin_project(project = TcpStreamProj)]\npub enum TcpStream {\n    Standard(#[pin] TokioTcpStream),\n    FastOpen(#[pin] TfoStream),\n}\n\nimpl TcpStream {\n    pub async fn connect(addr: SocketAddr, opts: &ConnectOpts) -> io::Result<TcpStream> {\n        let socket = match addr {\n            SocketAddr::V4(..) => TcpSocket::new_v4()?,\n            SocketAddr::V6(..) => TcpSocket::new_v6()?,\n        };\n\n        // Set SO_USER_COOKIE for mark-based routing on FreeBSD\n        if let Some(user_cookie) = opts.user_cookie {\n            let ret = unsafe {\n                libc::setsockopt(\n                    socket.as_raw_fd(),\n                    libc::SOL_SOCKET,\n                    libc::SO_USER_COOKIE,\n                    &user_cookie as *const _ as *const _,\n                    mem::size_of_val(&user_cookie) as libc::socklen_t,\n                )\n            };\n            if ret != 0 {\n                let err = io::Error::last_os_error();\n                error!(\"set SO_USER_COOKIE error: {}\", err);\n                return Err(err);\n            }\n        }\n\n        set_common_sockopt_for_connect(addr, &socket, opts)?;\n\n        if !opts.tcp.fastopen {\n            // If TFO is not enabled, it just works like a normal TcpStream\n            let stream = socket.connect(addr).await?;\n            set_common_sockopt_after_connect(&stream, opts)?;\n\n            return Ok(TcpStream::Standard(stream));\n        }\n\n        let stream = TfoStream::connect_with_socket(socket, addr).await?;\n        set_common_sockopt_after_connect(&stream, opts)?;\n\n        Ok(TcpStream::FastOpen(stream))\n    }\n\n    pub fn local_addr(&self) -> io::Result<SocketAddr> {\n        match *self {\n            TcpStream::Standard(ref s) => s.local_addr(),\n            TcpStream::FastOpen(ref s) => s.local_addr(),\n        }\n    }\n\n    pub fn peer_addr(&self) -> io::Result<SocketAddr> {\n        match *self {\n            TcpStream::Standard(ref s) => s.peer_addr(),\n            TcpStream::FastOpen(ref s) => s.peer_addr(),\n        }\n    }\n\n    pub fn nodelay(&self) -> io::Result<bool> {\n        match *self {\n            TcpStream::Standard(ref s) => s.nodelay(),\n            TcpStream::FastOpen(ref s) => s.nodelay(),\n        }\n    }\n\n    pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {\n        match *self {\n            TcpStream::Standard(ref s) => s.set_nodelay(nodelay),\n            TcpStream::FastOpen(ref s) => s.set_nodelay(nodelay),\n        }\n    }\n}\n\nimpl AsRawFd for TcpStream {\n    fn as_raw_fd(&self) -> RawFd {\n        match *self {\n            TcpStream::Standard(ref s) => s.as_raw_fd(),\n            TcpStream::FastOpen(ref s) => s.as_raw_fd(),\n        }\n    }\n}\n\nimpl AsyncRead for TcpStream {\n    fn poll_read(self: Pin<&mut Self>, cx: &mut task::Context<'_>, buf: &mut ReadBuf<'_>) -> Poll<io::Result<()>> {\n        match self.project() {\n            TcpStreamProj::Standard(s) => s.poll_read(cx, buf),\n            TcpStreamProj::FastOpen(s) => s.poll_read(cx, buf),\n        }\n    }\n}\n\nimpl AsyncWrite for TcpStream {\n    fn poll_write(self: Pin<&mut Self>, cx: &mut task::Context<'_>, buf: &[u8]) -> Poll<io::Result<usize>> {\n        match self.project() {\n            TcpStreamProj::Standard(s) => s.poll_write(cx, buf),\n            TcpStreamProj::FastOpen(s) => s.poll_write(cx, buf),\n        }\n    }\n\n    fn poll_flush(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<io::Result<()>> {\n        match self.project() {\n            TcpStreamProj::Standard(s) => s.poll_flush(cx),\n            TcpStreamProj::FastOpen(s) => s.poll_flush(cx),\n        }\n    }\n\n    fn poll_shutdown(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<io::Result<()>> {\n        match self.project() {\n            TcpStreamProj::Standard(s) => s.poll_shutdown(cx),\n            TcpStreamProj::FastOpen(s) => s.poll_shutdown(cx),\n        }\n    }\n}\n\n/// Enable `TCP_FASTOPEN`\n///\n/// TCP_FASTOPEN was supported since FreeBSD 12.0\n///\n/// Example program: <https://people.freebsd.org/~pkelsey/tfo-tools/tfo-srv.c>\npub fn set_tcp_fastopen<S: AsRawFd>(socket: &S) -> io::Result<()> {\n    let enable: libc::c_int = 1;\n\n    unsafe {\n        let ret = libc::setsockopt(\n            socket.as_raw_fd(),\n            libc::IPPROTO_TCP,\n            libc::TCP_FASTOPEN,\n            &enable as *const _ as *const libc::c_void,\n            mem::size_of_val(&enable) as libc::socklen_t,\n        );\n\n        if ret != 0 {\n            let err = io::Error::last_os_error();\n            error!(\"set TCP_FASTOPEN error: {}\", err);\n            return Err(err);\n        }\n    }\n\n    Ok(())\n}\n\n/// Create a TCP socket for listening\npub async fn create_inbound_tcp_socket(bind_addr: &SocketAddr, _accept_opts: &AcceptOpts) -> io::Result<TcpSocket> {\n    match bind_addr {\n        SocketAddr::V4(..) => TcpSocket::new_v4(),\n        SocketAddr::V6(..) => TcpSocket::new_v6(),\n    }\n}\n\n/// Disable IP fragmentation\n#[inline]\npub fn set_disable_ip_fragmentation<S: AsRawFd>(af: AddrFamily, socket: &S) -> io::Result<()> {\n    // https://www.freebsd.org/cgi/man.cgi?query=ip&sektion=4&manpath=FreeBSD+9.0-RELEASE\n\n    // sys/netinet/in.h\n    const IP_DONTFRAG: libc::c_int = 67; // don't fragment packet\n\n    // sys/netinet6/in6.h\n    const IPV6_DONTFRAG: libc::c_int = 62; // bool; disable IPv6 fragmentation\n\n    unsafe {\n        match af {\n            AddrFamily::Ipv4 => {\n                let enable: i32 = 1;\n                let ret = libc::setsockopt(\n                    socket.as_raw_fd(),\n                    libc::IPPROTO_IP,\n                    IP_DONTFRAG,\n                    &enable as *const _ as *const _,\n                    mem::size_of_val(&enable) as libc::socklen_t,\n                );\n\n                if ret < 0 {\n                    return Err(io::Error::last_os_error());\n                }\n            }\n            AddrFamily::Ipv6 => {\n                let enable: i32 = 1;\n                let ret = libc::setsockopt(\n                    socket.as_raw_fd(),\n                    libc::IPPROTO_IPV6,\n                    IPV6_DONTFRAG,\n                    &enable as *const _ as *const _,\n                    mem::size_of_val(&enable) as libc::socklen_t,\n                );\n\n                if ret < 0 {\n                    return Err(io::Error::last_os_error());\n                }\n            }\n        }\n    }\n\n    Ok(())\n}\n\n/// Create a `UdpSocket` with specific address family\n#[inline]\npub async fn create_outbound_udp_socket(af: AddrFamily, config: &ConnectOpts) -> io::Result<UdpSocket> {\n    let bind_addr = match (af, config.bind_local_addr) {\n        (AddrFamily::Ipv4, Some(SocketAddr::V4(addr))) => addr.into(),\n        (AddrFamily::Ipv4, Some(SocketAddr::V6(addr))) => {\n            // Map IPv6 bind_local_addr to IPv4 if AF is IPv4\n            match addr.ip().to_ipv4_mapped() {\n                Some(addr) => SocketAddr::new(addr.into(), 0),\n                None => return Err(io::Error::new(ErrorKind::InvalidInput, \"Invalid IPv6 address\")),\n            }\n        }\n        (AddrFamily::Ipv6, Some(SocketAddr::V6(addr))) => addr.into(),\n        (AddrFamily::Ipv6, Some(SocketAddr::V4(addr))) => {\n            // Map IPv4 bind_local_addr to IPv6 if AF is IPv6\n            SocketAddr::new(addr.ip().to_ipv6_mapped().into(), 0)\n        }\n        (AddrFamily::Ipv4, ..) => SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), 0),\n        (AddrFamily::Ipv6, ..) => SocketAddr::new(Ipv6Addr::UNSPECIFIED.into(), 0),\n    };\n\n    bind_outbound_udp_socket(&bind_addr, config).await\n}\n\n/// Create a `UdpSocket` binded to `bind_addr`\npub async fn bind_outbound_udp_socket(bind_addr: &SocketAddr, config: &ConnectOpts) -> io::Result<UdpSocket> {\n    let af = AddrFamily::from(bind_addr);\n\n    let socket = if af != AddrFamily::Ipv6 {\n        UdpSocket::bind(bind_addr).await?\n    } else {\n        let socket = Socket::new(Domain::for_address(*bind_addr), Type::DGRAM, Some(Protocol::UDP))?;\n        socket_bind_dual_stack(&socket, bind_addr, false)?;\n\n        // UdpSocket::from_std requires socket to be non-blocked\n        socket.set_nonblocking(true)?;\n        UdpSocket::from_std(socket.into())?\n    };\n\n    if !config.udp.allow_fragmentation {\n        if let Err(err) = set_disable_ip_fragmentation(af, &socket) {\n            warn!(\"failed to disable IP fragmentation, error: {}\", err);\n        }\n    }\n\n    Ok(socket)\n}\n\nstatic SUPPORT_BATCH_SEND_RECV_MSG: AtomicBool = AtomicBool::new(true);\n\nfn recvmsg_fallback<S: AsRawFd>(sock: &S, msg: &mut BatchRecvMessage<'_>) -> io::Result<()> {\n    let mut hdr: libc::msghdr = unsafe { mem::zeroed() };\n\n    let addr_storage = SockAddrStorage::zeroed();\n    let addr_len = addr_storage.size_of() as libc::socklen_t;\n\n    let sock_addr = unsafe { SockAddr::new(addr_storage, addr_len) };\n    hdr.msg_name = sock_addr.as_ptr() as *mut _;\n    hdr.msg_namelen = sock_addr.len() as _;\n\n    hdr.msg_iov = msg.data.as_ptr() as *mut _;\n    hdr.msg_iovlen = msg.data.len() as _;\n\n    let ret = unsafe { libc::recvmsg(sock.as_raw_fd(), &mut hdr as *mut _, 0) };\n    if ret < 0 {\n        return Err(io::Error::last_os_error());\n    }\n\n    msg.addr = sock_addr.as_socket().expect(\"SockAddr.as_socket\");\n    msg.data_len = ret as usize;\n\n    Ok(())\n}\n\npub fn batch_recvmsg<S: AsRawFd>(sock: &S, msgs: &mut [BatchRecvMessage<'_>]) -> io::Result<usize> {\n    if msgs.is_empty() {\n        return Ok(0);\n    }\n\n    if !SUPPORT_BATCH_SEND_RECV_MSG.load(Ordering::Relaxed) {\n        recvmsg_fallback(sock, &mut msgs[0])?;\n        return Ok(1);\n    }\n\n    let mut vec_msg_name = Vec::with_capacity(msgs.len());\n    let mut vec_msg_hdr = Vec::with_capacity(msgs.len());\n\n    for msg in msgs.iter_mut() {\n        let mut hdr: libc::mmsghdr = unsafe { mem::zeroed() };\n\n        let addr_storage = SockAddrStorage::zeroed();\n        let addr_len = addr_storage.size_of() as libc::socklen_t;\n\n        vec_msg_name.push(unsafe { SockAddr::new(addr_storage, addr_len) });\n        let sock_addr = vec_msg_name.last_mut().unwrap();\n        hdr.msg_hdr.msg_name = sock_addr.as_ptr() as *mut _;\n        hdr.msg_hdr.msg_namelen = sock_addr.len() as _;\n\n        hdr.msg_hdr.msg_iov = msg.data.as_ptr() as *mut _;\n        hdr.msg_hdr.msg_iovlen = msg.data.len() as _;\n\n        vec_msg_hdr.push(hdr);\n    }\n\n    let ret = unsafe {\n        libc::recvmmsg(\n            sock.as_raw_fd(),\n            vec_msg_hdr.as_mut_ptr(),\n            vec_msg_hdr.len() as _,\n            0,\n            ptr::null(),\n        )\n    };\n    if ret < 0 {\n        let err = io::Error::last_os_error();\n        if let Some(libc::ENOSYS) = err.raw_os_error() {\n            debug!(\"recvmmsg is not supported, fallback to recvmsg, error: {:?}\", err);\n            SUPPORT_BATCH_SEND_RECV_MSG.store(false, Ordering::Relaxed);\n\n            recvmsg_fallback(sock, &mut msgs[0])?;\n            return Ok(1);\n        }\n        return Err(err);\n    }\n\n    for idx in 0..ret as usize {\n        let msg = &mut msgs[idx];\n        let hdr = &vec_msg_hdr[idx];\n        let name = &vec_msg_name[idx];\n        msg.addr = name.as_socket().expect(\"SockAddr.as_socket\");\n        msg.data_len = hdr.msg_len as usize;\n    }\n\n    Ok(ret as usize)\n}\n\nfn sendmsg_fallback<S: AsRawFd>(sock: &S, msg: &mut BatchSendMessage<'_>) -> io::Result<()> {\n    let mut hdr: libc::msghdr = unsafe { mem::zeroed() };\n\n    let sock_addr = msg.addr.map(SockAddr::from);\n    if let Some(ref sa) = sock_addr {\n        hdr.msg_name = sa.as_ptr() as *mut _;\n        hdr.msg_namelen = sa.len() as _;\n    }\n\n    hdr.msg_iov = msg.data.as_ptr() as *mut _;\n    hdr.msg_iovlen = msg.data.len() as _;\n\n    let ret = unsafe { libc::sendmsg(sock.as_raw_fd(), &hdr as *const _, 0) };\n    if ret < 0 {\n        return Err(io::Error::last_os_error());\n    }\n    msg.data_len = ret as usize;\n\n    Ok(())\n}\n\npub fn batch_sendmsg<S: AsRawFd>(sock: &S, msgs: &mut [BatchSendMessage<'_>]) -> io::Result<usize> {\n    if msgs.is_empty() {\n        return Ok(0);\n    }\n\n    if !SUPPORT_BATCH_SEND_RECV_MSG.load(Ordering::Relaxed) {\n        sendmsg_fallback(sock, &mut msgs[0])?;\n        return Ok(1);\n    }\n\n    let mut vec_msg_name = Vec::with_capacity(msgs.len());\n    let mut vec_msg_hdr = Vec::with_capacity(msgs.len());\n\n    for msg in msgs.iter_mut() {\n        let mut hdr: libc::mmsghdr = unsafe { mem::zeroed() };\n\n        if let Some(addr) = msg.addr {\n            vec_msg_name.push(SockAddr::from(addr));\n            let sock_addr = vec_msg_name.last_mut().unwrap();\n            hdr.msg_hdr.msg_name = sock_addr.as_ptr() as *mut _;\n            hdr.msg_hdr.msg_namelen = sock_addr.len() as _;\n        }\n\n        hdr.msg_hdr.msg_iov = msg.data.as_ptr() as *mut _;\n        hdr.msg_hdr.msg_iovlen = msg.data.len() as _;\n\n        vec_msg_hdr.push(hdr);\n    }\n\n    let ret = unsafe { libc::sendmmsg(sock.as_raw_fd(), vec_msg_hdr.as_mut_ptr(), vec_msg_hdr.len() as _, 0) };\n    if ret < 0 {\n        let err = io::Error::last_os_error();\n        if let Some(libc::ENOSYS) = err.raw_os_error() {\n            debug!(\"sendmmsg is not supported, fallback to sendmsg, error: {:?}\", err);\n            SUPPORT_BATCH_SEND_RECV_MSG.store(false, Ordering::Relaxed);\n\n            sendmsg_fallback(sock, &mut msgs[0])?;\n            return Ok(1);\n        }\n        return Err(err);\n    }\n\n    for idx in 0..ret as usize {\n        let msg = &mut msgs[idx];\n        let hdr = &vec_msg_hdr[idx];\n        msg.data_len = hdr.msg_len as usize;\n    }\n\n    Ok(ret as usize)\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/net/sys/unix/bsd/macos.rs",
    "content": "use std::{\n    cell::RefCell,\n    collections::HashMap,\n    io::{self, ErrorKind},\n    mem,\n    net::{Ipv4Addr, Ipv6Addr, SocketAddr, TcpStream as StdTcpStream},\n    os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd},\n    pin::Pin,\n    ptr,\n    sync::atomic::{AtomicBool, Ordering},\n    task::{self, Poll},\n    time::{Duration, Instant},\n};\n\nuse log::{debug, error, warn};\nuse pin_project::pin_project;\nuse socket2::{Domain, Protocol, SockAddr, SockAddrStorage, Socket, Type};\nuse tokio::{\n    io::{AsyncRead, AsyncWrite, Interest, ReadBuf},\n    net::{TcpSocket, TcpStream as TokioTcpStream, UdpSocket},\n};\nuse tokio_tfo::TfoStream;\n\nuse crate::net::{\n    AcceptOpts, AddrFamily, ConnectOpts,\n    sys::{set_common_sockopt_after_connect, set_common_sockopt_for_connect, socket_bind_dual_stack},\n    udp::{BatchRecvMessage, BatchSendMessage},\n};\n\n/// A `TcpStream` that supports TFO (TCP Fast Open)\n#[pin_project(project = TcpStreamProj)]\npub enum TcpStream {\n    Standard(#[pin] TokioTcpStream),\n    FastOpen(#[pin] TfoStream),\n}\n\nimpl TcpStream {\n    pub async fn connect(addr: SocketAddr, opts: &ConnectOpts) -> io::Result<TcpStream> {\n        if opts.tcp.mptcp {\n            return TcpStream::connect_mptcp(addr, opts).await;\n        }\n\n        let socket = match addr {\n            SocketAddr::V4(..) => TcpSocket::new_v4()?,\n            SocketAddr::V6(..) => TcpSocket::new_v6()?,\n        };\n\n        TcpStream::connect_with_socket(socket, addr, opts).await\n    }\n\n    async fn connect_mptcp(addr: SocketAddr, opts: &ConnectOpts) -> io::Result<TcpStream> {\n        // https://opensource.apple.com/source/xnu/xnu-4570.41.2/bsd/sys/socket.h.auto.html\n        const AF_MULTIPATH: libc::c_int = 39;\n\n        let socket = unsafe {\n            let fd = libc::socket(AF_MULTIPATH, libc::SOCK_STREAM, libc::IPPROTO_TCP);\n            if fd < 0 {\n                let err = io::Error::last_os_error();\n                return Err(err);\n            }\n            let socket = Socket::from_raw_fd(fd);\n            socket.set_nonblocking(true)?;\n            TcpSocket::from_raw_fd(socket.into_raw_fd())\n        };\n\n        TcpStream::connect_with_socket(socket, addr, opts).await\n    }\n\n    #[inline]\n    async fn connect_with_socket(socket: TcpSocket, addr: SocketAddr, opts: &ConnectOpts) -> io::Result<TcpStream> {\n        // Binds to a specific network interface (device)\n        if let Some(ref iface) = opts.bind_interface {\n            set_ip_bound_if(&socket, &addr, iface)?;\n        }\n\n        set_common_sockopt_for_connect(addr, &socket, opts)?;\n\n        if !opts.tcp.fastopen {\n            // If TFO is not enabled, it just works like a normal TcpStream\n            //\n            // But for Multipath-TCP, we must use connectx\n            // http://blog.multipath-tcp.org/blog/html/2018/12/17/multipath_tcp_apis.html\n            let stream = if opts.tcp.mptcp {\n                let stream = unsafe {\n                    let raddr = SockAddr::from(addr);\n\n                    let mut endpoints: libc::sa_endpoints_t = mem::zeroed();\n                    endpoints.sae_dstaddr = raddr.as_ptr() as *const _;\n                    endpoints.sae_dstaddrlen = raddr.len();\n\n                    let ret = libc::connectx(\n                        socket.as_raw_fd(),\n                        &endpoints as *const _,\n                        libc::SAE_ASSOCID_ANY,\n                        0,\n                        ptr::null(),\n                        0,\n                        ptr::null_mut(),\n                        ptr::null_mut(),\n                    );\n\n                    if ret != 0 {\n                        let err = io::Error::last_os_error();\n                        if err.raw_os_error() != Some(libc::EINPROGRESS) {\n                            return Err(err);\n                        }\n                    }\n\n                    let fd = socket.into_raw_fd();\n                    TokioTcpStream::from_std(StdTcpStream::from_raw_fd(fd))?\n                };\n\n                stream.ready(Interest::WRITABLE).await?;\n\n                stream.take_error()?;\n\n                stream\n            } else {\n                socket.connect(addr).await?\n            };\n\n            set_common_sockopt_after_connect(&stream, opts)?;\n            return Ok(TcpStream::Standard(stream));\n        }\n\n        let stream = TfoStream::connect_with_socket(socket, addr).await?;\n        set_common_sockopt_after_connect(&stream, opts)?;\n\n        Ok(TcpStream::FastOpen(stream))\n    }\n\n    pub fn local_addr(&self) -> io::Result<SocketAddr> {\n        match *self {\n            TcpStream::Standard(ref s) => s.local_addr(),\n            TcpStream::FastOpen(ref s) => s.local_addr(),\n        }\n    }\n\n    pub fn peer_addr(&self) -> io::Result<SocketAddr> {\n        match *self {\n            TcpStream::Standard(ref s) => s.peer_addr(),\n            TcpStream::FastOpen(ref s) => s.peer_addr(),\n        }\n    }\n\n    pub fn nodelay(&self) -> io::Result<bool> {\n        match *self {\n            TcpStream::Standard(ref s) => s.nodelay(),\n            TcpStream::FastOpen(ref s) => s.nodelay(),\n        }\n    }\n\n    pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {\n        match *self {\n            TcpStream::Standard(ref s) => s.set_nodelay(nodelay),\n            TcpStream::FastOpen(ref s) => s.set_nodelay(nodelay),\n        }\n    }\n}\n\nimpl AsRawFd for TcpStream {\n    fn as_raw_fd(&self) -> RawFd {\n        match *self {\n            TcpStream::Standard(ref s) => s.as_raw_fd(),\n            TcpStream::FastOpen(ref s) => s.as_raw_fd(),\n        }\n    }\n}\n\nimpl AsyncRead for TcpStream {\n    fn poll_read(self: Pin<&mut Self>, cx: &mut task::Context<'_>, buf: &mut ReadBuf<'_>) -> Poll<io::Result<()>> {\n        match self.project() {\n            TcpStreamProj::Standard(s) => s.poll_read(cx, buf),\n            TcpStreamProj::FastOpen(s) => s.poll_read(cx, buf),\n        }\n    }\n}\n\nimpl AsyncWrite for TcpStream {\n    fn poll_write(self: Pin<&mut Self>, cx: &mut task::Context<'_>, buf: &[u8]) -> Poll<io::Result<usize>> {\n        match self.project() {\n            TcpStreamProj::Standard(s) => s.poll_write(cx, buf),\n            TcpStreamProj::FastOpen(s) => s.poll_write(cx, buf),\n        }\n    }\n\n    fn poll_flush(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<io::Result<()>> {\n        match self.project() {\n            TcpStreamProj::Standard(s) => s.poll_flush(cx),\n            TcpStreamProj::FastOpen(s) => s.poll_flush(cx),\n        }\n    }\n\n    fn poll_shutdown(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<io::Result<()>> {\n        match self.project() {\n            TcpStreamProj::Standard(s) => s.poll_shutdown(cx),\n            TcpStreamProj::FastOpen(s) => s.poll_shutdown(cx),\n        }\n    }\n}\n\n/// Enable `TCP_FASTOPEN`\n///\n/// `TCP_FASTOPEN` was supported since\n/// macosx(10.11), ios(9.0), tvos(9.0), watchos(2.0)\npub fn set_tcp_fastopen<S: AsRawFd>(socket: &S) -> io::Result<()> {\n    let enable: libc::c_int = 1;\n\n    unsafe {\n        let ret = libc::setsockopt(\n            socket.as_raw_fd(),\n            libc::IPPROTO_TCP,\n            libc::TCP_FASTOPEN,\n            &enable as *const _ as *const libc::c_void,\n            mem::size_of_val(&enable) as libc::socklen_t,\n        );\n\n        if ret != 0 {\n            let err = io::Error::last_os_error();\n            error!(\"set TCP_FASTOPEN error: {}\", err);\n            return Err(err);\n        }\n    }\n\n    Ok(())\n}\n\n/// Create a TCP socket for listening\npub async fn create_inbound_tcp_socket(bind_addr: &SocketAddr, _accept_opts: &AcceptOpts) -> io::Result<TcpSocket> {\n    match bind_addr {\n        SocketAddr::V4(..) => TcpSocket::new_v4(),\n        SocketAddr::V6(..) => TcpSocket::new_v6(),\n    }\n}\n\nfn find_interface_index_cached(iface: &str) -> io::Result<u32> {\n    const INDEX_EXPIRE_DURATION: Duration = Duration::from_secs(5);\n\n    thread_local! {\n        static INTERFACE_INDEX_CACHE: RefCell<HashMap<String, (u32, Instant)>> =\n            RefCell::new(HashMap::new());\n    }\n\n    let cache_index = INTERFACE_INDEX_CACHE.with(|cache| cache.borrow().get(iface).cloned());\n    if let Some((idx, insert_time)) = cache_index {\n        // short-path, cache hit for most cases\n        let now = Instant::now();\n        if now - insert_time < INDEX_EXPIRE_DURATION {\n            return Ok(idx);\n        }\n    }\n\n    let index = unsafe {\n        let mut ciface = [0u8; libc::IFNAMSIZ];\n        if iface.len() >= ciface.len() {\n            return Err(ErrorKind::InvalidInput.into());\n        }\n\n        let iface_bytes = iface.as_bytes();\n        ptr::copy_nonoverlapping(iface_bytes.as_ptr(), ciface.as_mut_ptr(), iface_bytes.len());\n\n        libc::if_nametoindex(ciface.as_ptr() as *const libc::c_char)\n    };\n\n    if index == 0 {\n        let err = io::Error::last_os_error();\n        error!(\"if_nametoindex ifname: {} error: {}\", iface, err);\n        return Err(err);\n    }\n\n    INTERFACE_INDEX_CACHE.with(|cache| {\n        cache.borrow_mut().insert(iface.to_owned(), (index, Instant::now()));\n    });\n\n    Ok(index)\n}\n\nfn set_ip_bound_if<S: AsRawFd>(socket: &S, addr: &SocketAddr, iface: &str) -> io::Result<()> {\n    const IP_BOUND_IF: libc::c_int = 25; // bsd/netinet/in.h\n    const IPV6_BOUND_IF: libc::c_int = 125; // bsd/netinet6/in6.h\n\n    unsafe {\n        let index = find_interface_index_cached(iface)?;\n\n        let ret = match addr {\n            SocketAddr::V4(..) => libc::setsockopt(\n                socket.as_raw_fd(),\n                libc::IPPROTO_IP,\n                IP_BOUND_IF,\n                &index as *const _ as *const _,\n                mem::size_of_val(&index) as libc::socklen_t,\n            ),\n            SocketAddr::V6(..) => libc::setsockopt(\n                socket.as_raw_fd(),\n                libc::IPPROTO_IPV6,\n                IPV6_BOUND_IF,\n                &index as *const _ as *const _,\n                mem::size_of_val(&index) as libc::socklen_t,\n            ),\n        };\n\n        if ret < 0 {\n            let err = io::Error::last_os_error();\n            error!(\n                \"set IF_BOUND_IF/IPV6_BOUND_IF ifname: {} ifindex: {} error: {}\",\n                iface, index, err\n            );\n            return Err(err);\n        }\n    }\n\n    Ok(())\n}\n\n/// Disable IP fragmentation\n#[inline]\npub fn set_disable_ip_fragmentation<S: AsRawFd>(af: AddrFamily, socket: &S) -> io::Result<()> {\n    unsafe {\n        match af {\n            AddrFamily::Ipv4 => {\n                let enable: i32 = 1;\n                let ret = libc::setsockopt(\n                    socket.as_raw_fd(),\n                    libc::IPPROTO_IP,\n                    libc::IP_DONTFRAG,\n                    &enable as *const _ as *const _,\n                    mem::size_of_val(&enable) as libc::socklen_t,\n                );\n\n                if ret < 0 {\n                    return Err(io::Error::last_os_error());\n                }\n            }\n            AddrFamily::Ipv6 => {\n                let enable: i32 = 1;\n                let ret = libc::setsockopt(\n                    socket.as_raw_fd(),\n                    libc::IPPROTO_IPV6,\n                    libc::IPV6_DONTFRAG,\n                    &enable as *const _ as *const _,\n                    mem::size_of_val(&enable) as libc::socklen_t,\n                );\n\n                if ret < 0 {\n                    return Err(io::Error::last_os_error());\n                }\n            }\n        }\n    }\n\n    Ok(())\n}\n\n/// Create a `UdpSocket` with specific address family\n#[inline]\npub async fn create_outbound_udp_socket(af: AddrFamily, config: &ConnectOpts) -> io::Result<UdpSocket> {\n    let bind_addr = match (af, config.bind_local_addr) {\n        (AddrFamily::Ipv4, Some(SocketAddr::V4(addr))) => addr.into(),\n        (AddrFamily::Ipv4, Some(SocketAddr::V6(addr))) => {\n            // Map IPv6 bind_local_addr to IPv4 if AF is IPv4\n            match addr.ip().to_ipv4_mapped() {\n                Some(addr) => SocketAddr::new(addr.into(), 0),\n                None => return Err(io::Error::new(ErrorKind::InvalidInput, \"Invalid IPv6 address\")),\n            }\n        }\n        (AddrFamily::Ipv6, Some(SocketAddr::V6(addr))) => addr.into(),\n        (AddrFamily::Ipv6, Some(SocketAddr::V4(addr))) => {\n            // Map IPv4 bind_local_addr to IPv6 if AF is IPv6\n            SocketAddr::new(addr.ip().to_ipv6_mapped().into(), 0)\n        }\n        (AddrFamily::Ipv4, ..) => SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), 0),\n        (AddrFamily::Ipv6, ..) => SocketAddr::new(Ipv6Addr::UNSPECIFIED.into(), 0),\n    };\n\n    bind_outbound_udp_socket(&bind_addr, config).await\n}\n\n/// Create a `UdpSocket` binded to `bind_addr`\npub async fn bind_outbound_udp_socket(bind_addr: &SocketAddr, config: &ConnectOpts) -> io::Result<UdpSocket> {\n    let af = AddrFamily::from(bind_addr);\n\n    let socket = if af != AddrFamily::Ipv6 {\n        UdpSocket::bind(bind_addr).await?\n    } else {\n        let socket = Socket::new(Domain::for_address(*bind_addr), Type::DGRAM, Some(Protocol::UDP))?;\n        socket_bind_dual_stack(&socket, bind_addr, false)?;\n\n        // UdpSocket::from_std requires socket to be non-blocked\n        socket.set_nonblocking(true)?;\n        UdpSocket::from_std(socket.into())?\n    };\n\n    if !config.udp.allow_fragmentation\n        && let Err(err) = set_disable_ip_fragmentation(af, &socket)\n    {\n        warn!(\"failed to disable IP fragmentation, error: {}\", err);\n    }\n\n    // Set IP_BOUND_IF for BSD-like\n    if let Some(ref iface) = config.bind_interface {\n        set_ip_bound_if(&socket, bind_addr, iface)?;\n    }\n\n    Ok(socket)\n}\n\n/// https://github.com/apple/darwin-xnu/blob/main/bsd/sys/socket.h\n#[repr(C)]\n#[allow(non_camel_case_types)]\nstruct msghdr_x {\n    msg_name: *mut libc::c_void,     //< optional address\n    msg_namelen: libc::socklen_t,    //< size of address\n    msg_iov: *mut libc::iovec,       //< scatter/gather array\n    msg_iovlen: libc::c_int,         //< # elements in msg_iov\n    msg_control: *mut libc::c_void,  //< ancillary data, see below\n    msg_controllen: libc::socklen_t, //< ancillary data buffer len\n    msg_flags: libc::c_int,          //< flags on received message\n    msg_datalen: libc::size_t,       //< byte length of buffer in msg_iov\n}\n\nunsafe extern \"C\" {\n    fn recvmsg_x(s: libc::c_int, msgp: *const msghdr_x, cnt: libc::c_uint, flags: libc::c_int) -> libc::ssize_t;\n    fn sendmsg_x(s: libc::c_int, msgp: *const msghdr_x, cnt: libc::c_uint, flags: libc::c_int) -> libc::ssize_t;\n}\n\nstatic SUPPORT_BATCH_SEND_RECV_MSG: AtomicBool = AtomicBool::new(true);\n\nfn recvmsg_fallback<S: AsRawFd>(sock: &S, msg: &mut BatchRecvMessage<'_>) -> io::Result<()> {\n    let mut hdr: libc::msghdr = unsafe { mem::zeroed() };\n\n    let addr_storage = SockAddrStorage::zeroed();\n    let addr_len = addr_storage.size_of() as libc::socklen_t;\n\n    let sock_addr = unsafe { SockAddr::new(addr_storage, addr_len) };\n    hdr.msg_name = sock_addr.as_ptr() as *mut _;\n    hdr.msg_namelen = sock_addr.len() as _;\n\n    hdr.msg_iov = msg.data.as_ptr() as *mut _;\n    hdr.msg_iovlen = msg.data.len() as _;\n\n    let ret = unsafe { libc::recvmsg(sock.as_raw_fd(), &mut hdr as *mut _, 0) };\n    if ret < 0 {\n        return Err(io::Error::last_os_error());\n    }\n\n    msg.addr = sock_addr.as_socket().expect(\"SockAddr.as_socket\");\n    msg.data_len = ret as usize;\n\n    Ok(())\n}\n\npub fn batch_recvmsg<S: AsRawFd>(sock: &S, msgs: &mut [BatchRecvMessage<'_>]) -> io::Result<usize> {\n    if msgs.is_empty() {\n        return Ok(0);\n    }\n\n    if !SUPPORT_BATCH_SEND_RECV_MSG.load(Ordering::Relaxed) {\n        recvmsg_fallback(sock, &mut msgs[0])?;\n        return Ok(1);\n    }\n\n    let mut vec_msg_name = Vec::with_capacity(msgs.len());\n    let mut vec_msg_hdr = Vec::with_capacity(msgs.len());\n\n    for msg in msgs.iter_mut() {\n        let mut hdr: msghdr_x = unsafe { mem::zeroed() };\n\n        let addr_storage = SockAddrStorage::zeroed();\n        let addr_len = addr_storage.size_of() as libc::socklen_t;\n\n        vec_msg_name.push(unsafe { SockAddr::new(addr_storage, addr_len) });\n        let sock_addr = vec_msg_name.last_mut().unwrap();\n        hdr.msg_name = sock_addr.as_ptr() as *mut _;\n        hdr.msg_namelen = sock_addr.len() as _;\n\n        hdr.msg_iov = msg.data.as_ptr() as *mut _;\n        hdr.msg_iovlen = msg.data.len() as _;\n\n        vec_msg_hdr.push(hdr);\n    }\n\n    let ret = unsafe { recvmsg_x(sock.as_raw_fd(), vec_msg_hdr.as_ptr(), vec_msg_hdr.len() as _, 0) };\n    if ret < 0 {\n        let err = io::Error::last_os_error();\n        if let Some(libc::ENOSYS) = err.raw_os_error() {\n            debug!(\"recvmsg_x is not supported, fallback to recvmsg, error: {:?}\", err);\n            SUPPORT_BATCH_SEND_RECV_MSG.store(false, Ordering::Relaxed);\n\n            recvmsg_fallback(sock, &mut msgs[0])?;\n            return Ok(1);\n        }\n        return Err(err);\n    }\n\n    for idx in 0..ret as usize {\n        let msg = &mut msgs[idx];\n        let hdr = &vec_msg_hdr[idx];\n        let name = &vec_msg_name[idx];\n        msg.addr = name.as_socket().expect(\"SockAddr.as_socket\");\n        msg.data_len = hdr.msg_datalen;\n    }\n\n    Ok(ret as usize)\n}\n\nfn sendmsg_fallback<S: AsRawFd>(sock: &S, msg: &mut BatchSendMessage<'_>) -> io::Result<()> {\n    let mut hdr: libc::msghdr = unsafe { mem::zeroed() };\n\n    let sock_addr = msg.addr.map(SockAddr::from);\n    if let Some(ref sa) = sock_addr {\n        hdr.msg_name = sa.as_ptr() as *mut _;\n        hdr.msg_namelen = sa.len() as _;\n    }\n\n    hdr.msg_iov = msg.data.as_ptr() as *mut _;\n    hdr.msg_iovlen = msg.data.len() as _;\n\n    let ret = unsafe { libc::sendmsg(sock.as_raw_fd(), &hdr as *const _, 0) };\n    if ret < 0 {\n        return Err(io::Error::last_os_error());\n    }\n    msg.data_len = ret as usize;\n\n    Ok(())\n}\n\npub fn batch_sendmsg<S: AsRawFd>(sock: &S, msgs: &mut [BatchSendMessage<'_>]) -> io::Result<usize> {\n    if msgs.is_empty() {\n        return Ok(0);\n    }\n\n    if !SUPPORT_BATCH_SEND_RECV_MSG.load(Ordering::Relaxed) {\n        sendmsg_fallback(sock, &mut msgs[0])?;\n        return Ok(1);\n    }\n\n    let mut vec_msg_name = Vec::with_capacity(msgs.len());\n    let mut vec_msg_hdr = Vec::with_capacity(msgs.len());\n\n    for msg in msgs.iter_mut() {\n        let mut hdr: msghdr_x = unsafe { mem::zeroed() };\n\n        if let Some(addr) = msg.addr {\n            vec_msg_name.push(SockAddr::from(addr));\n            let sock_addr = vec_msg_name.last_mut().unwrap();\n            hdr.msg_name = sock_addr.as_ptr() as *mut _;\n            hdr.msg_namelen = sock_addr.len() as _;\n        }\n\n        hdr.msg_iov = msg.data.as_ptr() as *mut _;\n        hdr.msg_iovlen = msg.data.len() as _;\n\n        vec_msg_hdr.push(hdr);\n    }\n\n    let ret = unsafe { sendmsg_x(sock.as_raw_fd(), vec_msg_hdr.as_ptr(), vec_msg_hdr.len() as _, 0) };\n    if ret < 0 {\n        let err = io::Error::last_os_error();\n        if let Some(libc::ENOSYS) = err.raw_os_error() {\n            debug!(\"sendmsg_x is not supported, fallback to sendmsg, error: {:?}\", err);\n            SUPPORT_BATCH_SEND_RECV_MSG.store(false, Ordering::Relaxed);\n\n            sendmsg_fallback(sock, &mut msgs[0])?;\n            return Ok(1);\n        }\n        return Err(err);\n    }\n\n    for idx in 0..ret as usize {\n        let msg = &mut msgs[idx];\n        let hdr = &vec_msg_hdr[idx];\n        msg.data_len = hdr.msg_datalen;\n    }\n\n    Ok(ret as usize)\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/net/sys/unix/bsd/mod.rs",
    "content": "use cfg_if::cfg_if;\n\ncfg_if! {\n    if #[cfg(target_os = \"freebsd\")] {\n        mod freebsd;\n        pub use self::freebsd::*;\n    } else if #[cfg(any(target_os = \"macos\", target_os = \"ios\", target_os = \"watchos\", target_os = \"tvos\"))] {\n        mod macos;\n        pub use self::macos::*;\n    } else {\n        mod others;\n        pub use self::others::*;\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/net/sys/unix/bsd/others.rs",
    "content": "include!(\"../others.rs\");\n"
  },
  {
    "path": "crates/shadowsocks/src/net/sys/unix/linux/mod.rs",
    "content": "use std::{\n    io::{self, ErrorKind},\n    mem,\n    net::{Ipv4Addr, Ipv6Addr, SocketAddr},\n    os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd},\n    pin::Pin,\n    ptr,\n    sync::atomic::{AtomicBool, Ordering},\n    task::{self, Poll},\n};\n\nuse log::{debug, error, warn};\nuse pin_project::pin_project;\nuse socket2::{Domain, Protocol, SockAddr, SockAddrStorage, Socket, Type};\nuse tokio::{\n    io::{AsyncRead, AsyncWrite, ReadBuf},\n    net::{TcpSocket, TcpStream as TokioTcpStream, UdpSocket},\n};\nuse tokio_tfo::TfoStream;\n\nuse crate::net::{\n    AcceptOpts, AddrFamily, ConnectOpts,\n    sys::{set_common_sockopt_after_connect, set_common_sockopt_for_connect, socket_bind_dual_stack},\n    udp::{BatchRecvMessage, BatchSendMessage},\n};\n\n/// A `TcpStream` that supports TFO (TCP Fast Open)\n#[pin_project(project = TcpStreamProj)]\npub enum TcpStream {\n    Standard(#[pin] TokioTcpStream),\n    FastOpen(#[pin] TfoStream),\n}\n\nimpl TcpStream {\n    pub async fn connect(addr: SocketAddr, opts: &ConnectOpts) -> io::Result<Self> {\n        if opts.tcp.mptcp {\n            return Self::connect_mptcp(addr, opts).await;\n        }\n\n        let socket = match addr {\n            SocketAddr::V4(..) => TcpSocket::new_v4()?,\n            SocketAddr::V6(..) => TcpSocket::new_v6()?,\n        };\n\n        Self::connect_with_socket(socket, addr, opts).await\n    }\n\n    async fn connect_mptcp(addr: SocketAddr, opts: &ConnectOpts) -> io::Result<Self> {\n        let socket = create_mptcp_socket(&addr)?;\n        Self::connect_with_socket(socket, addr, opts).await\n    }\n\n    async fn connect_with_socket(socket: TcpSocket, addr: SocketAddr, opts: &ConnectOpts) -> io::Result<Self> {\n        // Any traffic to localhost should not be protected\n        // This is a workaround for VPNService\n        #[cfg(target_os = \"android\")]\n        if !addr.ip().is_loopback() {\n            android::vpn_protect(&socket, opts).await?;\n        }\n\n        // Set SO_MARK for mark-based routing on Linux (since 2.6.25)\n        // NOTE: This will require CAP_NET_ADMIN capability (root in most cases)\n        if let Some(mark) = opts.fwmark {\n            let ret = unsafe {\n                libc::setsockopt(\n                    socket.as_raw_fd(),\n                    libc::SOL_SOCKET,\n                    libc::SO_MARK,\n                    &mark as *const _ as *const _,\n                    mem::size_of_val(&mark) as libc::socklen_t,\n                )\n            };\n            if ret != 0 {\n                let err = io::Error::last_os_error();\n                error!(\"set SO_MARK error: {}\", err);\n                return Err(err);\n            }\n        }\n\n        // Set SO_BINDTODEVICE for binding to a specific interface\n        if let Some(ref iface) = opts.bind_interface {\n            set_bindtodevice(&socket, iface)?;\n        }\n\n        set_common_sockopt_for_connect(addr, &socket, opts)?;\n\n        if !opts.tcp.fastopen {\n            // If TFO is not enabled, it just works like a normal TcpStream\n            let stream = socket.connect(addr).await?;\n            set_common_sockopt_after_connect(&stream, opts)?;\n\n            return Ok(Self::Standard(stream));\n        }\n\n        let stream = TfoStream::connect_with_socket(socket, addr).await?;\n        set_common_sockopt_after_connect(&stream, opts)?;\n\n        Ok(Self::FastOpen(stream))\n    }\n\n    pub fn local_addr(&self) -> io::Result<SocketAddr> {\n        match *self {\n            Self::Standard(ref s) => s.local_addr(),\n            Self::FastOpen(ref s) => s.local_addr(),\n        }\n    }\n\n    pub fn peer_addr(&self) -> io::Result<SocketAddr> {\n        match *self {\n            Self::Standard(ref s) => s.peer_addr(),\n            Self::FastOpen(ref s) => s.peer_addr(),\n        }\n    }\n\n    pub fn nodelay(&self) -> io::Result<bool> {\n        match *self {\n            Self::Standard(ref s) => s.nodelay(),\n            Self::FastOpen(ref s) => s.nodelay(),\n        }\n    }\n\n    pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {\n        match *self {\n            Self::Standard(ref s) => s.set_nodelay(nodelay),\n            Self::FastOpen(ref s) => s.set_nodelay(nodelay),\n        }\n    }\n}\n\nimpl AsRawFd for TcpStream {\n    fn as_raw_fd(&self) -> RawFd {\n        match *self {\n            Self::Standard(ref s) => s.as_raw_fd(),\n            Self::FastOpen(ref s) => s.as_raw_fd(),\n        }\n    }\n}\n\nimpl AsyncRead for TcpStream {\n    fn poll_read(self: Pin<&mut Self>, cx: &mut task::Context<'_>, buf: &mut ReadBuf<'_>) -> Poll<io::Result<()>> {\n        match self.project() {\n            TcpStreamProj::Standard(s) => s.poll_read(cx, buf),\n            TcpStreamProj::FastOpen(s) => s.poll_read(cx, buf),\n        }\n    }\n}\n\nimpl AsyncWrite for TcpStream {\n    fn poll_write(self: Pin<&mut Self>, cx: &mut task::Context<'_>, buf: &[u8]) -> Poll<io::Result<usize>> {\n        match self.project() {\n            TcpStreamProj::Standard(s) => s.poll_write(cx, buf),\n            TcpStreamProj::FastOpen(s) => s.poll_write(cx, buf),\n        }\n    }\n\n    fn poll_flush(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<io::Result<()>> {\n        match self.project() {\n            TcpStreamProj::Standard(s) => s.poll_flush(cx),\n            TcpStreamProj::FastOpen(s) => s.poll_flush(cx),\n        }\n    }\n\n    fn poll_shutdown(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<io::Result<()>> {\n        match self.project() {\n            TcpStreamProj::Standard(s) => s.poll_shutdown(cx),\n            TcpStreamProj::FastOpen(s) => s.poll_shutdown(cx),\n        }\n    }\n}\n\n/// Enable `TCP_FASTOPEN`\n///\n/// `TCP_FASTOPEN` was supported since Linux 3.7\npub fn set_tcp_fastopen<S: AsRawFd>(socket: &S) -> io::Result<()> {\n    // https://lwn.net/Articles/508865/\n    //\n    // The option value, qlen, specifies this server's limit on the size of the queue of TFO requests that have\n    // not yet completed the three-way handshake (see the remarks on prevention of resource-exhaustion attacks above).\n    //\n    // It was recommended to be `5` in this document.\n    //\n    // But since mio's TcpListener sets backlogs to 1024, it would be nice to have 1024 slots for handshaking TFO requests.\n    let queue: libc::c_int = 1024;\n\n    unsafe {\n        let ret = libc::setsockopt(\n            socket.as_raw_fd(),\n            libc::IPPROTO_TCP,\n            libc::TCP_FASTOPEN,\n            &queue as *const _ as *const libc::c_void,\n            mem::size_of_val(&queue) as libc::socklen_t,\n        );\n\n        if ret != 0 {\n            let err = io::Error::last_os_error();\n            error!(\"set TCP_FASTOPEN error: {}\", err);\n            return Err(err);\n        }\n    }\n\n    Ok(())\n}\n\nfn create_mptcp_socket(bind_addr: &SocketAddr) -> io::Result<TcpSocket> {\n    // https://www.kernel.org/doc/html/next/networking/mptcp.html\n\n    unsafe {\n        let family = match bind_addr {\n            SocketAddr::V4(..) => libc::AF_INET,\n            SocketAddr::V6(..) => libc::AF_INET6,\n        };\n        let fd = libc::socket(family, libc::SOCK_STREAM, libc::IPPROTO_MPTCP);\n        if fd < 0 {\n            let err = io::Error::last_os_error();\n            return Err(err);\n        }\n        let socket = Socket::from_raw_fd(fd);\n        socket.set_nonblocking(true)?;\n        Ok(TcpSocket::from_raw_fd(socket.into_raw_fd()))\n    }\n}\n\n/// Create a TCP socket for listening\npub async fn create_inbound_tcp_socket(bind_addr: &SocketAddr, accept_opts: &AcceptOpts) -> io::Result<TcpSocket> {\n    if accept_opts.tcp.mptcp {\n        create_mptcp_socket(bind_addr)\n    } else {\n        match bind_addr {\n            SocketAddr::V4(..) => TcpSocket::new_v4(),\n            SocketAddr::V6(..) => TcpSocket::new_v6(),\n        }\n    }\n}\n\n/// Disable IP fragmentation\n#[inline]\npub fn set_disable_ip_fragmentation<S: AsRawFd>(af: AddrFamily, socket: &S) -> io::Result<()> {\n    // For Linux, IP_MTU_DISCOVER should be enabled for both IPv4 and IPv6 sockets\n    // https://man7.org/linux/man-pages/man7/ip.7.html\n\n    unsafe {\n        let value: i32 = libc::IP_PMTUDISC_DO;\n        let ret = libc::setsockopt(\n            socket.as_raw_fd(),\n            libc::IPPROTO_IP,\n            libc::IP_MTU_DISCOVER,\n            &value as *const _ as *const _,\n            mem::size_of_val(&value) as libc::socklen_t,\n        );\n\n        if ret < 0 {\n            return Err(io::Error::last_os_error());\n        }\n\n        if af == AddrFamily::Ipv6 {\n            let value: i32 = libc::IP_PMTUDISC_DO;\n            let ret = libc::setsockopt(\n                socket.as_raw_fd(),\n                libc::IPPROTO_IPV6,\n                libc::IPV6_MTU_DISCOVER,\n                &value as *const _ as *const _,\n                mem::size_of_val(&value) as libc::socklen_t,\n            );\n\n            if ret < 0 {\n                return Err(io::Error::last_os_error());\n            }\n        }\n    }\n\n    Ok(())\n}\n\n/// Create a `UdpSocket` with specific address family\n#[inline]\npub async fn create_outbound_udp_socket(af: AddrFamily, config: &ConnectOpts) -> io::Result<UdpSocket> {\n    let bind_addr = match (af, config.bind_local_addr) {\n        (AddrFamily::Ipv4, Some(SocketAddr::V4(addr))) => addr.into(),\n        (AddrFamily::Ipv4, Some(SocketAddr::V6(addr))) => {\n            // Map IPv6 bind_local_addr to IPv4 if AF is IPv4\n            match addr.ip().to_ipv4_mapped() {\n                Some(addr) => SocketAddr::new(addr.into(), 0),\n                None => return Err(io::Error::new(ErrorKind::InvalidInput, \"Invalid IPv6 address\")),\n            }\n        }\n        (AddrFamily::Ipv6, Some(SocketAddr::V6(addr))) => addr.into(),\n        (AddrFamily::Ipv6, Some(SocketAddr::V4(addr))) => {\n            // Map IPv4 bind_local_addr to IPv6 if AF is IPv6\n            SocketAddr::new(addr.ip().to_ipv6_mapped().into(), 0)\n        }\n        (AddrFamily::Ipv4, ..) => SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), 0),\n        (AddrFamily::Ipv6, ..) => SocketAddr::new(Ipv6Addr::UNSPECIFIED.into(), 0),\n    };\n\n    bind_outbound_udp_socket(&bind_addr, config).await\n}\n\n/// Create a `UdpSocket` binded to `bind_addr`\npub async fn bind_outbound_udp_socket(bind_addr: &SocketAddr, config: &ConnectOpts) -> io::Result<UdpSocket> {\n    let af = AddrFamily::from(bind_addr);\n\n    let socket = if af != AddrFamily::Ipv6 {\n        UdpSocket::bind(bind_addr).await?\n    } else {\n        let socket = Socket::new(Domain::for_address(*bind_addr), Type::DGRAM, Some(Protocol::UDP))?;\n        socket_bind_dual_stack(&socket, bind_addr, false)?;\n\n        // UdpSocket::from_std requires socket to be non-blocked\n        socket.set_nonblocking(true)?;\n        UdpSocket::from_std(socket.into())?\n    };\n\n    if !config.udp.allow_fragmentation\n        && let Err(err) = set_disable_ip_fragmentation(af, &socket)\n    {\n        warn!(\"failed to disable IP fragmentation, error: {}\", err);\n    }\n\n    // Any traffic except localhost should be protected\n    // This is a workaround for VPNService\n    #[cfg(target_os = \"android\")]\n    android::vpn_protect(&socket, config).await?;\n\n    // Set SO_MARK for mark-based routing on Linux (since 2.6.25)\n    // NOTE: This will require CAP_NET_ADMIN capability (root in most cases)\n    if let Some(mark) = config.fwmark {\n        let ret = unsafe {\n            libc::setsockopt(\n                socket.as_raw_fd(),\n                libc::SOL_SOCKET,\n                libc::SO_MARK,\n                &mark as *const _ as *const _,\n                mem::size_of_val(&mark) as libc::socklen_t,\n            )\n        };\n        if ret != 0 {\n            let err = io::Error::last_os_error();\n            error!(\"set SO_MARK error: {}\", err);\n            return Err(err);\n        }\n    }\n\n    // Set SO_BINDTODEVICE for binding to a specific interface\n    if let Some(ref iface) = config.bind_interface {\n        set_bindtodevice(&socket, iface)?;\n    }\n\n    Ok(socket)\n}\n\nfn set_bindtodevice<S: AsRawFd>(socket: &S, iface: &str) -> io::Result<()> {\n    let iface_bytes = iface.as_bytes();\n\n    unsafe {\n        let ret = libc::setsockopt(\n            socket.as_raw_fd(),\n            libc::SOL_SOCKET,\n            libc::SO_BINDTODEVICE,\n            iface_bytes.as_ptr() as *const _ as *const libc::c_void,\n            iface_bytes.len() as libc::socklen_t,\n        );\n\n        if ret != 0 {\n            let err = io::Error::last_os_error();\n            error!(\"set SO_BINDTODEVICE error: {}\", err);\n            return Err(err);\n        }\n    }\n\n    Ok(())\n}\n\n#[cfg(target_os = \"android\")]\nmod android {\n    use std::{\n        io::{self, ErrorKind},\n        os::unix::io::{AsRawFd, RawFd},\n        path::Path,\n        time::Duration,\n    };\n    use tokio::{io::AsyncReadExt, time};\n\n    use super::super::uds::UnixStream;\n    use super::ConnectOpts;\n\n    /// This is a RPC for Android to `protect()` socket for connecting to remote servers\n    ///\n    /// https://developer.android.com/reference/android/net/VpnService#protect(java.net.Socket)\n    ///\n    /// More detail could be found in [shadowsocks-android](https://github.com/shadowsocks/shadowsocks-android) project.\n    async fn send_vpn_protect_uds<P: AsRef<Path>>(protect_path: P, fd: RawFd) -> io::Result<()> {\n        let mut stream = UnixStream::connect(protect_path).await?;\n\n        // send fds\n        let dummy: [u8; 1] = [1];\n        let fds: [RawFd; 1] = [fd];\n        stream.send_with_fd(&dummy, &fds).await?;\n\n        // receive the return value\n        let mut response = [0; 1];\n        stream.read_exact(&mut response).await?;\n\n        if response[0] == 0xFF {\n            return Err(io::Error::other(\"protect() failed\"));\n        }\n\n        Ok(())\n    }\n\n    /// Try to run VPNService#protect on Android\n    ///\n    /// https://developer.android.com/reference/android/net/VpnService#protect(java.net.Socket)\n    pub async fn vpn_protect<S>(socket: &S, opts: &ConnectOpts) -> io::Result<()>\n    where\n        S: AsRawFd + Send + Sync + 'static,\n    {\n        // shadowsocks-android uses a Unix domain socket to communicate with the VPNService#protect\n        if let Some(ref path) = opts.vpn_protect_path {\n            // RPC calls to `VpnService.protect()`\n            // Timeout in 3 seconds like shadowsocks-libev\n            match time::timeout(Duration::from_secs(3), send_vpn_protect_uds(path, socket.as_raw_fd())).await {\n                Ok(Ok(..)) => {}\n                Ok(Err(err)) => return Err(err),\n                Err(..) => return Err(io::Error::new(ErrorKind::TimedOut, \"protect() timeout\")),\n            }\n        }\n\n        // Customized SocketProtect\n        if let Some(ref protect) = opts.vpn_socket_protect {\n            protect.protect(socket.as_raw_fd())?;\n        }\n\n        Ok(())\n    }\n}\n\nstatic SUPPORT_BATCH_SEND_RECV_MSG: AtomicBool = AtomicBool::new(true);\n\nfn recvmsg_fallback<S: AsRawFd>(sock: &S, msg: &mut BatchRecvMessage<'_>) -> io::Result<()> {\n    let mut hdr: libc::msghdr = unsafe { mem::zeroed() };\n\n    let addr_storage = SockAddrStorage::zeroed();\n    let addr_len = addr_storage.size_of() as libc::socklen_t;\n\n    let sock_addr = unsafe { SockAddr::new(addr_storage, addr_len) };\n    hdr.msg_name = sock_addr.as_ptr() as *mut _;\n    hdr.msg_namelen = sock_addr.len() as _;\n\n    hdr.msg_iov = msg.data.as_ptr() as *mut _;\n    hdr.msg_iovlen = msg.data.len() as _;\n\n    let ret = unsafe { libc::recvmsg(sock.as_raw_fd(), &mut hdr as *mut _, 0) };\n    if ret < 0 {\n        return Err(io::Error::last_os_error());\n    }\n\n    msg.addr = sock_addr.as_socket().expect(\"SockAddr.as_socket\");\n    msg.data_len = ret as usize;\n\n    Ok(())\n}\n\npub fn batch_recvmsg<S: AsRawFd>(sock: &S, msgs: &mut [BatchRecvMessage<'_>]) -> io::Result<usize> {\n    if msgs.is_empty() {\n        return Ok(0);\n    }\n\n    if !SUPPORT_BATCH_SEND_RECV_MSG.load(Ordering::Relaxed) {\n        recvmsg_fallback(sock, &mut msgs[0])?;\n        return Ok(1);\n    }\n\n    let mut vec_msg_name = Vec::with_capacity(msgs.len());\n    let mut vec_msg_hdr = Vec::with_capacity(msgs.len());\n\n    for msg in msgs.iter_mut() {\n        let mut hdr: libc::mmsghdr = unsafe { mem::zeroed() };\n\n        let addr_storage = SockAddrStorage::zeroed();\n        let addr_len = addr_storage.size_of() as libc::socklen_t;\n\n        vec_msg_name.push(unsafe { SockAddr::new(addr_storage, addr_len) });\n        let sock_addr = vec_msg_name.last_mut().unwrap();\n        hdr.msg_hdr.msg_name = sock_addr.as_ptr() as *mut _;\n        hdr.msg_hdr.msg_namelen = sock_addr.len() as _;\n\n        hdr.msg_hdr.msg_iov = msg.data.as_ptr() as *mut _;\n        hdr.msg_hdr.msg_iovlen = msg.data.len() as _;\n\n        vec_msg_hdr.push(hdr);\n    }\n\n    let ret = unsafe {\n        libc::recvmmsg(\n            sock.as_raw_fd(),\n            vec_msg_hdr.as_mut_ptr(),\n            vec_msg_hdr.len() as _,\n            0,\n            ptr::null_mut(),\n        )\n    };\n    if ret < 0 {\n        let err = io::Error::last_os_error();\n        if let Some(libc::ENOSYS) = err.raw_os_error() {\n            debug!(\"recvmmsg is not supported, fallback to recvmsg, error: {:?}\", err);\n            SUPPORT_BATCH_SEND_RECV_MSG.store(false, Ordering::Relaxed);\n\n            recvmsg_fallback(sock, &mut msgs[0])?;\n            return Ok(1);\n        }\n        return Err(err);\n    }\n\n    for idx in 0..ret as usize {\n        let msg = &mut msgs[idx];\n        let hdr = &vec_msg_hdr[idx];\n        let name = &vec_msg_name[idx];\n        msg.addr = name.as_socket().expect(\"SockAddr.as_socket\");\n        msg.data_len = hdr.msg_len as usize;\n    }\n\n    Ok(ret as usize)\n}\n\nfn sendmsg_fallback<S: AsRawFd>(sock: &S, msg: &mut BatchSendMessage<'_>) -> io::Result<()> {\n    let mut hdr: libc::msghdr = unsafe { mem::zeroed() };\n\n    let sock_addr = msg.addr.map(SockAddr::from);\n    if let Some(ref sa) = sock_addr {\n        hdr.msg_name = sa.as_ptr() as *mut _;\n        hdr.msg_namelen = sa.len() as _;\n    }\n\n    hdr.msg_iov = msg.data.as_ptr() as *mut _;\n    hdr.msg_iovlen = msg.data.len() as _;\n\n    let ret = unsafe { libc::sendmsg(sock.as_raw_fd(), &hdr as *const _, 0) };\n    if ret < 0 {\n        return Err(io::Error::last_os_error());\n    }\n    msg.data_len = ret as usize;\n\n    Ok(())\n}\n\npub fn batch_sendmsg<S: AsRawFd>(sock: &S, msgs: &mut [BatchSendMessage<'_>]) -> io::Result<usize> {\n    if msgs.is_empty() {\n        return Ok(0);\n    }\n\n    if !SUPPORT_BATCH_SEND_RECV_MSG.load(Ordering::Relaxed) {\n        sendmsg_fallback(sock, &mut msgs[0])?;\n        return Ok(1);\n    }\n\n    let mut vec_msg_name = Vec::with_capacity(msgs.len());\n    let mut vec_msg_hdr = Vec::with_capacity(msgs.len());\n\n    for msg in msgs.iter_mut() {\n        let mut hdr: libc::mmsghdr = unsafe { mem::zeroed() };\n\n        if let Some(addr) = msg.addr {\n            vec_msg_name.push(SockAddr::from(addr));\n            let sock_addr = vec_msg_name.last_mut().unwrap();\n            hdr.msg_hdr.msg_name = sock_addr.as_ptr() as *mut _;\n            hdr.msg_hdr.msg_namelen = sock_addr.len() as _;\n        }\n\n        hdr.msg_hdr.msg_iov = msg.data.as_ptr() as *mut _;\n        hdr.msg_hdr.msg_iovlen = msg.data.len() as _;\n\n        vec_msg_hdr.push(hdr);\n    }\n\n    let ret = unsafe { libc::sendmmsg(sock.as_raw_fd(), vec_msg_hdr.as_mut_ptr(), vec_msg_hdr.len() as _, 0) };\n    if ret < 0 {\n        let err = io::Error::last_os_error();\n        if let Some(libc::ENOSYS) = err.raw_os_error() {\n            debug!(\"sendmmsg is not supported, fallback to sendmsg, error: {:?}\", err);\n            SUPPORT_BATCH_SEND_RECV_MSG.store(false, Ordering::Relaxed);\n\n            sendmsg_fallback(sock, &mut msgs[0])?;\n            return Ok(1);\n        }\n        return Err(err);\n    }\n\n    for idx in 0..ret as usize {\n        let msg = &mut msgs[idx];\n        let hdr = &vec_msg_hdr[idx];\n        msg.data_len = hdr.msg_len as usize;\n    }\n\n    Ok(ret as usize)\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/net/sys/unix/mod.rs",
    "content": "use std::{io, net::SocketAddr, os::fd::AsFd};\n\nuse cfg_if::cfg_if;\nuse log::warn;\nuse socket2::{Domain, Protocol, SockRef, Socket, TcpKeepalive, Type};\nuse tokio::net::UdpSocket;\n\nuse crate::net::{AcceptOpts, AddrFamily, ConnectOpts, TcpSocketOpts, is_dual_stack_addr, sys::socket_bind_dual_stack};\n\ncfg_if! {\n    if #[cfg(any(target_os = \"linux\", target_os = \"android\"))] {\n        mod linux;\n        pub use self::linux::*;\n    } else if #[cfg(any(target_os = \"freebsd\",\n                        target_os = \"openbsd\",\n                        target_os = \"netbsd\",\n                        target_os = \"dragonfly\",\n                        target_os = \"macos\",\n                        target_os = \"ios\",\n                        target_os = \"watchos\",\n                        target_os = \"tvos\"))] {\n        mod bsd;\n        pub use self::bsd::*;\n    } else {\n        mod others;\n        pub use self::others::*;\n    }\n}\n\npub mod uds;\n\n/// Create a `UdpSocket` binded to `addr`\npub async fn create_inbound_udp_socket(addr: &SocketAddr, ipv6_only: bool) -> io::Result<UdpSocket> {\n    let set_dual_stack = is_dual_stack_addr(addr);\n\n    let socket = if !set_dual_stack {\n        UdpSocket::bind(addr).await?\n    } else {\n        let socket = Socket::new(Domain::for_address(*addr), Type::DGRAM, Some(Protocol::UDP))?;\n        socket_bind_dual_stack(&socket, addr, ipv6_only)?;\n\n        // UdpSocket::from_std requires socket to be non-blocked\n        socket.set_nonblocking(true)?;\n        UdpSocket::from_std(socket.into())?\n    };\n\n    let addr_family = match addr {\n        SocketAddr::V4(..) => AddrFamily::Ipv4,\n        SocketAddr::V6(..) => AddrFamily::Ipv6,\n    };\n    if let Err(err) = set_disable_ip_fragmentation(addr_family, &socket) {\n        warn!(\"failed to disable IP fragmentation, error: {}\", err);\n    }\n\n    Ok(socket)\n}\n\n#[inline]\nfn set_tcp_keepalive(socket: &Socket, tcp: &TcpSocketOpts) -> io::Result<()> {\n    if let Some(intv) = tcp.keepalive {\n        #[allow(unused_mut)]\n        let mut keepalive = TcpKeepalive::new().with_time(intv);\n\n        #[cfg(any(\n            target_os = \"freebsd\",\n            target_os = \"fuchsia\",\n            target_os = \"linux\",\n            target_os = \"netbsd\",\n            target_vendor = \"apple\",\n        ))]\n        {\n            keepalive = keepalive.with_interval(intv);\n        }\n\n        cfg_if! {\n            if #[cfg(any(target_os = \"linux\", target_os = \"android\"))] {\n                // FIXME: Linux Kernel doesn't support setting TCP Keep Alive. (MPTCP)\n                // SO_KEEPALIVE works fine. But TCP_KEEPIDLE, TCP_KEEPINTV are not supported.\n                // https://github.com/multipath-tcp/mptcp_net-next/issues/383\n                // https://github.com/multipath-tcp/mptcp_net-next/issues/353\n                if let Err(err) = socket.set_tcp_keepalive(&keepalive) {\n                    log::debug!(\"set TCP keep-alive with time & interval failed with error: {:?}\", err);\n\n                    // Try again without time & interval\n                    let keepalive = TcpKeepalive::new();\n                    socket.set_tcp_keepalive(&keepalive)?;\n                }\n            } else {\n                socket.set_tcp_keepalive(&keepalive)?;\n            }\n        }\n    }\n\n    Ok(())\n}\n\n#[inline(always)]\nfn socket_call_warp<S, F>(stream: &S, f: F) -> io::Result<()>\nwhere\n    S: AsFd,\n    F: FnOnce(&Socket) -> io::Result<()>,\n{\n    let socket = SockRef::from(stream);\n    f(&socket)\n}\n\npub fn set_common_sockopt_after_connect<S>(stream: &S, opts: &ConnectOpts) -> io::Result<()>\nwhere\n    S: AsFd,\n{\n    socket_call_warp(stream, |socket| set_common_sockopt_after_connect_impl(socket, opts))\n}\n\nfn set_common_sockopt_after_connect_impl(socket: &Socket, opts: &ConnectOpts) -> io::Result<()> {\n    if opts.tcp.nodelay {\n        socket.set_tcp_nodelay(true)?;\n    }\n\n    set_tcp_keepalive(socket, &opts.tcp)?;\n\n    Ok(())\n}\n\npub fn set_common_sockopt_after_accept<S>(stream: &S, opts: &AcceptOpts) -> io::Result<()>\nwhere\n    S: AsFd,\n{\n    socket_call_warp(stream, |socket| set_common_sockopt_after_accept_impl(socket, opts))\n}\n\nfn set_common_sockopt_after_accept_impl(socket: &Socket, opts: &AcceptOpts) -> io::Result<()> {\n    if let Some(buf_size) = opts.tcp.send_buffer_size {\n        socket.set_send_buffer_size(buf_size as usize)?;\n    }\n\n    if let Some(buf_size) = opts.tcp.recv_buffer_size {\n        socket.set_recv_buffer_size(buf_size as usize)?;\n    }\n\n    socket.set_tcp_nodelay(opts.tcp.nodelay)?;\n\n    set_tcp_keepalive(socket, &opts.tcp)?;\n\n    Ok(())\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/net/sys/unix/others.rs",
    "content": "use std::{\n    io::{self, ErrorKind},\n    net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},\n    ops::{Deref, DerefMut},\n    os::fd::AsRawFd,\n    pin::Pin,\n    task::{self, Poll},\n};\n\nuse pin_project::pin_project;\nuse tokio::{\n    io::{AsyncRead, AsyncWrite, ReadBuf},\n    net::{TcpSocket, TcpStream as TokioTcpStream, UdpSocket},\n};\n\nuse crate::net::{\n    AcceptOpts, AddrFamily, ConnectOpts,\n    sys::{set_common_sockopt_after_connect, set_common_sockopt_for_connect},\n};\n\n/// A wrapper of `TcpStream`\n#[pin_project]\npub struct TcpStream(#[pin] TokioTcpStream);\n\nimpl TcpStream {\n    pub async fn connect(addr: SocketAddr, opts: &ConnectOpts) -> io::Result<TcpStream> {\n        let socket = match addr {\n            SocketAddr::V4(..) => TcpSocket::new_v4()?,\n            SocketAddr::V6(..) => TcpSocket::new_v6()?,\n        };\n\n        set_common_sockopt_for_connect(addr, &socket, opts)?;\n\n        let stream = socket.connect(addr).await?;\n        set_common_sockopt_after_connect(&stream, opts)?;\n        Ok(TcpStream(stream))\n    }\n}\n\nimpl Deref for TcpStream {\n    type Target = TokioTcpStream;\n\n    fn deref(&self) -> &Self::Target {\n        &self.0\n    }\n}\n\nimpl DerefMut for TcpStream {\n    fn deref_mut(&mut self) -> &mut Self::Target {\n        &mut self.0\n    }\n}\n\nimpl AsyncRead for TcpStream {\n    fn poll_read(self: Pin<&mut Self>, cx: &mut task::Context<'_>, buf: &mut ReadBuf<'_>) -> Poll<io::Result<()>> {\n        self.project().0.poll_read(cx, buf)\n    }\n}\n\nimpl AsyncWrite for TcpStream {\n    fn poll_write(self: Pin<&mut Self>, cx: &mut task::Context<'_>, buf: &[u8]) -> Poll<io::Result<usize>> {\n        self.project().0.poll_write(cx, buf)\n    }\n\n    fn poll_flush(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<io::Result<()>> {\n        self.project().0.poll_flush(cx)\n    }\n\n    fn poll_shutdown(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<io::Result<()>> {\n        self.project().0.poll_shutdown(cx)\n    }\n}\n\n/// Disable IP fragmentation\n#[inline]\npub fn set_disable_ip_fragmentation<S: AsRawFd>(_af: AddrFamily, _socket: &S) -> io::Result<()> {\n    Ok(())\n}\n\n/// Create a `UdpSocket` with specific address family\n#[inline]\npub async fn create_outbound_udp_socket(af: AddrFamily, config: &ConnectOpts) -> io::Result<UdpSocket> {\n    let bind_addr = match (af, config.bind_local_addr) {\n        (AddrFamily::Ipv4, Some(SocketAddr::V4(addr))) => addr.into(),\n        (AddrFamily::Ipv4, Some(SocketAddr::V6(addr))) => {\n            // Map IPv6 bind_local_addr to IPv4 if AF is IPv4\n            match addr.ip().to_ipv4_mapped() {\n                Some(addr) => SocketAddr::new(IpAddr::from(addr), 0),\n                None => return Err(io::Error::new(ErrorKind::InvalidInput, \"Invalid IPv6 address\")),\n            }\n        }\n        (AddrFamily::Ipv6, Some(SocketAddr::V6(addr))) => addr.into(),\n        (AddrFamily::Ipv6, Some(SocketAddr::V4(addr))) => {\n            // Map IPv4 bind_local_addr to IPv6 if AF is IPv6\n            let ip_addr: IpAddr = addr.ip().to_ipv6_mapped().into();\n            SocketAddr::new(ip_addr, 0)\n        }\n        (AddrFamily::Ipv4, ..) => SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), 0),\n        (AddrFamily::Ipv6, ..) => SocketAddr::new(Ipv6Addr::UNSPECIFIED.into(), 0),\n    };\n\n    bind_outbound_udp_socket(&bind_addr, config).await\n}\n\n/// Create a `UdpSocket` binded to `bind_addr`\npub async fn bind_outbound_udp_socket(bind_addr: &SocketAddr, _config: &ConnectOpts) -> io::Result<UdpSocket> {\n    let af = AddrFamily::from(bind_addr);\n\n    let socket = UdpSocket::bind(bind_addr).await?;\n    let _ = set_disable_ip_fragmentation(af, &socket);\n\n    Ok(socket)\n}\n\n/// Enable TCP Fast Open\npub fn set_tcp_fastopen<S: AsRawFd>(_: &S) -> io::Result<()> {\n    let err = io::Error::other(\"TFO is not supported in this platform\");\n    Err(err)\n}\n\n/// Create a TCP socket for listening\npub async fn create_inbound_tcp_socket(bind_addr: &SocketAddr, _accept_opts: &AcceptOpts) -> io::Result<TcpSocket> {\n    match bind_addr {\n        SocketAddr::V4(..) => TcpSocket::new_v4(),\n        SocketAddr::V6(..) => TcpSocket::new_v6(),\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/net/sys/unix/uds.rs",
    "content": "//! Android specific features\n\nuse std::{\n    io::{self, ErrorKind},\n    os::unix::io::RawFd,\n    path::Path,\n    pin::Pin,\n    task::{Context, Poll},\n};\n\nuse futures::{future, ready};\nuse pin_project::pin_project;\nuse sendfd::{RecvWithFd, SendWithFd};\nuse tokio::{\n    io::{AsyncRead, AsyncWrite, Interest, ReadBuf},\n    net::{UnixListener as TokioUnixListener, UnixStream as TokioUnixStream, unix::SocketAddr},\n};\n\n/// A UnixStream supports transferring FDs between processes\n#[pin_project]\npub struct UnixStream {\n    #[pin]\n    io: TokioUnixStream,\n}\n\nimpl UnixStream {\n    /// Connects to the socket named by `path`.\n    pub async fn connect<P: AsRef<Path>>(path: P) -> io::Result<Self> {\n        TokioUnixStream::connect(path).await.map(|io| Self { io })\n    }\n\n    fn poll_send_with_fd(&self, cx: &mut Context, buf: &[u8], fds: &[RawFd]) -> Poll<io::Result<usize>> {\n        loop {\n            ready!(self.io.poll_write_ready(cx))?;\n\n            match self.io.try_io(Interest::WRITABLE, || self.io.send_with_fd(buf, fds)) {\n                // self.io.poll_write_ready indicates that writable event have been received by tokio,\n                // so it is not a common case that sendto returns EAGAIN.\n                Err(ref err) if err.kind() == ErrorKind::WouldBlock => {}\n                x => return Poll::Ready(x),\n            }\n        }\n    }\n\n    /// Send data with file descriptors\n    pub async fn send_with_fd(&mut self, buf: &[u8], fds: &[RawFd]) -> io::Result<usize> {\n        future::poll_fn(|cx| self.poll_send_with_fd(cx, buf, fds)).await\n    }\n\n    fn poll_recv_with_fd(\n        &self,\n        cx: &mut Context,\n        buf: &mut [u8],\n        fds: &mut [RawFd],\n    ) -> Poll<io::Result<(usize, usize)>> {\n        loop {\n            ready!(self.io.poll_read_ready(cx))?;\n\n            match self.io.try_io(Interest::READABLE, || self.io.recv_with_fd(buf, fds)) {\n                // self.io.poll_write_ready indicates that writable event have been received by tokio,\n                // so it is not a common case that recvto returns EAGAIN.\n                //\n                // Just for double check. If EAGAIN actually returns, clear the readiness state.\n                Err(ref err) if err.kind() == ErrorKind::WouldBlock => {}\n                x => return Poll::Ready(x),\n            }\n        }\n    }\n\n    /// Recv data with file descriptors\n    pub async fn recv_with_fd(&mut self, buf: &mut [u8], fds: &mut [RawFd]) -> io::Result<(usize, usize)> {\n        future::poll_fn(|cx| self.poll_recv_with_fd(cx, buf, fds)).await\n    }\n}\n\nimpl AsyncRead for UnixStream {\n    fn poll_read(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>) -> Poll<io::Result<()>> {\n        self.project().io.poll_read(cx, buf)\n    }\n}\n\nimpl AsyncWrite for UnixStream {\n    fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<io::Result<usize>> {\n        self.project().io.poll_write(cx, buf)\n    }\n\n    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {\n        self.project().io.poll_flush(cx)\n    }\n\n    fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {\n        self.project().io.poll_shutdown(cx)\n    }\n}\n\n/// A UnixListener supports transferring FDs between processes\npub struct UnixListener {\n    io: TokioUnixListener,\n}\n\nimpl UnixListener {\n    /// Creates a new `UnixListener` bound to the specified socket.\n    pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<Self> {\n        TokioUnixListener::bind(path).map(|io| Self { io })\n    }\n\n    /// Accepts a new incoming connection to this listener.\n    pub fn poll_accept(&self, cx: &mut Context<'_>) -> Poll<io::Result<(UnixStream, SocketAddr)>> {\n        let (stream, peer_addr) = ready!(self.io.poll_accept(cx))?;\n        Ok((UnixStream { io: stream }, peer_addr)).into()\n    }\n\n    /// Accepts a new incoming connection to this listener.\n    pub async fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> {\n        future::poll_fn(|cx| self.poll_accept(cx)).await\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/net/sys/windows/mod.rs",
    "content": "use std::{\n    cell::RefCell,\n    collections::HashMap,\n    ffi::{CStr, CString, OsString, c_void},\n    io::{self, ErrorKind},\n    mem,\n    net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},\n    os::windows::{\n        ffi::OsStringExt,\n        io::{AsRawSocket, AsSocket, RawSocket},\n    },\n    pin::Pin,\n    ptr, slice,\n    task::{self, Poll},\n    time::{Duration, Instant},\n};\n\nuse bytes::BytesMut;\nuse log::{error, warn};\nuse pin_project::pin_project;\nuse socket2::{Domain, Protocol, SockAddr, SockRef, Socket, TcpKeepalive, Type};\nuse tokio::{\n    io::{AsyncRead, AsyncWrite, ReadBuf},\n    net::{TcpSocket, TcpStream as TokioTcpStream, UdpSocket},\n};\nuse tokio_tfo::TfoStream;\nuse windows_sys::{\n    Win32::{\n        Foundation::{ERROR_BUFFER_OVERFLOW, ERROR_NO_DATA, ERROR_SUCCESS, FALSE},\n        NetworkManagement::IpHelper::{\n            GAA_FLAG_SKIP_ANYCAST, GAA_FLAG_SKIP_DNS_SERVER, GAA_FLAG_SKIP_MULTICAST, GAA_FLAG_SKIP_UNICAST,\n            GetAdaptersAddresses, IP_ADAPTER_ADDRESSES_LH, if_nametoindex,\n        },\n        Networking::WinSock::{\n            AF_UNSPEC, IP_MTU_DISCOVER, IP_PMTUDISC_DO, IP_UNICAST_IF, IPPROTO_IP, IPPROTO_IPV6, IPPROTO_TCP,\n            IPV6_MTU_DISCOVER, IPV6_UNICAST_IF, SIO_UDP_CONNRESET, SOCKET, SOCKET_ERROR, TCP_FASTOPEN, WSAGetLastError,\n            WSAIoctl, htonl, setsockopt,\n        },\n    },\n    core::{BOOL, PCSTR},\n};\n\nuse crate::net::{\n    AcceptOpts, AddrFamily, ConnectOpts, is_dual_stack_addr,\n    sys::{set_common_sockopt_for_connect, socket_bind_dual_stack},\n};\n\n/// A `TcpStream` that supports TFO (TCP Fast Open)\n#[pin_project(project = TcpStreamProj)]\npub enum TcpStream {\n    Standard(#[pin] TokioTcpStream),\n    FastOpen(#[pin] TfoStream),\n}\n\nimpl TcpStream {\n    pub async fn connect(addr: SocketAddr, opts: &ConnectOpts) -> io::Result<TcpStream> {\n        let socket = match addr {\n            SocketAddr::V4(..) => TcpSocket::new_v4()?,\n            SocketAddr::V6(..) => TcpSocket::new_v6()?,\n        };\n\n        // Binds to a specific network interface (device)\n        if let Some(ref iface) = opts.bind_interface {\n            set_ip_unicast_if(&socket, &addr, iface)?;\n        }\n\n        set_common_sockopt_for_connect(addr, &socket, opts)?;\n\n        if !opts.tcp.fastopen {\n            // If TFO is not enabled, it just works like a normal TcpStream\n            let stream = socket.connect(addr).await?;\n            set_common_sockopt_after_connect(&stream, opts)?;\n\n            return Ok(TcpStream::Standard(stream));\n        }\n\n        let stream = TfoStream::connect_with_socket(socket, addr).await?;\n        set_common_sockopt_after_connect(&stream, opts)?;\n\n        Ok(TcpStream::FastOpen(stream))\n    }\n\n    pub fn local_addr(&self) -> io::Result<SocketAddr> {\n        match *self {\n            TcpStream::Standard(ref s) => s.local_addr(),\n            TcpStream::FastOpen(ref s) => s.local_addr(),\n        }\n    }\n\n    pub fn peer_addr(&self) -> io::Result<SocketAddr> {\n        match *self {\n            TcpStream::Standard(ref s) => s.peer_addr(),\n            TcpStream::FastOpen(ref s) => s.peer_addr(),\n        }\n    }\n\n    pub fn nodelay(&self) -> io::Result<bool> {\n        match *self {\n            TcpStream::Standard(ref s) => s.nodelay(),\n            TcpStream::FastOpen(ref s) => s.nodelay(),\n        }\n    }\n\n    pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {\n        match *self {\n            TcpStream::Standard(ref s) => s.set_nodelay(nodelay),\n            TcpStream::FastOpen(ref s) => s.set_nodelay(nodelay),\n        }\n    }\n}\n\nimpl AsRawSocket for TcpStream {\n    fn as_raw_socket(&self) -> RawSocket {\n        match *self {\n            TcpStream::Standard(ref s) => s.as_raw_socket(),\n            TcpStream::FastOpen(ref s) => s.as_raw_socket(),\n        }\n    }\n}\n\nimpl AsyncRead for TcpStream {\n    fn poll_read(self: Pin<&mut Self>, cx: &mut task::Context<'_>, buf: &mut ReadBuf<'_>) -> Poll<io::Result<()>> {\n        match self.project() {\n            TcpStreamProj::Standard(s) => s.poll_read(cx, buf),\n            TcpStreamProj::FastOpen(s) => s.poll_read(cx, buf),\n        }\n    }\n}\n\nimpl AsyncWrite for TcpStream {\n    fn poll_write(self: Pin<&mut Self>, cx: &mut task::Context<'_>, buf: &[u8]) -> Poll<io::Result<usize>> {\n        match self.project() {\n            TcpStreamProj::Standard(s) => s.poll_write(cx, buf),\n            TcpStreamProj::FastOpen(s) => s.poll_write(cx, buf),\n        }\n    }\n\n    fn poll_flush(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<io::Result<()>> {\n        match self.project() {\n            TcpStreamProj::Standard(s) => s.poll_flush(cx),\n            TcpStreamProj::FastOpen(s) => s.poll_flush(cx),\n        }\n    }\n\n    fn poll_shutdown(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<io::Result<()>> {\n        match self.project() {\n            TcpStreamProj::Standard(s) => s.poll_shutdown(cx),\n            TcpStreamProj::FastOpen(s) => s.poll_shutdown(cx),\n        }\n    }\n}\n\n/// Enable `TCP_FASTOPEN`\n///\n/// Program borrowed from\n/// https://social.msdn.microsoft.com/Forums/en-US/94d1fe8e-4f17-4b28-89eb-1ac776a2e134/how-to-create-tcp-fast-open-connections-with-winsock-?forum=windowsgeneraldevelopmentissues\n///\n/// TCP_FASTOPEN document\n/// https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options\n///\n/// TCP_FASTOPEN is supported since Windows 10\npub fn set_tcp_fastopen<S: AsRawSocket>(socket: &S) -> io::Result<()> {\n    let enable: u32 = 1;\n\n    unsafe {\n        let ret = setsockopt(\n            socket.as_raw_socket() as SOCKET,\n            IPPROTO_TCP,\n            TCP_FASTOPEN,\n            &enable as *const _ as PCSTR,\n            mem::size_of_val(&enable) as i32,\n        );\n\n        if ret == SOCKET_ERROR {\n            let err = io::Error::from_raw_os_error(WSAGetLastError());\n            error!(\"set TCP_FASTOPEN error: {}\", err);\n            return Err(err);\n        }\n    }\n\n    Ok(())\n}\n\n/// Create a TCP socket for listening\npub async fn create_inbound_tcp_socket(bind_addr: &SocketAddr, _accept_opts: &AcceptOpts) -> io::Result<TcpSocket> {\n    match bind_addr {\n        SocketAddr::V4(..) => TcpSocket::new_v4(),\n        SocketAddr::V6(..) => TcpSocket::new_v6(),\n    }\n}\n\nfn find_adapter_interface_index(addr: &SocketAddr, iface: &str) -> io::Result<Option<u32>> {\n    // https://learn.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getadaptersaddresses\n\n    let ip = addr.ip();\n\n    unsafe {\n        let mut ip_adapter_addresses_buffer = BytesMut::with_capacity(15 * 1024);\n        ip_adapter_addresses_buffer.set_len(15 * 1024);\n\n        let mut ip_adapter_addresses_buffer_size: u32 = ip_adapter_addresses_buffer.len() as u32;\n        loop {\n            let ret = GetAdaptersAddresses(\n                AF_UNSPEC as u32,\n                GAA_FLAG_SKIP_UNICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER,\n                ptr::null(),\n                ip_adapter_addresses_buffer.as_mut_ptr() as *mut _,\n                &mut ip_adapter_addresses_buffer_size as *mut _,\n            );\n\n            match ret {\n                ERROR_SUCCESS => break,\n                ERROR_BUFFER_OVERFLOW => {\n                    // resize buffer to ip_adapter_addresses_buffer_size\n                    ip_adapter_addresses_buffer.resize(ip_adapter_addresses_buffer_size as usize, 0);\n                    continue;\n                }\n                ERROR_NO_DATA => return Ok(None),\n                _ => {\n                    let err = io::Error::other(format!(\"GetAdaptersAddresses failed with error: {}\", ret));\n                    return Err(err);\n                }\n            }\n        }\n\n        // IP_ADAPTER_ADDRESSES_LH is a linked-list\n        let mut current_ip_adapter_address: *mut IP_ADAPTER_ADDRESSES_LH =\n            ip_adapter_addresses_buffer.as_mut_ptr() as *mut _;\n        while !current_ip_adapter_address.is_null() {\n            let ip_adapter_address: &IP_ADAPTER_ADDRESSES_LH = &*current_ip_adapter_address;\n\n            // Friendly Name\n            let friendly_name_len: usize = libc::wcslen(ip_adapter_address.FriendlyName);\n            let friendly_name_slice: &[u16] = slice::from_raw_parts(ip_adapter_address.FriendlyName, friendly_name_len);\n            let friendly_name_os = OsString::from_wide(friendly_name_slice); // UTF-16 to UTF-8\n            if let Some(friendly_name) = friendly_name_os.to_str()\n                && friendly_name == iface\n            {\n                match ip {\n                    IpAddr::V4(..) => return Ok(Some(ip_adapter_address.Anonymous1.Anonymous.IfIndex)),\n                    IpAddr::V6(..) => return Ok(Some(ip_adapter_address.Ipv6IfIndex)),\n                }\n            }\n\n            // Adapter Name\n            let adapter_name = CStr::from_ptr(ip_adapter_address.AdapterName as *mut _ as *const _);\n            if adapter_name.to_bytes() == iface.as_bytes() {\n                match ip {\n                    IpAddr::V4(..) => return Ok(Some(ip_adapter_address.Anonymous1.Anonymous.IfIndex)),\n                    IpAddr::V6(..) => return Ok(Some(ip_adapter_address.Ipv6IfIndex)),\n                }\n            }\n\n            current_ip_adapter_address = ip_adapter_address.Next;\n        }\n    }\n\n    Ok(None)\n}\n\nfn find_interface_index_cached(addr: &SocketAddr, iface: &str) -> io::Result<u32> {\n    const INDEX_EXPIRE_DURATION: Duration = Duration::from_secs(5);\n\n    thread_local! {\n        static INTERFACE_INDEX_CACHE: RefCell<HashMap<String, (u32, Instant)>> =\n            RefCell::new(HashMap::new());\n    }\n\n    let cache_index = INTERFACE_INDEX_CACHE.with(|cache| cache.borrow().get(iface).cloned());\n    if let Some((idx, insert_time)) = cache_index {\n        // short-path, cache hit for most cases\n        let now = Instant::now();\n        if now - insert_time < INDEX_EXPIRE_DURATION {\n            return Ok(idx);\n        }\n    }\n\n    // Get from API GetAdaptersAddresses\n    let idx = match find_adapter_interface_index(addr, iface)? {\n        Some(idx) => idx,\n        None => unsafe {\n            // Windows if_nametoindex requires a C-string for interface name\n            let ifname = CString::new(iface).expect(\"iface\");\n\n            // https://docs.microsoft.com/en-us/previous-versions/windows/hardware/drivers/ff553788(v=vs.85)\n            let if_index = if_nametoindex(ifname.as_ptr() as PCSTR);\n            if if_index == 0 {\n                // If the if_nametoindex function fails and returns zero, it is not possible to determine an error code.\n                error!(\"if_nametoindex {} fails\", iface);\n                return Err(io::Error::new(ErrorKind::InvalidInput, \"invalid interface name\"));\n            }\n\n            if_index\n        },\n    };\n\n    INTERFACE_INDEX_CACHE.with(|cache| {\n        cache.borrow_mut().insert(iface.to_owned(), (idx, Instant::now()));\n    });\n\n    Ok(idx)\n}\n\nfn set_ip_unicast_if<S: AsRawSocket>(socket: &S, addr: &SocketAddr, iface: &str) -> io::Result<()> {\n    let handle = socket.as_raw_socket() as SOCKET;\n\n    let if_index = find_interface_index_cached(addr, iface)?;\n\n    unsafe {\n        // https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options\n        let ret = match addr {\n            SocketAddr::V4(..) => {\n                // Interface index is in network byte order for IPPROTO_IP.\n                let if_index = htonl(if_index);\n                setsockopt(\n                    handle,\n                    IPPROTO_IP,\n                    IP_UNICAST_IF,\n                    &if_index as *const _ as PCSTR,\n                    mem::size_of_val(&if_index) as i32,\n                )\n            }\n            SocketAddr::V6(..) => {\n                // Interface index is in host byte order for IPPROTO_IPV6.\n                setsockopt(\n                    handle,\n                    IPPROTO_IPV6,\n                    IPV6_UNICAST_IF,\n                    &if_index as *const _ as PCSTR,\n                    mem::size_of_val(&if_index) as i32,\n                )\n            }\n        };\n\n        if ret == SOCKET_ERROR {\n            let err = io::Error::from_raw_os_error(WSAGetLastError());\n            error!(\n                \"set IP_UNICAST_IF / IPV6_UNICAST_IF interface: {}, index: {}, error: {}\",\n                iface, if_index, err\n            );\n            return Err(err);\n        }\n    }\n\n    Ok(())\n}\n\nfn disable_connection_reset(socket: &UdpSocket) -> io::Result<()> {\n    let handle = socket.as_raw_socket() as SOCKET;\n\n    unsafe {\n        // Ignoring UdpSocket's WSAECONNRESET error\n        // https://github.com/shadowsocks/shadowsocks-rust/issues/179\n        // https://stackoverflow.com/questions/30749423/is-winsock-error-10054-wsaeconnreset-normal-with-udp-to-from-localhost\n        //\n        // This is because `UdpSocket::recv_from` may return WSAECONNRESET\n        // if you called `UdpSocket::send_to` a destination that is not existed (may be closed).\n        //\n        // It is not an error. Could be ignored completely.\n        // We have to ignore it here because it will crash the server.\n\n        let mut bytes_returned: u32 = 0;\n        let enable: BOOL = FALSE;\n\n        let ret = WSAIoctl(\n            handle,\n            SIO_UDP_CONNRESET,\n            &enable as *const _ as *const c_void,\n            mem::size_of_val(&enable) as u32,\n            ptr::null_mut(),\n            0,\n            &mut bytes_returned as *mut _,\n            ptr::null_mut(),\n            None,\n        );\n\n        if ret == SOCKET_ERROR {\n            use std::io::Error;\n\n            // Error occurs\n            let err_code = WSAGetLastError();\n            return Err(Error::from_raw_os_error(err_code));\n        }\n    }\n\n    Ok(())\n}\n\n/// Disable IP fragmentation\n#[inline]\npub fn set_disable_ip_fragmentation<S: AsRawSocket>(af: AddrFamily, socket: &S) -> io::Result<()> {\n    let handle = socket.as_raw_socket() as SOCKET;\n\n    unsafe {\n        // For Windows, IP_MTU_DISCOVER should be enabled for both IPv4 and IPv6 sockets\n        // https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options\n        let value = IP_PMTUDISC_DO;\n        let ret = setsockopt(\n            handle,\n            IPPROTO_IP,\n            IP_MTU_DISCOVER,\n            &value as *const _ as PCSTR,\n            mem::size_of_val(&value) as i32,\n        );\n\n        if ret == SOCKET_ERROR {\n            let err = io::Error::from_raw_os_error(WSAGetLastError());\n            return Err(err);\n        }\n\n        if af == AddrFamily::Ipv6 {\n            let value = IP_PMTUDISC_DO;\n            let ret = setsockopt(\n                handle,\n                IPPROTO_IPV6,\n                IPV6_MTU_DISCOVER,\n                &value as *const _ as PCSTR,\n                mem::size_of_val(&value) as i32,\n            );\n\n            if ret == SOCKET_ERROR {\n                let err = io::Error::from_raw_os_error(WSAGetLastError());\n                return Err(err);\n            }\n        }\n    }\n\n    Ok(())\n}\n\n/// Create a `UdpSocket` binded to `addr`\n///\n/// It also disables `WSAECONNRESET` for UDP socket\npub async fn create_inbound_udp_socket(addr: &SocketAddr, ipv6_only: bool) -> io::Result<UdpSocket> {\n    let set_dual_stack = is_dual_stack_addr(addr);\n\n    let socket = if !set_dual_stack {\n        UdpSocket::bind(addr).await?\n    } else {\n        let socket = Socket::new(Domain::for_address(*addr), Type::DGRAM, Some(Protocol::UDP))?;\n        socket_bind_dual_stack(&socket, addr, ipv6_only)?;\n\n        // UdpSocket::from_std requires socket to be non-blocked\n        socket.set_nonblocking(true)?;\n        UdpSocket::from_std(socket.into())?\n    };\n\n    let addr_family = match addr {\n        SocketAddr::V4(..) => AddrFamily::Ipv4,\n        SocketAddr::V6(..) => AddrFamily::Ipv6,\n    };\n    if let Err(err) = set_disable_ip_fragmentation(addr_family, &socket) {\n        warn!(\"failed to disable IP fragmentation, error: {}\", err);\n    }\n    disable_connection_reset(&socket)?;\n\n    Ok(socket)\n}\n\n/// Create a `UdpSocket` for connecting to `addr`\n#[inline(always)]\npub async fn create_outbound_udp_socket(af: AddrFamily, opts: &ConnectOpts) -> io::Result<UdpSocket> {\n    let bind_addr = match (af, opts.bind_local_addr) {\n        (AddrFamily::Ipv4, Some(SocketAddr::V4(addr))) => addr.into(),\n        (AddrFamily::Ipv4, Some(SocketAddr::V6(addr))) => {\n            // Map IPv6 bind_local_addr to IPv4 if AF is IPv4\n            match addr.ip().to_ipv4_mapped() {\n                Some(addr) => SocketAddr::new(addr.into(), 0),\n                None => return Err(io::Error::new(ErrorKind::InvalidInput, \"Invalid IPv6 address\")),\n            }\n        }\n        (AddrFamily::Ipv6, Some(SocketAddr::V6(addr))) => addr.into(),\n        (AddrFamily::Ipv6, Some(SocketAddr::V4(addr))) => {\n            // Map IPv4 bind_local_addr to IPv6 if AF is IPv6\n            SocketAddr::new(addr.ip().to_ipv6_mapped().into(), 0)\n        }\n        (AddrFamily::Ipv4, ..) => SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), 0),\n        (AddrFamily::Ipv6, ..) => SocketAddr::new(Ipv6Addr::UNSPECIFIED.into(), 0),\n    };\n\n    bind_outbound_udp_socket(&bind_addr, opts).await\n}\n\n/// Create a `UdpSocket` binded to `bind_addr`\npub async fn bind_outbound_udp_socket(bind_addr: &SocketAddr, opts: &ConnectOpts) -> io::Result<UdpSocket> {\n    let af = AddrFamily::from(bind_addr);\n\n    let socket = Socket::new(Domain::for_address(*bind_addr), Type::DGRAM, Some(Protocol::UDP))?;\n\n    if let Some(ref iface) = opts.bind_interface {\n        set_ip_unicast_if(&socket, bind_addr, iface)?;\n    }\n\n    // bind() should be called after IP_UNICAST_IF\n    if af != AddrFamily::Ipv6 {\n        let bind_addr = SockAddr::from(*bind_addr);\n        socket.bind(&bind_addr)?;\n    } else {\n        socket_bind_dual_stack(&socket, bind_addr, false)?;\n    }\n\n    socket.set_nonblocking(true)?;\n    let socket = UdpSocket::from_std(socket.into())?;\n\n    if !opts.udp.allow_fragmentation\n        && let Err(err) = set_disable_ip_fragmentation(af, &socket)\n    {\n        warn!(\"failed to disable IP fragmentation, error: {}\", err);\n    }\n    disable_connection_reset(&socket)?;\n\n    Ok(socket)\n}\n\n#[inline(always)]\nfn socket_call_warp<S, F>(stream: &S, f: F) -> io::Result<()>\nwhere\n    S: AsSocket,\n    F: FnOnce(&Socket) -> io::Result<()>,\n{\n    let socket = SockRef::from(stream);\n    f(&socket)\n}\n\npub fn set_common_sockopt_after_connect<S>(stream: &S, opts: &ConnectOpts) -> io::Result<()>\nwhere\n    S: AsSocket,\n{\n    socket_call_warp(stream, |socket| set_common_sockopt_after_connect_impl(socket, opts))\n}\n\nfn set_common_sockopt_after_connect_impl(socket: &Socket, opts: &ConnectOpts) -> io::Result<()> {\n    if opts.tcp.nodelay {\n        socket.set_tcp_nodelay(true)?;\n    }\n\n    if let Some(intv) = opts.tcp.keepalive {\n        let keepalive = TcpKeepalive::new().with_time(intv).with_interval(intv);\n        socket.set_tcp_keepalive(&keepalive)?;\n    }\n\n    Ok(())\n}\n\npub fn set_common_sockopt_after_accept<S>(stream: &S, opts: &AcceptOpts) -> io::Result<()>\nwhere\n    S: AsSocket,\n{\n    socket_call_warp(stream, |socket| set_common_sockopt_after_accept_impl(socket, opts))\n}\n\nfn set_common_sockopt_after_accept_impl(socket: &Socket, opts: &AcceptOpts) -> io::Result<()> {\n    if let Some(buf_size) = opts.tcp.send_buffer_size {\n        socket.set_send_buffer_size(buf_size as usize)?;\n    }\n\n    if let Some(buf_size) = opts.tcp.recv_buffer_size {\n        socket.set_recv_buffer_size(buf_size as usize)?;\n    }\n\n    socket.set_tcp_nodelay(opts.tcp.nodelay)?;\n\n    if let Some(intv) = opts.tcp.keepalive {\n        let keepalive = TcpKeepalive::new().with_time(intv).with_interval(intv);\n        socket.set_tcp_keepalive(&keepalive)?;\n    }\n\n    Ok(())\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/net/tcp.rs",
    "content": "//! TcpStream wrappers that supports connecting with options\n\n#[cfg(unix)]\nuse std::os::unix::io::{AsRawFd, RawFd};\n#[cfg(windows)]\nuse std::os::windows::io::{AsRawSocket, RawSocket};\nuse std::{\n    io,\n    net::SocketAddr,\n    ops::{Deref, DerefMut},\n    pin::Pin,\n    task::{self, Poll},\n};\n\nuse futures::{future, ready};\nuse pin_project::pin_project;\nuse tokio::{\n    io::{AsyncRead, AsyncWrite, ReadBuf},\n    net::{TcpListener as TokioTcpListener, TcpStream as TokioTcpStream},\n};\n\nuse crate::{ServerAddr, context::Context, relay::socks5::Address};\n\nuse super::{\n    AcceptOpts, ConnectOpts, is_dual_stack_addr,\n    sys::{\n        TcpStream as SysTcpStream, create_inbound_tcp_socket, set_common_sockopt_after_accept, set_tcp_fastopen,\n        socket_bind_dual_stack,\n    },\n};\n\n/// TcpStream for outbound connections\n#[pin_project]\npub struct TcpStream(#[pin] SysTcpStream);\n\nimpl TcpStream {\n    /// Connects to address\n    pub async fn connect_with_opts(addr: &SocketAddr, opts: &ConnectOpts) -> io::Result<Self> {\n        // tcp_stream_connect(addr, opts).await.map(TcpStream)\n        SysTcpStream::connect(*addr, opts).await.map(TcpStream)\n    }\n\n    /// Connects shadowsocks server\n    pub async fn connect_server_with_opts(\n        context: &Context,\n        addr: &ServerAddr,\n        opts: &ConnectOpts,\n    ) -> io::Result<Self> {\n        let stream = match *addr {\n            ServerAddr::SocketAddr(ref addr) => SysTcpStream::connect(*addr, opts).await?,\n            ServerAddr::DomainName(ref domain, port) => {\n                lookup_then_connect!(context, domain, port, |addr| {\n                    SysTcpStream::connect(addr, opts).await\n                })?\n                .1\n            }\n        };\n\n        Ok(Self(stream))\n    }\n\n    /// Connects proxy remote target\n    pub async fn connect_remote_with_opts(context: &Context, addr: &Address, opts: &ConnectOpts) -> io::Result<Self> {\n        let stream = match *addr {\n            Address::SocketAddress(ref addr) => SysTcpStream::connect(*addr, opts).await?,\n            Address::DomainNameAddress(ref domain, port) => {\n                lookup_then_connect!(context, domain, port, |addr| {\n                    SysTcpStream::connect(addr, opts).await\n                })?\n                .1\n            }\n        };\n\n        Ok(Self(stream))\n    }\n\n    /// Returns the local address that this stream is bound to.\n    pub fn local_addr(&self) -> io::Result<SocketAddr> {\n        self.0.local_addr()\n    }\n\n    /// Returns the remote address that this stream is connected to.\n    pub fn peer_addr(&self) -> io::Result<SocketAddr> {\n        self.0.peer_addr()\n    }\n\n    /// Gets the value of the `TCP_NODELAY` option on this socket.\n    pub fn nodelay(&self) -> io::Result<bool> {\n        self.0.nodelay()\n    }\n\n    /// Sets the value of the `TCP_NODELAY` option on this socket.\n    pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {\n        self.0.set_nodelay(nodelay)\n    }\n}\n\nimpl AsyncRead for TcpStream {\n    fn poll_read(self: Pin<&mut Self>, cx: &mut task::Context<'_>, buf: &mut ReadBuf<'_>) -> Poll<io::Result<()>> {\n        self.project().0.poll_read(cx, buf)\n    }\n}\n\nimpl AsyncWrite for TcpStream {\n    fn poll_write(self: Pin<&mut Self>, cx: &mut task::Context<'_>, buf: &[u8]) -> Poll<io::Result<usize>> {\n        self.project().0.poll_write(cx, buf)\n    }\n\n    fn poll_flush(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<io::Result<()>> {\n        self.project().0.poll_flush(cx)\n    }\n\n    fn poll_shutdown(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<io::Result<()>> {\n        self.project().0.poll_shutdown(cx)\n    }\n}\n\n/// `TcpListener` for accepting inbound connections\n#[derive(Debug)]\npub struct TcpListener {\n    inner: TokioTcpListener,\n    accept_opts: AcceptOpts,\n}\n\nimpl TcpListener {\n    /// Creates a new TcpListener, which will be bound to the specified address.\n    pub async fn bind_with_opts(addr: &SocketAddr, accept_opts: AcceptOpts) -> io::Result<Self> {\n        let socket = create_inbound_tcp_socket(addr, &accept_opts).await?;\n\n        if let Some(size) = accept_opts.tcp.send_buffer_size {\n            socket.set_send_buffer_size(size)?;\n        }\n\n        if let Some(size) = accept_opts.tcp.recv_buffer_size {\n            socket.set_recv_buffer_size(size)?;\n        }\n\n        // On platforms with Berkeley-derived sockets, this allows to quickly\n        // rebind a socket, without needing to wait for the OS to clean up the\n        // previous one.\n        //\n        // On Windows, this allows rebinding sockets which are actively in use,\n        // which allows “socket hijacking”, so we explicitly don't set it here.\n        // https://docs.microsoft.com/en-us/windows/win32/winsock/using-so-reuseaddr-and-so-exclusiveaddruse\n        #[cfg(not(windows))]\n        socket.set_reuseaddr(true)?;\n\n        let set_dual_stack = is_dual_stack_addr(addr);\n\n        if set_dual_stack {\n            socket_bind_dual_stack(&socket, addr, accept_opts.ipv6_only)?;\n        } else {\n            socket.bind(*addr)?;\n        }\n\n        // mio's default backlog is 1024\n        let inner = socket.listen(1024)?;\n\n        // Enable TFO if supported\n        // macos requires TCP_FASTOPEN to be set after listen(), but other platform doesn't have this constraint\n        if accept_opts.tcp.fastopen {\n            set_tcp_fastopen(&inner)?;\n        }\n\n        Ok(Self { inner, accept_opts })\n    }\n\n    /// Create a `TcpListener` from tokio's `TcpListener`\n    pub fn from_listener(listener: TokioTcpListener, accept_opts: AcceptOpts) -> io::Result<Self> {\n        // Enable TFO if supported\n        // macos requires TCP_FASTOPEN to be set after listen(), but other platform doesn't have this constraint\n        if accept_opts.tcp.fastopen {\n            set_tcp_fastopen(&listener)?;\n        }\n\n        Ok(Self {\n            inner: listener,\n            accept_opts,\n        })\n    }\n\n    /// Polls to accept a new incoming connection to this listener.\n    pub fn poll_accept(&self, cx: &mut task::Context<'_>) -> Poll<io::Result<(TokioTcpStream, SocketAddr)>> {\n        let (stream, peer_addr) = ready!(self.inner.poll_accept(cx))?;\n        set_common_sockopt_after_accept(&stream, &self.accept_opts)?;\n        Poll::Ready(Ok((stream, peer_addr)))\n    }\n\n    /// Accept a new incoming connection to this listener\n    pub async fn accept(&self) -> io::Result<(TokioTcpStream, SocketAddr)> {\n        future::poll_fn(|cx| self.poll_accept(cx)).await\n    }\n\n    /// Unwraps and take the internal `TcpListener`\n    pub fn into_inner(self) -> TokioTcpListener {\n        self.inner\n    }\n}\n\nimpl Deref for TcpListener {\n    type Target = TokioTcpListener;\n\n    fn deref(&self) -> &Self::Target {\n        &self.inner\n    }\n}\n\nimpl DerefMut for TcpListener {\n    fn deref_mut(&mut self) -> &mut Self::Target {\n        &mut self.inner\n    }\n}\n\nimpl From<TcpListener> for TokioTcpListener {\n    fn from(listener: TcpListener) -> Self {\n        listener.inner\n    }\n}\n\n#[cfg(unix)]\nimpl AsRawFd for TcpStream {\n    fn as_raw_fd(&self) -> RawFd {\n        self.0.as_raw_fd()\n    }\n}\n\n#[cfg(windows)]\nimpl AsRawSocket for TcpStream {\n    fn as_raw_socket(&self) -> RawSocket {\n        self.0.as_raw_socket()\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/net/udp.rs",
    "content": "//! UDP socket wrappers\n\n#[cfg(any(\n    target_os = \"linux\",\n    target_os = \"android\",\n    target_os = \"macos\",\n    target_os = \"ios\",\n    target_os = \"freebsd\"\n))]\nuse std::io::{ErrorKind, IoSlice, IoSliceMut};\nuse std::{\n    io,\n    net::SocketAddr,\n    ops::{Deref, DerefMut},\n    task::{Context as TaskContext, Poll},\n};\n\n#[cfg(any(\n    target_os = \"linux\",\n    target_os = \"android\",\n    target_os = \"macos\",\n    target_os = \"ios\",\n    target_os = \"freebsd\"\n))]\nuse futures::future;\nuse futures::ready;\n\n#[cfg(any(\n    target_os = \"linux\",\n    target_os = \"android\",\n    target_os = \"macos\",\n    target_os = \"ios\",\n    target_os = \"freebsd\"\n))]\nuse tokio::io::Interest;\nuse tokio::{io::ReadBuf, net::ToSocketAddrs};\n\nuse crate::{ServerAddr, context::Context, relay::socks5::Address};\n\nuse super::{\n    AcceptOpts, AddrFamily, ConnectOpts,\n    sys::{bind_outbound_udp_socket, create_inbound_udp_socket, create_outbound_udp_socket},\n};\n\n/// Message struct for `batch_send`\n#[cfg(any(\n    target_os = \"linux\",\n    target_os = \"android\",\n    target_os = \"macos\",\n    target_os = \"ios\",\n    target_os = \"freebsd\"\n))]\npub struct BatchSendMessage<'a> {\n    /// Optional target address\n    pub addr: Option<SocketAddr>,\n    /// Data to be transmitted\n    pub data: &'a [IoSlice<'a>],\n    /// Output result. The number of bytes sent by `batch_send`\n    pub data_len: usize,\n}\n\n/// Message struct for `batch_recv`\n#[cfg(any(\n    target_os = \"linux\",\n    target_os = \"android\",\n    target_os = \"macos\",\n    target_os = \"ios\",\n    target_os = \"freebsd\"\n))]\npub struct BatchRecvMessage<'a> {\n    /// Peer address\n    pub addr: SocketAddr,\n    /// Data buffer for receiving\n    pub data: &'a mut [IoSliceMut<'a>],\n    /// Output result. The number of bytes received by `batch_recv`\n    pub data_len: usize,\n}\n\n#[inline]\nfn make_mtu_error(packet_size: usize, mtu: usize) -> io::Error {\n    io::Error::other(format!(\"UDP packet {} > MTU {}\", packet_size, mtu))\n}\n\n/// Wrappers for outbound `UdpSocket`\n#[derive(Debug)]\npub struct UdpSocket {\n    socket: tokio::net::UdpSocket,\n    mtu: Option<usize>,\n}\n\nimpl UdpSocket {\n    /// Connects to shadowsocks server\n    pub async fn connect_server_with_opts(\n        context: &Context,\n        addr: &ServerAddr,\n        opts: &ConnectOpts,\n    ) -> io::Result<Self> {\n        let socket = match *addr {\n            ServerAddr::SocketAddr(ref remote_addr) => {\n                let socket = create_outbound_udp_socket(From::from(remote_addr), opts).await?;\n                socket.connect(remote_addr).await?;\n                socket\n            }\n            ServerAddr::DomainName(ref dname, port) => {\n                lookup_then!(context, dname, port, |remote_addr| {\n                    let s = create_outbound_udp_socket(From::from(&remote_addr), opts).await?;\n                    s.connect(remote_addr).await.map(|_| s)\n                })?\n                .1\n            }\n        };\n\n        Ok(Self {\n            socket,\n            mtu: opts.udp.mtu,\n        })\n    }\n\n    /// Connects to proxy target\n    pub async fn connect_remote_with_opts(context: &Context, addr: &Address, opts: &ConnectOpts) -> io::Result<Self> {\n        let socket = match *addr {\n            Address::SocketAddress(ref remote_addr) => {\n                let socket = create_outbound_udp_socket(From::from(remote_addr), opts).await?;\n                socket.connect(remote_addr).await?;\n                socket\n            }\n            Address::DomainNameAddress(ref dname, port) => {\n                lookup_then!(context, dname, port, |remote_addr| {\n                    let s = create_outbound_udp_socket(From::from(&remote_addr), opts).await?;\n                    s.connect(remote_addr).await.map(|_| s)\n                })?\n                .1\n            }\n        };\n\n        Ok(Self {\n            socket,\n            mtu: opts.udp.mtu,\n        })\n    }\n\n    /// Connects to shadowsocks server\n    pub async fn connect_with_opts(addr: &SocketAddr, opts: &ConnectOpts) -> io::Result<Self> {\n        let socket = create_outbound_udp_socket(From::from(addr), opts).await?;\n        socket.connect(addr).await?;\n        Ok(Self {\n            socket,\n            mtu: opts.udp.mtu,\n        })\n    }\n\n    /// Binds to a specific address with opts\n    pub async fn connect_any_with_opts<AF: Into<AddrFamily>>(af: AF, opts: &ConnectOpts) -> io::Result<Self> {\n        create_outbound_udp_socket(af.into(), opts).await.map(|socket| Self {\n            socket,\n            mtu: opts.udp.mtu,\n        })\n    }\n\n    /// Binds to a specific address as an outbound socket\n    #[inline]\n    pub async fn bind(addr: &SocketAddr) -> io::Result<Self> {\n        Self::bind_with_opts(addr, &ConnectOpts::default()).await\n    }\n\n    /// Binds to a specific address with opts as an outbound socket\n    pub async fn bind_with_opts(addr: &SocketAddr, opts: &ConnectOpts) -> io::Result<Self> {\n        bind_outbound_udp_socket(addr, opts).await.map(|socket| Self {\n            socket,\n            mtu: opts.udp.mtu,\n        })\n    }\n\n    /// Binds to a specific address (inbound)\n    #[inline]\n    pub async fn listen(addr: &SocketAddr) -> io::Result<Self> {\n        Self::listen_with_opts(addr, AcceptOpts::default()).await\n    }\n\n    /// Binds to a specific address (inbound)\n    pub async fn listen_with_opts(addr: &SocketAddr, opts: AcceptOpts) -> io::Result<Self> {\n        let socket = create_inbound_udp_socket(addr, opts.ipv6_only).await?;\n        Ok(Self {\n            socket,\n            mtu: opts.udp.mtu,\n        })\n    }\n\n    /// Wrapper of `UdpSocket::poll_send`\n    pub fn poll_send(&self, cx: &mut TaskContext<'_>, buf: &[u8]) -> Poll<io::Result<usize>> {\n        // Check MTU\n        if let Some(mtu) = self.mtu\n            && buf.len() > mtu\n        {\n            return Err(make_mtu_error(buf.len(), mtu)).into();\n        }\n\n        self.socket.poll_send(cx, buf)\n    }\n\n    /// Wrapper of `UdpSocket::send`\n    #[inline]\n    pub async fn send(&self, buf: &[u8]) -> io::Result<usize> {\n        // Check MTU\n        if let Some(mtu) = self.mtu\n            && buf.len() > mtu\n        {\n            return Err(make_mtu_error(buf.len(), mtu));\n        }\n\n        self.socket.send(buf).await\n    }\n\n    /// Wrapper of `UdpSocket::poll_send_to`\n    pub fn poll_send_to(&self, cx: &mut TaskContext<'_>, buf: &[u8], target: SocketAddr) -> Poll<io::Result<usize>> {\n        // Check MTU\n        if let Some(mtu) = self.mtu\n            && buf.len() > mtu\n        {\n            return Err(make_mtu_error(buf.len(), mtu)).into();\n        }\n\n        self.socket.poll_send_to(cx, buf, target)\n    }\n\n    /// Wrapper of `UdpSocket::send_to`\n    #[inline]\n    pub async fn send_to<A: ToSocketAddrs>(&self, buf: &[u8], target: A) -> io::Result<usize> {\n        // Check MTU\n        if let Some(mtu) = self.mtu\n            && buf.len() > mtu\n        {\n            return Err(make_mtu_error(buf.len(), mtu));\n        }\n\n        self.socket.send_to(buf, target).await\n    }\n\n    /// Wrapper of `UdpSocket::poll_recv`\n    #[inline]\n    pub fn poll_recv(&self, cx: &mut TaskContext<'_>, buf: &mut ReadBuf<'_>) -> Poll<io::Result<()>> {\n        ready!(self.socket.poll_recv(cx, buf))?;\n\n        if let Some(mtu) = self.mtu\n            && buf.filled().len() > mtu\n        {\n            return Err(make_mtu_error(buf.filled().len(), mtu)).into();\n        }\n\n        Ok(()).into()\n    }\n\n    /// Wrapper of `UdpSocket::recv`\n    #[inline]\n    pub async fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {\n        let n = self.socket.recv(buf).await?;\n\n        if let Some(mtu) = self.mtu\n            && n > mtu\n        {\n            return Err(make_mtu_error(n, mtu));\n        }\n\n        Ok(n)\n    }\n\n    /// Wrapper of `UdpSocket::poll_recv_from`\n    #[inline]\n    pub fn poll_recv_from(&self, cx: &mut TaskContext<'_>, buf: &mut ReadBuf<'_>) -> Poll<io::Result<SocketAddr>> {\n        let addr = ready!(self.socket.poll_recv_from(cx, buf))?;\n\n        if let Some(mtu) = self.mtu\n            && buf.filled().len() > mtu\n        {\n            return Err(make_mtu_error(buf.filled().len(), mtu)).into();\n        }\n\n        Ok(addr).into()\n    }\n\n    /// Wrapper of `UdpSocket::recv`\n    #[inline]\n    pub async fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {\n        let (n, addr) = self.socket.recv_from(buf).await?;\n\n        if let Some(mtu) = self.mtu\n            && n > mtu\n        {\n            return Err(make_mtu_error(n, mtu));\n        }\n\n        Ok((n, addr))\n    }\n\n    /// Batch send packets\n    #[cfg(any(\n        target_os = \"linux\",\n        target_os = \"android\",\n        target_os = \"macos\",\n        target_os = \"ios\",\n        target_os = \"freebsd\"\n    ))]\n    pub fn poll_batch_send(\n        &self,\n        cx: &mut TaskContext<'_>,\n        msgs: &mut [BatchSendMessage<'_>],\n    ) -> Poll<io::Result<usize>> {\n        use super::sys::batch_sendmsg;\n\n        loop {\n            ready!(self.socket.poll_send_ready(cx))?;\n\n            match self\n                .socket\n                .try_io(Interest::WRITABLE, || batch_sendmsg(&self.socket, msgs))\n            {\n                Ok(n) => return Ok(n).into(),\n                Err(ref err) if err.kind() == ErrorKind::WouldBlock => {}\n                Err(err) => return Err(err).into(),\n            }\n        }\n    }\n\n    /// Batch send packets\n    #[cfg(any(\n        target_os = \"linux\",\n        target_os = \"android\",\n        target_os = \"macos\",\n        target_os = \"ios\",\n        target_os = \"freebsd\"\n    ))]\n    pub async fn batch_send(&self, msgs: &mut [BatchSendMessage<'_>]) -> io::Result<usize> {\n        future::poll_fn(|cx| self.poll_batch_send(cx, msgs)).await\n    }\n\n    /// Batch recv packets\n    #[cfg(any(\n        target_os = \"linux\",\n        target_os = \"android\",\n        target_os = \"ios\",\n        target_os = \"macos\",\n        target_os = \"freebsd\"\n    ))]\n    pub fn poll_batch_recv(\n        &self,\n        cx: &mut TaskContext<'_>,\n        msgs: &mut [BatchRecvMessage<'_>],\n    ) -> Poll<io::Result<usize>> {\n        use super::sys::batch_recvmsg;\n\n        loop {\n            ready!(self.socket.poll_recv_ready(cx))?;\n\n            match self\n                .socket\n                .try_io(Interest::READABLE, || batch_recvmsg(&self.socket, msgs))\n            {\n                Ok(n) => return Ok(n).into(),\n                Err(ref err) if err.kind() == ErrorKind::WouldBlock => {}\n                Err(err) => return Err(err).into(),\n            }\n        }\n    }\n\n    /// Batch recv packets\n    #[cfg(any(\n        target_os = \"linux\",\n        target_os = \"android\",\n        target_os = \"macos\",\n        target_os = \"ios\",\n        target_os = \"freebsd\"\n    ))]\n    pub async fn batch_recv(&self, msgs: &mut [BatchRecvMessage<'_>]) -> io::Result<usize> {\n        future::poll_fn(|cx| self.poll_batch_recv(cx, msgs)).await\n    }\n}\n\nimpl Deref for UdpSocket {\n    type Target = tokio::net::UdpSocket;\n\n    fn deref(&self) -> &Self::Target {\n        &self.socket\n    }\n}\n\nimpl DerefMut for UdpSocket {\n    fn deref_mut(&mut self) -> &mut Self::Target {\n        &mut self.socket\n    }\n}\n\nimpl From<tokio::net::UdpSocket> for UdpSocket {\n    fn from(socket: tokio::net::UdpSocket) -> Self {\n        Self { socket, mtu: None }\n    }\n}\n\nimpl From<UdpSocket> for tokio::net::UdpSocket {\n    fn from(s: UdpSocket) -> Self {\n        s.socket\n    }\n}\n\n#[cfg(unix)]\nimpl std::os::fd::AsRawFd for UdpSocket {\n    fn as_raw_fd(&self) -> std::os::fd::RawFd {\n        self.socket.as_raw_fd()\n    }\n}\n\n#[cfg(unix)]\nimpl std::os::fd::AsFd for UdpSocket {\n    fn as_fd(&self) -> std::os::fd::BorrowedFd<'_> {\n        self.socket.as_fd()\n    }\n}\n\n#[cfg(windows)]\nimpl std::os::windows::io::AsRawSocket for UdpSocket {\n    fn as_raw_socket(&self) -> std::os::windows::io::RawSocket {\n        self.socket.as_raw_socket()\n    }\n}\n\n#[cfg(windows)]\nimpl std::os::windows::io::AsSocket for UdpSocket {\n    fn as_socket(&self) -> std::os::windows::io::BorrowedSocket<'_> {\n        self.socket.as_socket()\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/plugin/mod.rs",
    "content": "//! Plugin (SIP003)\n//!\n//! ```plain\n//! +------------+                    +---------------------------+\n//! |  SS Client +-- Local Loopback --+  Plugin Client (Tunnel)   +--+\n//! +------------+                    +---------------------------+  |\n//!                                                                  |\n//!             Public Internet (Obfuscated/Transformed traffic) ==> |\n//!                                                                  |\n//! +------------+                    +---------------------------+  |\n//! |  SS Server +-- Local Loopback --+  Plugin Server (Tunnel)   +--+\n//! +------------+                    +---------------------------+\n//! ```\n\nuse std::{\n    io,\n    net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, TcpListener},\n    process::ExitStatus,\n    time::{Duration, Instant},\n};\n\nuse log::{debug, error};\nuse tokio::{net::TcpStream, process::Child, time};\n\nuse crate::config::{Mode, ServerAddr};\n\nmod obfs_proxy;\nmod ss_plugin;\n\n/// Config for plugin\n#[derive(Debug, Clone)]\npub struct PluginConfig {\n    pub plugin: String,\n    pub plugin_opts: Option<String>,\n    pub plugin_args: Vec<String>,\n    pub plugin_mode: Mode,\n}\n\n/// Mode of Plugin\n#[derive(Debug, Clone, Copy)]\npub enum PluginMode {\n    /// Server's Plugin\n    ///\n    /// ```plain\n    /// LOCAL -> PLUGIN -> SERVER -> REMOTE\n    /// ```\n    ///\n    /// Plugin listens to the inbound address of server\n    Server,\n    /// Local's Plugin\n    ///\n    /// ```plain\n    /// CLIENT -> LOCAL -> PLUGIN -> SERVER -> ...\n    /// ```\n    ///\n    /// Plugin sends data to the outbound address of server\n    Client,\n}\n\n/// A shadowsocks SIP004 Plugin\n#[derive(Debug)]\npub struct Plugin {\n    process: Child,\n    local_addr: SocketAddr,\n    mode: Mode,\n}\n\nimpl Plugin {\n    /// Start a plugin subprocess\n    ///\n    /// `PluginMode::Client`: Plugin listens to `local_addr` and send data to `remote_addr`, client should send data to `local_addr`\n    /// `PluginMode::Server`: Plugin listens to `remote_addr` and send data to `local_addr`, server should listen to `local_addr`\n    pub fn start(c: &PluginConfig, remote_addr: &ServerAddr, mode: PluginMode) -> io::Result<Self> {\n        let loop_ip = match remote_addr {\n            ServerAddr::SocketAddr(sa) => match sa.ip() {\n                IpAddr::V4(..) => Ipv4Addr::LOCALHOST.into(),\n                IpAddr::V6(..) => Ipv6Addr::LOCALHOST.into(),\n            },\n            ServerAddr::DomainName(..) => Ipv4Addr::LOCALHOST.into(),\n        };\n\n        let local_addr = get_local_port(loop_ip)?;\n\n        match start_plugin(c, remote_addr, &local_addr, mode) {\n            Err(err) => {\n                error!(\n                    \"failed to start plugin \\\"{}\\\" for server {}, err: {}\",\n                    c.plugin, remote_addr, err\n                );\n                Err(err)\n            }\n            Ok(process) => {\n                match mode {\n                    PluginMode::Client => {\n                        debug!(\n                            \"started plugin \\\"{}\\\" on {} <-> {} ({}) {}\",\n                            c.plugin,\n                            local_addr,\n                            remote_addr,\n                            process.id().unwrap_or(0),\n                            c.plugin_mode\n                        );\n                    }\n                    PluginMode::Server => {\n                        debug!(\n                            \"started plugin \\\"{}\\\" on {} <-> {} ({}) {}\",\n                            c.plugin,\n                            remote_addr,\n                            local_addr,\n                            process.id().unwrap_or(0),\n                            c.plugin_mode\n                        );\n                    }\n                }\n\n                Ok(Self {\n                    process,\n                    local_addr,\n                    mode: c.plugin_mode,\n                })\n            }\n        }\n    }\n\n    /// Join until plugin exits\n    pub async fn join(mut self) -> io::Result<ExitStatus> {\n        self.process.wait().await\n    }\n\n    /// Check if plugin have been started\n    pub async fn wait_started(&self, timeout: Duration) -> bool {\n        // Only test started with TCP connect()\n        // XXX: Is there an easy way to test if UDP port was listening? (no ICMP!)\n        if !self.mode.enable_tcp() {\n            return true;\n        }\n\n        let start_time = Instant::now();\n\n        loop {\n            let now_time = Instant::now();\n            let elapsed_time = now_time - start_time;\n            if elapsed_time >= timeout {\n                return false;\n            }\n\n            let remain_time = timeout - elapsed_time;\n\n            match time::timeout(remain_time, TcpStream::connect(self.local_addr)).await {\n                Ok(Ok(..)) => {\n                    return true;\n                }\n                Ok(Err(..)) => {}\n                Err(..) => {\n                    return false;\n                }\n            }\n        }\n    }\n\n    /// Get listen address of plugin\n    pub fn local_addr(&self) -> SocketAddr {\n        self.local_addr\n    }\n}\n\nimpl Drop for Plugin {\n    // NOTE: Even we have set `Command.kill_on_drop(true)`, processes may not be killed when `Child` handles are dropped.\n    // https://github.com/tokio-rs/tokio/issues/2685\n\n    #[cfg(not(unix))]\n    fn drop(&mut self) {\n        debug!(\n            \"killing plugin process {:?}, local_addr: {}\",\n            self.process.id(),\n            self.local_addr\n        );\n        let _ = self.process.start_kill();\n    }\n\n    #[cfg(unix)]\n    fn drop(&mut self) {\n        debug!(\n            \"terminating plugin process {:?}, local_addr: {}\",\n            self.process.id(),\n            self.local_addr\n        );\n\n        let mut terminated = false;\n\n        if let Some(id) = self.process.id() {\n            unsafe {\n                let ret = libc::kill(id as libc::pid_t, libc::SIGTERM);\n                if ret != 0 {\n                    let err = io::Error::last_os_error();\n                    error!(\"terminating plugin process {}, error: {}\", id, err);\n                }\n            }\n\n            const MAX_WAIT_DURATION: Duration = Duration::from_millis(10);\n\n            let start_wait = Instant::now();\n            loop {\n                match self.process.try_wait() {\n                    Ok(Some(status)) => {\n                        // subprocess is finished\n                        debug!(\n                            \"plugin process {} is terminated gracefully with status: {:?}\",\n                            id, status\n                        );\n                        terminated = true;\n                        break;\n                    }\n                    Ok(None) => {}\n                    Err(err) => {\n                        error!(\"plugin process waitpid error: {}\", err);\n                        break;\n                    }\n                }\n\n                let elapsed = Instant::now() - start_wait;\n                if elapsed > MAX_WAIT_DURATION {\n                    debug!(\"plugin process {} isn't terminated in {:?}\", id, MAX_WAIT_DURATION);\n                    break;\n                }\n\n                std::thread::yield_now();\n            }\n        }\n\n        if !terminated && self.process.start_kill().is_ok() {\n            debug!(\"killed plugin process {:?}\", self.process.id());\n        }\n    }\n}\n\nfn start_plugin(plugin: &PluginConfig, remote: &ServerAddr, local: &SocketAddr, mode: PluginMode) -> io::Result<Child> {\n    let mut cmd = if plugin.plugin == \"obfsproxy\" {\n        obfs_proxy::plugin_cmd(plugin, remote, local, mode)\n    } else {\n        ss_plugin::plugin_cmd(plugin, remote, local, mode)\n    };\n    cmd.spawn()\n}\n\nfn get_local_port(loop_ip: IpAddr) -> io::Result<SocketAddr> {\n    let listener = TcpListener::bind(SocketAddr::new(loop_ip, 0))?;\n    listener.local_addr()\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n\n    #[test]\n    fn generate_random_port() {\n        let loop_ip = Ipv4Addr::LOCALHOST.into();\n        let addr = get_local_port(loop_ip).unwrap();\n        println!(\"{addr:?}\");\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/plugin/obfs_proxy.rs",
    "content": "use super::{PluginConfig, PluginMode};\nuse crate::config::ServerAddr;\nuse std::{net::SocketAddr, process::Stdio};\nuse tokio::process::Command;\n\n/// For obfsproxy, we use standalone mode for now.\n/// Managed mode needs to use SOCKS5 proxy as forwarder, which is not supported\n/// yet.\n///\n/// The idea of using standalone mode is quite simple, just assemble the\n/// internal port into obfsproxy parameters.\n///\n/// Using manually ran scramblesuit as an example:\n/// obfsproxy \\\n/// --data-dir /tmp/ss_libev_plugin_with_suffix \\\n/// scramblesuit \\\n/// --password SOMEMEANINGLESSPASSWORDASEXAMPLE \\\n/// --dest some.server.org:12345 \\\n/// client \\\n/// 127.0.0.1:54321\n///\n/// In above case, @plugin = \"obfsproxy\",\n/// @plugin_opts = \"scramblesuit --password SOMEMEANINGLESSPASSWORDASEXAMPLE\"\n/// For obfs3, it's even easier, just pass @plugin = \"obfsproxy\"\n/// @plugin_opts = \"obfs3\"\n///\n/// And the rest parameters are all assembled here.\n/// Some old obfsproxy will not be supported as it doesn't even support\n/// \"--data-dir\" option\npub fn plugin_cmd(plugin: &PluginConfig, remote: &ServerAddr, local: &SocketAddr, mode: PluginMode) -> Command {\n    let mut cmd = Command::new(&plugin.plugin);\n    cmd.stdin(Stdio::null())\n        .kill_on_drop(true)\n        .arg(\"--data-dir\")\n        .arg(format!(\"/tmp/{}_{}_{}\", plugin.plugin, remote, local)); // FIXME: Not compatible in Windows\n\n    if let Some(ref opt) = plugin.plugin_opts {\n        cmd.args(opt.split(' '));\n    }\n\n    match mode {\n        PluginMode::Client => cmd\n            .arg(\"--dest\")\n            .arg(remote.to_string())\n            .arg(\"client\")\n            .arg(local.to_string()),\n        PluginMode::Server => cmd\n            .arg(\"--dest\")\n            .arg(local.to_string())\n            .arg(\"server\")\n            .arg(remote.to_string()),\n    };\n\n    if !plugin.plugin_args.is_empty() {\n        cmd.args(&plugin.plugin_args);\n    }\n\n    cmd\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/plugin/ss_plugin.rs",
    "content": "use super::{PluginConfig, PluginMode};\nuse crate::config::ServerAddr;\nuse log::trace;\nuse std::{net::SocketAddr, process::Stdio};\nuse tokio::process::Command;\n\npub fn plugin_cmd(plugin: &PluginConfig, remote: &ServerAddr, local: &SocketAddr, _mode: PluginMode) -> Command {\n    trace!(\n        \"Starting plugin \\\"{}\\\", opt: {:?}, arg: {:?}, remote: {}, local: {}\",\n        plugin.plugin, plugin.plugin_opts, plugin.plugin_args, remote, local\n    );\n\n    let mut cmd = Command::new(&plugin.plugin);\n    cmd.env(\"SS_REMOTE_HOST\", remote.host())\n        .env(\"SS_REMOTE_PORT\", remote.port().to_string())\n        .env(\"SS_LOCAL_HOST\", local.ip().to_string())\n        .env(\"SS_LOCAL_PORT\", local.port().to_string())\n        .stdin(Stdio::null())\n        .kill_on_drop(true);\n\n    if let Some(ref opt) = plugin.plugin_opts {\n        cmd.env(\"SS_PLUGIN_OPTIONS\", opt);\n    }\n\n    if !plugin.plugin_args.is_empty() {\n        cmd.args(&plugin.plugin_args);\n    }\n\n    cmd\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/relay/mod.rs",
    "content": "//! Relay server in local and server side implementations.\n\npub use self::socks5::Address;\n\npub mod socks5;\npub mod tcprelay;\npub mod udprelay;\n\n/// AEAD 2022 maximum padding length\n#[cfg(feature = \"aead-cipher-2022\")]\nconst AEAD2022_MAX_PADDING_SIZE: usize = 900;\n\n/// Get a properly AEAD 2022 padding size according to payload's length\n#[cfg(feature = \"aead-cipher-2022\")]\nfn get_aead_2022_padding_size(payload: &[u8]) -> usize {\n    use std::cell::RefCell;\n\n    use rand::{RngExt, rngs::SmallRng};\n\n    thread_local! {\n        static PADDING_RNG: RefCell<SmallRng> = RefCell::new(rand::make_rng());\n    }\n\n    if payload.is_empty() {\n        PADDING_RNG.with(|rng| rng.borrow_mut().random_range::<usize, _>(0..=AEAD2022_MAX_PADDING_SIZE))\n    } else {\n        0\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/relay/socks5.rs",
    "content": "//! Socks5 protocol definition (RFC1928)\n//!\n//! Implements [SOCKS Protocol Version 5](https://www.ietf.org/rfc/rfc1928.txt) proxy protocol\n\nuse std::{\n    convert::From,\n    fmt::{self, Debug, Display, Formatter},\n    io::{self, ErrorKind},\n    net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs},\n    slice,\n    str::FromStr,\n    vec,\n};\n\nuse bytes::{Buf, BufMut, BytesMut};\nuse tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};\n\npub use self::consts::{\n    SOCKS5_AUTH_METHOD_GSSAPI, SOCKS5_AUTH_METHOD_NONE, SOCKS5_AUTH_METHOD_NOT_ACCEPTABLE, SOCKS5_AUTH_METHOD_PASSWORD,\n};\n\n#[rustfmt::skip]\nmod consts {\n    pub const SOCKS5_VERSION:                          u8 = 0x05;\n\n    pub const SOCKS5_AUTH_METHOD_NONE:                 u8 = 0x00;\n    pub const SOCKS5_AUTH_METHOD_GSSAPI:               u8 = 0x01;\n    pub const SOCKS5_AUTH_METHOD_PASSWORD:             u8 = 0x02;\n    pub const SOCKS5_AUTH_METHOD_NOT_ACCEPTABLE:       u8 = 0xff;\n\n    pub const SOCKS5_CMD_TCP_CONNECT:                  u8 = 0x01;\n    pub const SOCKS5_CMD_TCP_BIND:                     u8 = 0x02;\n    pub const SOCKS5_CMD_UDP_ASSOCIATE:                u8 = 0x03;\n\n    pub const SOCKS5_ADDR_TYPE_IPV4:                   u8 = 0x01;\n    pub const SOCKS5_ADDR_TYPE_DOMAIN_NAME:            u8 = 0x03;\n    pub const SOCKS5_ADDR_TYPE_IPV6:                   u8 = 0x04;\n\n    pub const SOCKS5_REPLY_SUCCEEDED:                  u8 = 0x00;\n    pub const SOCKS5_REPLY_GENERAL_FAILURE:            u8 = 0x01;\n    pub const SOCKS5_REPLY_CONNECTION_NOT_ALLOWED:     u8 = 0x02;\n    pub const SOCKS5_REPLY_NETWORK_UNREACHABLE:        u8 = 0x03;\n    pub const SOCKS5_REPLY_HOST_UNREACHABLE:           u8 = 0x04;\n    pub const SOCKS5_REPLY_CONNECTION_REFUSED:         u8 = 0x05;\n    pub const SOCKS5_REPLY_TTL_EXPIRED:                u8 = 0x06;\n    pub const SOCKS5_REPLY_COMMAND_NOT_SUPPORTED:      u8 = 0x07;\n    pub const SOCKS5_REPLY_ADDRESS_TYPE_NOT_SUPPORTED: u8 = 0x08;\n}\n\n/// SOCKS5 command\n#[derive(Clone, Debug, Copy)]\npub enum Command {\n    /// CONNECT command (TCP tunnel)\n    TcpConnect,\n    /// BIND command (Not supported in ShadowSocks)\n    TcpBind,\n    /// UDP ASSOCIATE command\n    UdpAssociate,\n}\n\nimpl Command {\n    #[inline]\n    #[rustfmt::skip]\n    fn as_u8(self) -> u8 {\n        match self {\n            Self::TcpConnect   => consts::SOCKS5_CMD_TCP_CONNECT,\n            Self::TcpBind      => consts::SOCKS5_CMD_TCP_BIND,\n            Self::UdpAssociate => consts::SOCKS5_CMD_UDP_ASSOCIATE,\n        }\n    }\n\n    #[inline]\n    #[rustfmt::skip]\n    fn from_u8(code: u8) -> Option<Self> {\n        match code {\n            consts::SOCKS5_CMD_TCP_CONNECT   => Some(Self::TcpConnect),\n            consts::SOCKS5_CMD_TCP_BIND      => Some(Self::TcpBind),\n            consts::SOCKS5_CMD_UDP_ASSOCIATE => Some(Self::UdpAssociate),\n            _                                => None,\n        }\n    }\n}\n\n/// SOCKS5 reply code\n#[derive(Clone, Debug, Copy)]\npub enum Reply {\n    Succeeded,\n    GeneralFailure,\n    ConnectionNotAllowed,\n    NetworkUnreachable,\n    HostUnreachable,\n    ConnectionRefused,\n    TtlExpired,\n    CommandNotSupported,\n    AddressTypeNotSupported,\n\n    OtherReply(u8),\n}\n\nimpl Reply {\n    #[inline]\n    #[rustfmt::skip]\n    pub fn as_u8(self) -> u8 {\n        match self {\n            Self::Succeeded               => consts::SOCKS5_REPLY_SUCCEEDED,\n            Self::GeneralFailure          => consts::SOCKS5_REPLY_GENERAL_FAILURE,\n            Self::ConnectionNotAllowed    => consts::SOCKS5_REPLY_CONNECTION_NOT_ALLOWED,\n            Self::NetworkUnreachable      => consts::SOCKS5_REPLY_NETWORK_UNREACHABLE,\n            Self::HostUnreachable         => consts::SOCKS5_REPLY_HOST_UNREACHABLE,\n            Self::ConnectionRefused       => consts::SOCKS5_REPLY_CONNECTION_REFUSED,\n            Self::TtlExpired              => consts::SOCKS5_REPLY_TTL_EXPIRED,\n            Self::CommandNotSupported     => consts::SOCKS5_REPLY_COMMAND_NOT_SUPPORTED,\n            Self::AddressTypeNotSupported => consts::SOCKS5_REPLY_ADDRESS_TYPE_NOT_SUPPORTED,\n            Self::OtherReply(c)           => c,\n        }\n    }\n\n    #[inline]\n    #[rustfmt::skip]\n    pub fn from_u8(code: u8) -> Self {\n        match code {\n            consts::SOCKS5_REPLY_SUCCEEDED                  => Self::Succeeded,\n            consts::SOCKS5_REPLY_GENERAL_FAILURE            => Self::GeneralFailure,\n            consts::SOCKS5_REPLY_CONNECTION_NOT_ALLOWED     => Self::ConnectionNotAllowed,\n            consts::SOCKS5_REPLY_NETWORK_UNREACHABLE        => Self::NetworkUnreachable,\n            consts::SOCKS5_REPLY_HOST_UNREACHABLE           => Self::HostUnreachable,\n            consts::SOCKS5_REPLY_CONNECTION_REFUSED         => Self::ConnectionRefused,\n            consts::SOCKS5_REPLY_TTL_EXPIRED                => Self::TtlExpired,\n            consts::SOCKS5_REPLY_COMMAND_NOT_SUPPORTED      => Self::CommandNotSupported,\n            consts::SOCKS5_REPLY_ADDRESS_TYPE_NOT_SUPPORTED => Self::AddressTypeNotSupported,\n            _                                               => Self::OtherReply(code),\n        }\n    }\n}\n\nimpl fmt::Display for Reply {\n    #[rustfmt::skip]\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        match *self {\n            Self::Succeeded               => write!(f, \"Succeeded\"),\n            Self::AddressTypeNotSupported => write!(f, \"Address type not supported\"),\n            Self::CommandNotSupported     => write!(f, \"Command not supported\"),\n            Self::ConnectionNotAllowed    => write!(f, \"Connection not allowed\"),\n            Self::ConnectionRefused       => write!(f, \"Connection refused\"),\n            Self::GeneralFailure          => write!(f, \"General failure\"),\n            Self::HostUnreachable         => write!(f, \"Host unreachable\"),\n            Self::NetworkUnreachable      => write!(f, \"Network unreachable\"),\n            Self::OtherReply(u)           => write!(f, \"Other reply ({u})\"),\n            Self::TtlExpired              => write!(f, \"TTL expired\"),\n        }\n    }\n}\n\n/// SOCKS5 protocol error\n#[derive(Debug, thiserror::Error)]\npub enum Error {\n    #[error(\"{0}\")]\n    IoError(#[from] io::Error),\n    #[error(\"address type {0:#x} not supported\")]\n    AddressTypeNotSupported(u8),\n    #[error(\"address domain name must be UTF-8 encoding\")]\n    AddressDomainInvalidEncoding,\n    #[error(\"unsupported socks version {0:#x}\")]\n    UnsupportedSocksVersion(u8),\n    #[error(\"unsupported command {0:#x}\")]\n    UnsupportedCommand(u8),\n    #[error(\"unsupported username/password authentication version {0:#x}\")]\n    UnsupportedPasswdAuthVersion(u8),\n    #[error(\"username/password authentication invalid request\")]\n    PasswdAuthInvalidRequest,\n    #[error(\"{0}\")]\n    Reply(Reply),\n}\n\nimpl From<Error> for io::Error {\n    fn from(err: Error) -> Self {\n        match err {\n            Error::IoError(err) => err,\n            e => Self::other(e),\n        }\n    }\n}\n\nimpl Error {\n    /// Convert to `Reply` for responding\n    pub fn as_reply(&self) -> Reply {\n        match *self {\n            Self::IoError(ref err) => match err.kind() {\n                ErrorKind::ConnectionRefused => Reply::ConnectionRefused,\n                _ => Reply::GeneralFailure,\n            },\n            Self::AddressTypeNotSupported(..) => Reply::AddressTypeNotSupported,\n            Self::AddressDomainInvalidEncoding => Reply::GeneralFailure,\n            Self::UnsupportedSocksVersion(..) => Reply::GeneralFailure,\n            Self::UnsupportedCommand(..) => Reply::CommandNotSupported,\n            Self::UnsupportedPasswdAuthVersion(..) => Reply::GeneralFailure,\n            Self::PasswdAuthInvalidRequest => Reply::GeneralFailure,\n            Self::Reply(r) => r,\n        }\n    }\n}\n\n/// SOCKS5 address type\n#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]\npub enum Address {\n    /// Socket address (IP Address)\n    SocketAddress(SocketAddr),\n    /// Domain name address\n    DomainNameAddress(String, u16),\n}\n\nimpl Address {\n    /// read from a cursor\n    pub fn read_cursor<T: AsRef<[u8]>>(cur: &mut io::Cursor<T>) -> Result<Self, Error> {\n        if cur.remaining() < 2 {\n            return Err(io::Error::other(\"invalid buf\").into());\n        }\n\n        let atyp = cur.get_u8();\n        match atyp {\n            consts::SOCKS5_ADDR_TYPE_IPV4 => {\n                if cur.remaining() < 4 + 2 {\n                    return Err(io::Error::other(\"invalid buf\").into());\n                }\n                let addr = Ipv4Addr::from(cur.get_u32());\n                let port = cur.get_u16();\n                Ok(Self::SocketAddress(SocketAddr::V4(SocketAddrV4::new(addr, port))))\n            }\n            consts::SOCKS5_ADDR_TYPE_IPV6 => {\n                if cur.remaining() < 16 + 2 {\n                    return Err(io::Error::other(\"invalid buf\").into());\n                }\n                let addr = Ipv6Addr::from(cur.get_u128());\n                let port = cur.get_u16();\n                Ok(Self::SocketAddress(SocketAddr::V6(SocketAddrV6::new(addr, port, 0, 0))))\n            }\n            consts::SOCKS5_ADDR_TYPE_DOMAIN_NAME => {\n                let domain_len = cur.get_u8() as usize;\n                if cur.remaining() < domain_len {\n                    return Err(Error::AddressDomainInvalidEncoding);\n                }\n                let mut buf = vec![0u8; domain_len];\n                cur.copy_to_slice(&mut buf);\n                let port = cur.get_u16();\n                let addr = String::from_utf8(buf).map_err(|_| Error::AddressDomainInvalidEncoding)?;\n                Ok(Self::DomainNameAddress(addr, port))\n            }\n            _ => Err(Error::AddressTypeNotSupported(atyp)),\n        }\n    }\n\n    /// Parse from a `AsyncRead`\n    pub async fn read_from<R>(stream: &mut R) -> Result<Self, Error>\n    where\n        R: AsyncRead + Unpin,\n    {\n        let mut addr_type_buf = [0u8; 1];\n        let _ = stream.read_exact(&mut addr_type_buf).await?;\n\n        let addr_type = addr_type_buf[0];\n        match addr_type {\n            consts::SOCKS5_ADDR_TYPE_IPV4 => {\n                let mut buf = [0u8; 6];\n                let _ = stream.read_exact(&mut buf).await?;\n\n                let v4addr = Ipv4Addr::new(buf[0], buf[1], buf[2], buf[3]);\n                let port = u16::from_be_bytes([buf[4], buf[5]]);\n                Ok(Self::SocketAddress(SocketAddr::V4(SocketAddrV4::new(v4addr, port))))\n            }\n            consts::SOCKS5_ADDR_TYPE_IPV6 => {\n                let mut buf = [0u16; 9];\n\n                let bytes_buf = unsafe { slice::from_raw_parts_mut(buf.as_mut_ptr() as *mut _, 18) };\n                let _ = stream.read_exact(bytes_buf).await?;\n\n                let v6addr = Ipv6Addr::new(\n                    u16::from_be(buf[0]),\n                    u16::from_be(buf[1]),\n                    u16::from_be(buf[2]),\n                    u16::from_be(buf[3]),\n                    u16::from_be(buf[4]),\n                    u16::from_be(buf[5]),\n                    u16::from_be(buf[6]),\n                    u16::from_be(buf[7]),\n                );\n                let port = u16::from_be(buf[8]);\n\n                Ok(Self::SocketAddress(SocketAddr::V6(SocketAddrV6::new(\n                    v6addr, port, 0, 0,\n                ))))\n            }\n            consts::SOCKS5_ADDR_TYPE_DOMAIN_NAME => {\n                let mut length_buf = [0u8; 1];\n                let _ = stream.read_exact(&mut length_buf).await?;\n                let length = length_buf[0] as usize;\n\n                // Len(Domain) + Len(Port)\n                let buf_length = length + 2;\n\n                let mut raw_addr = vec![0u8; buf_length];\n                let _ = stream.read_exact(&mut raw_addr).await?;\n\n                let raw_port = &raw_addr[length..];\n                let port = u16::from_be_bytes([raw_port[0], raw_port[1]]);\n\n                raw_addr.truncate(length);\n\n                let addr = match String::from_utf8(raw_addr) {\n                    Ok(addr) => addr,\n                    Err(..) => return Err(Error::AddressDomainInvalidEncoding),\n                };\n\n                Ok(Self::DomainNameAddress(addr, port))\n            }\n            _ => {\n                // Wrong Address Type . Socks5 only supports ipv4, ipv6 and domain name\n                Err(Error::AddressTypeNotSupported(addr_type))\n            }\n        }\n    }\n\n    /// Writes to writer\n    #[inline]\n    pub async fn write_to<W>(&self, writer: &mut W) -> io::Result<()>\n    where\n        W: AsyncWrite + Unpin,\n    {\n        let mut buf = BytesMut::with_capacity(self.serialized_len());\n        self.write_to_buf(&mut buf);\n        writer.write_all(&buf).await\n    }\n\n    /// Writes to buffer\n    #[inline]\n    pub fn write_to_buf<B: BufMut>(&self, buf: &mut B) {\n        write_address(self, buf)\n    }\n\n    /// Get required buffer size for serializing\n    #[inline]\n    pub fn serialized_len(&self) -> usize {\n        get_addr_len(self)\n    }\n\n    /// Get maximum required buffer size for serializing\n    #[inline]\n    pub fn max_serialized_len() -> usize {\n        1 // ADDR_TYPE\n        + 1 // DOMAIN LENGTH\n        + u8::MAX as usize // MAX DOMAIN\n        + 2 // PORT\n    }\n\n    /// Get associated port number\n    pub fn port(&self) -> u16 {\n        match *self {\n            Self::SocketAddress(addr) => addr.port(),\n            Self::DomainNameAddress(.., port) => port,\n        }\n    }\n\n    /// Get host address string\n    pub fn host(&self) -> String {\n        match *self {\n            Self::SocketAddress(ref addr) => addr.ip().to_string(),\n            Self::DomainNameAddress(ref domain, ..) => domain.to_owned(),\n        }\n    }\n}\n\nimpl Debug for Address {\n    #[inline]\n    fn fmt(&self, f: &mut Formatter) -> fmt::Result {\n        match *self {\n            Self::SocketAddress(ref addr) => write!(f, \"{addr}\"),\n            Self::DomainNameAddress(ref addr, ref port) => write!(f, \"{addr}:{port}\"),\n        }\n    }\n}\n\nimpl fmt::Display for Address {\n    #[inline]\n    fn fmt(&self, f: &mut Formatter) -> fmt::Result {\n        match *self {\n            Self::SocketAddress(ref addr) => write!(f, \"{addr}\"),\n            Self::DomainNameAddress(ref addr, ref port) => write!(f, \"{addr}:{port}\"),\n        }\n    }\n}\n\nimpl ToSocketAddrs for Address {\n    type Iter = vec::IntoIter<SocketAddr>;\n\n    fn to_socket_addrs(&self) -> io::Result<vec::IntoIter<SocketAddr>> {\n        match self.clone() {\n            Self::SocketAddress(addr) => Ok(vec![addr].into_iter()),\n            Self::DomainNameAddress(addr, port) => (&addr[..], port).to_socket_addrs(),\n        }\n    }\n}\n\nimpl From<SocketAddr> for Address {\n    fn from(s: SocketAddr) -> Self {\n        Self::SocketAddress(s)\n    }\n}\n\nimpl From<(String, u16)> for Address {\n    fn from((dn, port): (String, u16)) -> Self {\n        Self::DomainNameAddress(dn, port)\n    }\n}\n\nimpl From<&Self> for Address {\n    fn from(addr: &Self) -> Self {\n        addr.clone()\n    }\n}\n\n/// Parse `Address` error\n#[derive(Debug)]\npub struct AddressError;\n\nimpl Display for AddressError {\n    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {\n        f.write_str(\"invalid Address\")\n    }\n}\n\nimpl std::error::Error for AddressError {}\n\nimpl FromStr for Address {\n    type Err = AddressError;\n\n    fn from_str(s: &str) -> Result<Self, AddressError> {\n        match s.parse::<SocketAddr>() {\n            Ok(addr) => Ok(Self::SocketAddress(addr)),\n            Err(..) => {\n                let mut sp = s.split(':');\n                match (sp.next(), sp.next()) {\n                    (Some(dn), Some(port)) => match port.parse::<u16>() {\n                        Ok(port) => Ok(Self::DomainNameAddress(dn.to_owned(), port)),\n                        Err(..) => Err(AddressError),\n                    },\n                    (Some(dn), None) => {\n                        // Assume it is 80 (http's default port)\n                        Ok(Self::DomainNameAddress(dn.to_owned(), 80))\n                    }\n                    _ => Err(AddressError),\n                }\n            }\n        }\n    }\n}\n\nfn write_ipv4_address<B: BufMut>(addr: &SocketAddrV4, buf: &mut B) {\n    buf.put_u8(consts::SOCKS5_ADDR_TYPE_IPV4); // Address type\n    buf.put_slice(&addr.ip().octets()); // Ipv4 bytes\n    buf.put_u16(addr.port()); // Port\n}\n\nfn write_ipv6_address<B: BufMut>(addr: &SocketAddrV6, buf: &mut B) {\n    buf.put_u8(consts::SOCKS5_ADDR_TYPE_IPV6); // Address type\n    for seg in &addr.ip().segments() {\n        buf.put_u16(*seg); // Ipv6 bytes\n    }\n    buf.put_u16(addr.port()); // Port\n}\n\nfn write_domain_name_address<B: BufMut>(dnaddr: &str, port: u16, buf: &mut B) {\n    assert!(dnaddr.len() <= u8::MAX as usize);\n\n    buf.put_u8(consts::SOCKS5_ADDR_TYPE_DOMAIN_NAME);\n    assert!(\n        dnaddr.len() <= u8::MAX as usize,\n        \"domain name length must be smaller than 256\"\n    );\n    buf.put_u8(dnaddr.len() as u8);\n    buf.put_slice(dnaddr.as_bytes());\n    buf.put_u16(port);\n}\n\nfn write_socket_address<B: BufMut>(addr: &SocketAddr, buf: &mut B) {\n    match *addr {\n        SocketAddr::V4(ref addr) => write_ipv4_address(addr, buf),\n        SocketAddr::V6(ref addr) => write_ipv6_address(addr, buf),\n    }\n}\n\nfn write_address<B: BufMut>(addr: &Address, buf: &mut B) {\n    match *addr {\n        Address::SocketAddress(ref addr) => write_socket_address(addr, buf),\n        Address::DomainNameAddress(ref dnaddr, ref port) => write_domain_name_address(dnaddr, *port, buf),\n    }\n}\n\n#[inline]\nfn get_addr_len(atyp: &Address) -> usize {\n    match *atyp {\n        Address::SocketAddress(SocketAddr::V4(..)) => 1 + 4 + 2,\n        Address::SocketAddress(SocketAddr::V6(..)) => 1 + 8 * 2 + 2,\n        Address::DomainNameAddress(ref dmname, _) => 1 + 1 + dmname.len() + 2,\n    }\n}\n\n/// TCP request header after handshake\n///\n/// ```plain\n/// +----+-----+-------+------+----------+----------+\n/// |VER | CMD |  RSV  | ATYP | DST.ADDR | DST.PORT |\n/// +----+-----+-------+------+----------+----------+\n/// | 1  |  1  | X'00' |  1   | Variable |    2     |\n/// +----+-----+-------+------+----------+----------+\n/// ```\n#[derive(Clone, Debug)]\npub struct TcpRequestHeader {\n    /// SOCKS5 command\n    pub command: Command,\n    /// Remote address\n    pub address: Address,\n}\n\nimpl TcpRequestHeader {\n    /// Creates a request header\n    pub fn new(cmd: Command, addr: Address) -> Self {\n        Self {\n            command: cmd,\n            address: addr,\n        }\n    }\n\n    /// Read from a reader\n    pub async fn read_from<R>(r: &mut R) -> Result<Self, Error>\n    where\n        R: AsyncRead + Unpin,\n    {\n        let mut buf = [0u8; 3];\n        let _ = r.read_exact(&mut buf).await?;\n\n        let ver = buf[0];\n        if ver != consts::SOCKS5_VERSION {\n            return Err(Error::UnsupportedSocksVersion(ver));\n        }\n\n        let cmd = buf[1];\n        let command = match Command::from_u8(cmd) {\n            Some(c) => c,\n            None => return Err(Error::UnsupportedCommand(cmd)),\n        };\n\n        let address = Address::read_from(r).await?;\n        Ok(Self { command, address })\n    }\n\n    /// Write data into a writer\n    pub async fn write_to<W>(&self, w: &mut W) -> io::Result<()>\n    where\n        W: AsyncWrite + Unpin,\n    {\n        let mut buf = BytesMut::with_capacity(self.serialized_len());\n        self.write_to_buf(&mut buf);\n        w.write_all(&buf).await\n    }\n\n    /// Writes to buffer\n    pub fn write_to_buf<B: BufMut>(&self, buf: &mut B) {\n        let Self {\n            ref address,\n            ref command,\n        } = *self;\n\n        buf.put_slice(&[consts::SOCKS5_VERSION, command.as_u8(), 0x00]);\n        address.write_to_buf(buf);\n    }\n\n    /// Length in bytes\n    #[inline]\n    pub fn serialized_len(&self) -> usize {\n        self.address.serialized_len() + 3\n    }\n}\n\n/// TCP response header\n///\n/// ```plain\n/// +----+-----+-------+------+----------+----------+\n/// |VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |\n/// +----+-----+-------+------+----------+----------+\n/// | 1  |  1  | X'00' |  1   | Variable |    2     |\n/// +----+-----+-------+------+----------+----------+\n/// ```\n#[derive(Clone, Debug)]\npub struct TcpResponseHeader {\n    /// SOCKS5 reply\n    pub reply: Reply,\n    /// Reply address\n    pub address: Address,\n}\n\nimpl TcpResponseHeader {\n    /// Creates a response header\n    pub fn new(reply: Reply, address: Address) -> Self {\n        Self { reply, address }\n    }\n\n    /// Read from a reader\n    pub async fn read_from<R>(r: &mut R) -> Result<Self, Error>\n    where\n        R: AsyncRead + Unpin,\n    {\n        let mut buf = [0u8; 3];\n        let _ = r.read_exact(&mut buf).await?;\n\n        let ver = buf[0];\n        let reply_code = buf[1];\n\n        if ver != consts::SOCKS5_VERSION {\n            return Err(Error::UnsupportedSocksVersion(ver));\n        }\n\n        let address = Address::read_from(r).await?;\n\n        Ok(Self {\n            reply: Reply::from_u8(reply_code),\n            address,\n        })\n    }\n\n    /// Write to a writer\n    pub async fn write_to<W>(&self, w: &mut W) -> io::Result<()>\n    where\n        W: AsyncWrite + Unpin,\n    {\n        let mut buf = BytesMut::with_capacity(self.serialized_len());\n        self.write_to_buf(&mut buf);\n        w.write_all(&buf).await\n    }\n\n    /// Writes to buffer\n    pub fn write_to_buf<B: BufMut>(&self, buf: &mut B) {\n        let Self { ref reply, ref address } = *self;\n        buf.put_slice(&[consts::SOCKS5_VERSION, reply.as_u8(), 0x00]);\n        address.write_to_buf(buf);\n    }\n\n    /// Length in bytes\n    #[inline]\n    pub fn serialized_len(&self) -> usize {\n        self.address.serialized_len() + 3\n    }\n}\n\n/// SOCKS5 handshake request packet\n///\n/// ```plain\n/// +----+----------+----------+\n/// |VER | NMETHODS | METHODS  |\n/// +----+----------+----------+\n/// | 5  |    1     | 1 to 255 |\n/// +----+----------+----------|\n/// ```\n#[derive(Clone, Debug)]\npub struct HandshakeRequest {\n    pub methods: Vec<u8>,\n}\n\nimpl HandshakeRequest {\n    /// Creates a handshake request\n    pub fn new(methods: Vec<u8>) -> Self {\n        Self { methods }\n    }\n\n    /// Read from a reader\n    pub async fn read_from<R>(r: &mut R) -> Result<Self, Error>\n    where\n        R: AsyncRead + Unpin,\n    {\n        let mut buf = [0u8; 2];\n        let _ = r.read_exact(&mut buf).await?;\n\n        let ver = buf[0];\n        let nmet = buf[1];\n\n        if ver != consts::SOCKS5_VERSION {\n            return Err(Error::UnsupportedSocksVersion(ver));\n        }\n\n        let mut methods = vec![0u8; nmet as usize];\n        let _ = r.read_exact(&mut methods).await?;\n\n        Ok(Self { methods })\n    }\n\n    /// Write to a writer\n    pub async fn write_to<W>(&self, w: &mut W) -> io::Result<()>\n    where\n        W: AsyncWrite + Unpin,\n    {\n        let mut buf = BytesMut::with_capacity(self.serialized_len());\n        self.write_to_buf(&mut buf);\n        w.write_all(&buf).await\n    }\n\n    /// Write to buffer\n    pub fn write_to_buf<B: BufMut>(&self, buf: &mut B) {\n        let Self { ref methods } = *self;\n        buf.put_slice(&[consts::SOCKS5_VERSION, methods.len() as u8]);\n        buf.put_slice(methods);\n    }\n\n    /// Get length of bytes\n    pub fn serialized_len(&self) -> usize {\n        2 + self.methods.len()\n    }\n}\n\n/// SOCKS5 handshake response packet\n///\n/// ```plain\n/// +----+--------+\n/// |VER | METHOD |\n/// +----+--------+\n/// | 1  |   1    |\n/// +----+--------+\n/// ```\n#[derive(Clone, Debug, Copy)]\npub struct HandshakeResponse {\n    pub chosen_method: u8,\n}\n\nimpl HandshakeResponse {\n    /// Creates a handshake response\n    pub fn new(cm: u8) -> Self {\n        Self { chosen_method: cm }\n    }\n\n    /// Read from a reader\n    pub async fn read_from<R>(r: &mut R) -> Result<Self, Error>\n    where\n        R: AsyncRead + Unpin,\n    {\n        let mut buf = [0u8; 2];\n        let _ = r.read_exact(&mut buf).await?;\n\n        let ver = buf[0];\n        let met = buf[1];\n\n        if ver != consts::SOCKS5_VERSION {\n            Err(Error::UnsupportedSocksVersion(ver))\n        } else {\n            Ok(Self { chosen_method: met })\n        }\n    }\n\n    /// Write to a writer\n    pub async fn write_to<W>(self, w: &mut W) -> io::Result<()>\n    where\n        W: AsyncWrite + Unpin,\n    {\n        let mut buf = BytesMut::with_capacity(self.serialized_len());\n        self.write_to_buf(&mut buf);\n        w.write_all(&buf).await\n    }\n\n    /// Write to buffer\n    pub fn write_to_buf<B: BufMut>(self, buf: &mut B) {\n        buf.put_slice(&[consts::SOCKS5_VERSION, self.chosen_method]);\n    }\n\n    /// Length in bytes\n    pub fn serialized_len(self) -> usize {\n        2\n    }\n}\n\n/// UDP ASSOCIATE request header\n///\n/// ```plain\n/// +----+------+------+----------+----------+----------+\n/// |RSV | FRAG | ATYP | DST.ADDR | DST.PORT |   DATA   |\n/// +----+------+------+----------+----------+----------+\n/// | 2  |  1   |  1   | Variable |    2     | Variable |\n/// +----+------+------+----------+----------+----------+\n/// ```\n#[derive(Clone, Debug)]\npub struct UdpAssociateHeader {\n    /// Fragment\n    ///\n    /// ShadowSocks does not support fragment, so this frag must be 0x00\n    pub frag: u8,\n    /// Remote address\n    pub address: Address,\n}\n\nimpl UdpAssociateHeader {\n    /// Creates a header\n    pub fn new(frag: u8, address: Address) -> Self {\n        Self { frag, address }\n    }\n\n    /// Read from a reader\n    pub async fn read_from<R>(r: &mut R) -> Result<Self, Error>\n    where\n        R: AsyncRead + Unpin,\n    {\n        let mut buf = [0u8; 3];\n        let _ = r.read_exact(&mut buf).await?;\n\n        let frag = buf[2];\n        let address = Address::read_from(r).await?;\n        Ok(Self::new(frag, address))\n    }\n\n    /// Write to a writer\n    pub async fn write_to<W>(&self, w: &mut W) -> io::Result<()>\n    where\n        W: AsyncWrite + Unpin,\n    {\n        let mut buf = BytesMut::with_capacity(self.serialized_len());\n        self.write_to_buf(&mut buf);\n        w.write_all(&buf).await\n    }\n\n    /// Write to buffer\n    pub fn write_to_buf<B: BufMut>(&self, buf: &mut B) {\n        let Self { ref frag, ref address } = *self;\n        buf.put_slice(&[0x00, 0x00, *frag]);\n        address.write_to_buf(buf);\n    }\n\n    /// Length in bytes\n    #[inline]\n    pub fn serialized_len(&self) -> usize {\n        3 + self.address.serialized_len()\n    }\n}\n\n/// Username/Password Authentication Initial Negotiation\n///\n/// https://datatracker.ietf.org/doc/html/rfc1929\n///\n/// ```plain\n/// +----+------+----------+------+----------+\n/// |VER | ULEN |  UNAME   | PLEN |  PASSWD  |\n/// +----+------+----------+------+----------+\n/// | 1  |  1   | 1 to 255 |  1   | 1 to 255 |\n/// +----+------+----------+------+----------+\n/// ```\npub struct PasswdAuthRequest {\n    pub uname: Vec<u8>,\n    pub passwd: Vec<u8>,\n}\n\nimpl PasswdAuthRequest {\n    /// Create a Username/Password Authentication Request\n    pub fn new<U, P>(uname: U, passwd: P) -> Self\n    where\n        U: Into<Vec<u8>>,\n        P: Into<Vec<u8>>,\n    {\n        let uname = uname.into();\n        let passwd = passwd.into();\n        assert!(\n            !uname.is_empty()\n                && uname.len() <= u8::MAX as usize\n                && !passwd.is_empty()\n                && passwd.len() <= u8::MAX as usize\n        );\n\n        Self { uname, passwd }\n    }\n\n    /// Read from a reader\n    pub async fn read_from<R>(r: &mut R) -> Result<Self, Error>\n    where\n        R: AsyncRead + Unpin,\n    {\n        let mut ver_buf = [0u8; 1];\n        let _ = r.read_exact(&mut ver_buf).await?;\n\n        // The only valid subnegotiation version\n        if ver_buf[0] != 0x01 {\n            return Err(Error::UnsupportedPasswdAuthVersion(ver_buf[0]));\n        }\n\n        let mut ulen_buf = [0u8; 1];\n        let _ = r.read_exact(&mut ulen_buf).await?;\n\n        let ulen = ulen_buf[0] as usize;\n        if ulen == 0 {\n            return Err(Error::PasswdAuthInvalidRequest);\n        }\n\n        let mut uname = vec![0u8; ulen];\n        if ulen > 0 {\n            let _ = r.read_exact(&mut uname).await?;\n        }\n\n        let mut plen_buf = [0u8; 1];\n        let _ = r.read_exact(&mut plen_buf).await?;\n\n        let plen = plen_buf[0] as usize;\n        if plen == 0 {\n            return Err(Error::PasswdAuthInvalidRequest);\n        }\n\n        let mut passwd = vec![0u8; plen];\n        if plen > 0 {\n            let _ = r.read_exact(&mut passwd).await?;\n        }\n\n        Ok(Self { uname, passwd })\n    }\n\n    /// Write to a writer\n    pub async fn write_to<W>(&self, w: &mut W) -> io::Result<()>\n    where\n        W: AsyncWrite + Unpin,\n    {\n        let mut buf = BytesMut::with_capacity(self.serialized_len());\n        self.write_to_buf(&mut buf);\n        w.write_all(&buf).await\n    }\n\n    /// Write to buffer\n    fn write_to_buf<B: BufMut>(&self, buf: &mut B) {\n        buf.put_u8(0x01);\n        buf.put_u8(self.uname.len() as u8);\n        buf.put_slice(&self.uname);\n        buf.put_u8(self.passwd.len() as u8);\n        buf.put_slice(&self.passwd);\n    }\n\n    /// Length in bytes\n    #[inline]\n    pub fn serialized_len(&self) -> usize {\n        1 + 1 + self.uname.len() + 1 + self.passwd.len()\n    }\n}\n\npub struct PasswdAuthResponse {\n    pub status: u8,\n}\n\nimpl PasswdAuthResponse {\n    pub fn new(status: u8) -> Self {\n        Self { status }\n    }\n\n    /// Read from a reader\n    pub async fn read_from<R>(r: &mut R) -> Result<Self, Error>\n    where\n        R: AsyncRead + Unpin,\n    {\n        let mut buf = [0u8; 2];\n        let _ = r.read_exact(&mut buf).await;\n\n        if buf[0] != 0x01 {\n            return Err(Error::UnsupportedPasswdAuthVersion(buf[0]));\n        }\n\n        Ok(Self { status: buf[1] })\n    }\n\n    /// Write to a writer\n    pub async fn write_to<W>(&self, w: &mut W) -> io::Result<()>\n    where\n        W: AsyncWrite + Unpin,\n    {\n        let mut buf = BytesMut::with_capacity(self.serialized_len());\n        self.write_to_buf(&mut buf);\n        w.write_all(&buf).await\n    }\n\n    /// Write to buffer\n    fn write_to_buf<B: BufMut>(&self, buf: &mut B) {\n        buf.put_u8(0x01);\n        buf.put_u8(self.status);\n    }\n\n    /// Length in bytes\n    #[inline]\n    pub fn serialized_len(&self) -> usize {\n        2\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/relay/tcprelay/aead.rs",
    "content": "//! AEAD packet I/O facilities\n//!\n//! AEAD protocol is defined in <https://shadowsocks.org/doc/aead.html>.\n//!\n//! ```plain\n//! TCP request (before encryption)\n//! +------+---------------------+------------------+\n//! | ATYP | Destination Address | Destination Port |\n//! +------+---------------------+------------------+\n//! |  1   |       Variable      |         2        |\n//! +------+---------------------+------------------+\n//!\n//! TCP request (after encryption, *ciphertext*)\n//! +--------+--------------+------------------+--------------+---------------+\n//! | NONCE  |  *HeaderLen* |   HeaderLen_TAG  |   *Header*   |  Header_TAG   |\n//! +--------+--------------+------------------+--------------+---------------+\n//! | Fixed  |       2      |       Fixed      |   Variable   |     Fixed     |\n//! +--------+--------------+------------------+--------------+---------------+\n//!\n//! TCP Chunk (before encryption)\n//! +----------+\n//! |  DATA    |\n//! +----------+\n//! | Variable |\n//! +----------+\n//!\n//! TCP Chunk (after encryption, *ciphertext*)\n//! +--------------+---------------+--------------+------------+\n//! |  *DataLen*   |  DataLen_TAG  |    *Data*    |  Data_TAG  |\n//! +--------------+---------------+--------------+------------+\n//! |      2       |     Fixed     |   Variable   |   Fixed    |\n//! +--------------+---------------+--------------+------------+\n//! ```\nuse std::{\n    io::{self, ErrorKind},\n    marker::Unpin,\n    pin::Pin,\n    slice,\n    task::{self, Poll},\n};\n\nuse byte_string::ByteStr;\nuse bytes::{BufMut, Bytes, BytesMut};\nuse futures::ready;\nuse log::trace;\nuse tokio::io::{AsyncRead, AsyncWrite, ReadBuf};\n\nuse crate::{\n    context::Context,\n    crypto::{CipherKind, v1::Cipher},\n};\n\n/// AEAD packet payload must be smaller than 0x3FFF\npub const MAX_PACKET_SIZE: usize = 0x3FFF;\n\n/// AEAD Protocol Error\n#[derive(thiserror::Error, Debug)]\npub enum ProtocolError {\n    #[error(transparent)]\n    IoError(#[from] io::Error),\n    #[error(\"header too short, expecting {0} bytes, but found {1} bytes\")]\n    HeaderTooShort(usize, usize),\n    #[error(\"decrypt data failed\")]\n    DecryptDataError,\n    #[error(\"decrypt length failed\")]\n    DecryptLengthError,\n    #[error(\n        \"buffer size too large ({0:#x}), AEAD encryption protocol requires buffer to be smaller than 0x3FFF, the higher two bits must be set to zero\"\n    )]\n    DataTooLong(usize),\n}\n\n/// AEAD Protocol result\npub type ProtocolResult<T> = Result<T, ProtocolError>;\n\nimpl From<ProtocolError> for io::Error {\n    fn from(e: ProtocolError) -> Self {\n        match e {\n            ProtocolError::IoError(err) => err,\n            _ => Self::other(e),\n        }\n    }\n}\n\n#[derive(Debug)]\nenum DecryptReadState {\n    WaitSalt { key: Bytes },\n    ReadLength,\n    ReadData { length: usize },\n    BufferedData { pos: usize },\n}\n\n/// Reader wrapper that will decrypt data automatically\npub struct DecryptedReader {\n    state: DecryptReadState,\n    cipher: Option<Cipher>,\n    buffer: BytesMut,\n    method: CipherKind,\n    salt: Option<Bytes>,\n    has_handshaked: bool,\n}\n\nimpl DecryptedReader {\n    pub fn new(method: CipherKind, key: &[u8]) -> Self {\n        if method.salt_len() > 0 {\n            Self {\n                state: DecryptReadState::WaitSalt {\n                    key: Bytes::copy_from_slice(key),\n                },\n                cipher: None,\n                buffer: BytesMut::with_capacity(method.salt_len()),\n                method,\n                salt: None,\n                has_handshaked: false,\n            }\n        } else {\n            Self {\n                state: DecryptReadState::ReadLength,\n                cipher: Some(Cipher::new(method, key, &[])),\n                buffer: BytesMut::with_capacity(2 + method.tag_len()),\n                method,\n                salt: None,\n                has_handshaked: false,\n            }\n        }\n    }\n\n    pub fn salt(&self) -> Option<&[u8]> {\n        self.salt.as_deref()\n    }\n\n    /// Attempt to read decrypted data from stream\n    pub fn poll_read_decrypted<S>(\n        &mut self,\n        cx: &mut task::Context<'_>,\n        context: &Context,\n        stream: &mut S,\n        buf: &mut ReadBuf<'_>,\n    ) -> Poll<ProtocolResult<()>>\n    where\n        S: AsyncRead + Unpin + ?Sized,\n    {\n        loop {\n            match self.state {\n                DecryptReadState::WaitSalt { ref key } => {\n                    let key = unsafe { &*(key.as_ref() as *const _) };\n                    ready!(self.poll_read_salt(cx, stream, key))?;\n\n                    self.buffer.clear();\n                    self.state = DecryptReadState::ReadLength;\n                    self.buffer.reserve(2 + self.method.tag_len());\n                    self.has_handshaked = true;\n                }\n                DecryptReadState::ReadLength => match ready!(self.poll_read_length(cx, stream))? {\n                    None => {\n                        return Ok(()).into();\n                    }\n                    Some(length) => {\n                        self.buffer.clear();\n                        self.state = DecryptReadState::ReadData { length };\n                        self.buffer.reserve(length + self.method.tag_len());\n                    }\n                },\n                DecryptReadState::ReadData { length } => {\n                    ready!(self.poll_read_data(cx, context, stream, length))?;\n\n                    self.state = DecryptReadState::BufferedData { pos: 0 };\n                }\n                DecryptReadState::BufferedData { ref mut pos } => {\n                    if *pos < self.buffer.len() {\n                        let buffered = &self.buffer[*pos..];\n\n                        let consumed = usize::min(buffered.len(), buf.remaining());\n                        buf.put_slice(&buffered[..consumed]);\n\n                        *pos += consumed;\n\n                        return Ok(()).into();\n                    }\n\n                    self.buffer.clear();\n                    self.state = DecryptReadState::ReadLength;\n                    self.buffer.reserve(2 + self.method.tag_len());\n                }\n            }\n        }\n    }\n\n    fn poll_read_salt<S>(&mut self, cx: &mut task::Context<'_>, stream: &mut S, key: &[u8]) -> Poll<ProtocolResult<()>>\n    where\n        S: AsyncRead + Unpin + ?Sized,\n    {\n        let salt_len = self.method.salt_len();\n\n        let n = ready!(self.poll_read_exact(cx, stream, salt_len))?;\n        if n < salt_len {\n            return Err(io::Error::from(ErrorKind::UnexpectedEof).into()).into();\n        }\n\n        let salt = &self.buffer[..salt_len];\n        // #442 Remember salt in filter after first successful decryption.\n        //\n        // If we check salt right here will allow attacker to flood our filter and eventually block all of our legitimate clients' requests.\n        self.salt = Some(Bytes::copy_from_slice(salt));\n\n        trace!(\"got AEAD salt {:?}\", ByteStr::new(salt));\n\n        let cipher = Cipher::new(self.method, key, salt);\n\n        self.cipher = Some(cipher);\n\n        Ok(()).into()\n    }\n\n    fn poll_read_length<S>(&mut self, cx: &mut task::Context<'_>, stream: &mut S) -> Poll<ProtocolResult<Option<usize>>>\n    where\n        S: AsyncRead + Unpin + ?Sized,\n    {\n        let length_len = 2 + self.method.tag_len();\n\n        let n = ready!(self.poll_read_exact(cx, stream, length_len))?;\n        if n == 0 {\n            return Ok(None).into();\n        }\n\n        let cipher = self.cipher.as_mut().expect(\"cipher is None\");\n\n        let m = &mut self.buffer[..length_len];\n        let length = Self::decrypt_length(cipher, m)?;\n\n        Ok(Some(length)).into()\n    }\n\n    fn poll_read_data<S>(\n        &mut self,\n        cx: &mut task::Context<'_>,\n        context: &Context,\n        stream: &mut S,\n        size: usize,\n    ) -> Poll<ProtocolResult<()>>\n    where\n        S: AsyncRead + Unpin + ?Sized,\n    {\n        let data_len = size + self.method.tag_len();\n\n        let n = ready!(self.poll_read_exact(cx, stream, data_len))?;\n        if n == 0 {\n            return Err(io::Error::from(ErrorKind::UnexpectedEof).into()).into();\n        }\n\n        let cipher = self.cipher.as_mut().expect(\"cipher is None\");\n\n        let m = &mut self.buffer[..data_len];\n        if !cipher.decrypt_packet(m) {\n            return Err(ProtocolError::DecryptDataError).into();\n        }\n\n        // Check repeated salt after first successful decryption #442\n        if self.salt.is_some() {\n            let salt = self.salt.take().unwrap();\n            context.check_nonce_replay(self.method, &salt)?;\n        }\n\n        // Remote TAG\n        self.buffer.truncate(size);\n\n        Ok(()).into()\n    }\n\n    fn poll_read_exact<S>(&mut self, cx: &mut task::Context<'_>, stream: &mut S, size: usize) -> Poll<io::Result<usize>>\n    where\n        S: AsyncRead + Unpin + ?Sized,\n    {\n        assert!(size != 0);\n\n        while self.buffer.len() < size {\n            let remaining = size - self.buffer.len();\n            let buffer = &mut self.buffer.chunk_mut()[..remaining];\n\n            let mut read_buf =\n                ReadBuf::uninit(unsafe { slice::from_raw_parts_mut(buffer.as_mut_ptr() as *mut _, remaining) });\n            ready!(Pin::new(&mut *stream).poll_read(cx, &mut read_buf))?;\n\n            let n = read_buf.filled().len();\n            if n == 0 {\n                if !self.buffer.is_empty() {\n                    return Err(ErrorKind::UnexpectedEof.into()).into();\n                } else {\n                    return Ok(0).into();\n                }\n            }\n\n            unsafe {\n                self.buffer.advance_mut(n);\n            }\n        }\n\n        Ok(size).into()\n    }\n\n    fn decrypt_length(cipher: &mut Cipher, m: &mut [u8]) -> ProtocolResult<usize> {\n        let plen = {\n            if !cipher.decrypt_packet(m) {\n                return Err(ProtocolError::DecryptLengthError);\n            }\n\n            u16::from_be_bytes([m[0], m[1]]) as usize\n        };\n\n        if plen > MAX_PACKET_SIZE {\n            // https://shadowsocks.org/doc/aead.html\n            //\n            // AEAD TCP protocol have reserved the higher two bits for future use\n            return Err(ProtocolError::DataTooLong(plen));\n        }\n\n        Ok(plen)\n    }\n\n    /// Check if handshake finished\n    pub fn handshaked(&self) -> bool {\n        self.has_handshaked\n    }\n}\n\n#[derive(Debug)]\nenum EncryptWriteState {\n    AssemblePacket,\n    Writing { pos: usize },\n}\n\n/// Writer wrapper that will encrypt data automatically\npub struct EncryptedWriter {\n    cipher: Cipher,\n    buffer: BytesMut,\n    state: EncryptWriteState,\n    salt: Bytes,\n}\n\nimpl EncryptedWriter {\n    /// Creates a new EncryptedWriter\n    pub fn new(method: CipherKind, key: &[u8], nonce: &[u8]) -> Self {\n        // nonce should be sent with the first packet\n        let mut buffer = BytesMut::with_capacity(nonce.len());\n        buffer.put(nonce);\n\n        Self {\n            cipher: Cipher::new(method, key, nonce),\n            buffer,\n            state: EncryptWriteState::AssemblePacket,\n            salt: Bytes::copy_from_slice(nonce),\n        }\n    }\n\n    /// Salt (nonce)\n    pub fn salt(&self) -> &[u8] {\n        self.salt.as_ref()\n    }\n\n    /// Attempt to write encrypted data into the writer\n    pub fn poll_write_encrypted<S>(\n        &mut self,\n        cx: &mut task::Context<'_>,\n        stream: &mut S,\n        mut buf: &[u8],\n    ) -> Poll<io::Result<usize>>\n    where\n        S: AsyncWrite + Unpin + ?Sized,\n    {\n        if buf.len() > MAX_PACKET_SIZE {\n            buf = &buf[..MAX_PACKET_SIZE];\n        }\n\n        loop {\n            match self.state {\n                EncryptWriteState::AssemblePacket => {\n                    // Step 1. Append Length\n                    let length_size = 2 + self.cipher.tag_len();\n                    self.buffer.reserve(length_size);\n\n                    let mbuf = &mut self.buffer.chunk_mut()[..length_size];\n                    let mbuf = unsafe { slice::from_raw_parts_mut(mbuf.as_mut_ptr(), mbuf.len()) };\n\n                    self.buffer.put_u16(buf.len() as u16);\n                    self.cipher.encrypt_packet(mbuf);\n                    unsafe { self.buffer.advance_mut(self.cipher.tag_len()) };\n\n                    // Step 2. Append data\n                    let data_size = buf.len() + self.cipher.tag_len();\n                    self.buffer.reserve(data_size);\n\n                    let mbuf = &mut self.buffer.chunk_mut()[..data_size];\n                    let mbuf = unsafe { slice::from_raw_parts_mut(mbuf.as_mut_ptr(), mbuf.len()) };\n\n                    self.buffer.put_slice(buf);\n                    self.cipher.encrypt_packet(mbuf);\n                    unsafe { self.buffer.advance_mut(self.cipher.tag_len()) };\n\n                    // Step 3. Write all\n                    self.state = EncryptWriteState::Writing { pos: 0 };\n                }\n                EncryptWriteState::Writing { ref mut pos } => {\n                    while *pos < self.buffer.len() {\n                        let n = ready!(Pin::new(&mut *stream).poll_write(cx, &self.buffer[*pos..]))?;\n                        if n == 0 {\n                            return Err(ErrorKind::UnexpectedEof.into()).into();\n                        }\n                        *pos += n;\n                    }\n\n                    // Reset state\n                    self.state = EncryptWriteState::AssemblePacket;\n                    self.buffer.clear();\n\n                    return Ok(buf.len()).into();\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/relay/tcprelay/aead_2022.rs",
    "content": "//! AEAD 2022 packet I/O facilities\n//!\n//! ```plain\n//! TCP Header (before encryption)\n//!\n//! +--------+--------+--------+--------+--------+--------+--------+--------+--------+\n//! | TYPE   | TIMESTAMP (BE)                                                        |\n//! +--------+--------+--------+--------+--------+--------+--------+--------+--------+\n//! | ATYP   | ADDRESS ... (Variable Length ...)\n//! +--------+--------+--------+--------+--------+--------+--------+--------+--------+\n//! | PORT (BE)       | Padding Length  | Padding (Variable Length ...)\n//! +--------+--------+--------+--------+--------+--------+--------+--------+--------+\n//!\n//! TCP Request Header (after encryption, *ciphertext*)\n//!\n//! +--------+--------+--------+--------+--------+--------+--------+--------+\n//! | SALT (Variable Length ...)\n//! +--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+\n//! | AEAD (TYPE + TIMESTAMP + HEADER_LENGTH)                                                          |\n//! +--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+\n//! | AEAD (ATYP + ADDRESS + PORT + PADDING_LENGTH + PADDING)\n//! +--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+\n//!\n//! TCP Respond Header (after encryption, *ciphertext*)\n//!\n//! +--------+--------+--------+--------+--------+--------+--------+--------+\n//! | SALT (Variable Length ...)\n//! +--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+\n//! | AEAD (TYPE + TIMESTAMP + REQUEST_SALT + DATA_LENGTH)\n//! +--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+\n//!\n//! TCP Chunk (before encryption)\n//! +----------+\n//! |  DATA    |\n//! +----------+\n//! | Variable |\n//! +----------+\n//!\n//! TCP Chunk (after encryption, *ciphertext*)\n//! +--------------+---------------+--------------+------------+\n//! |  *DataLen*   |  DataLen_TAG  |    *Data*    |  Data_TAG  |\n//! +--------------+---------------+--------------+------------+\n//! |      2       |     Fixed     |   Variable   |   Fixed    |\n//! +--------------+---------------+--------------+------------+\n//! ```\nuse std::{\n    io::{self, Cursor, ErrorKind, Read},\n    marker::Unpin,\n    pin::Pin,\n    slice,\n    sync::Arc,\n    task::{self, Poll},\n    time::SystemTime,\n};\n\nuse aes::{\n    Aes128, Aes256, Block,\n    cipher::{BlockDecrypt, BlockEncrypt, KeyInit},\n};\nuse byte_string::ByteStr;\nuse bytes::{Buf, BufMut, Bytes, BytesMut};\nuse futures::ready;\nuse log::{error, trace};\nuse tokio::io::{AsyncRead, AsyncWrite, ReadBuf};\n\nuse super::{crypto_io::StreamType, proxy_stream::protocol::v2::SERVER_STREAM_TIMESTAMP_MAX_DIFF};\nuse crate::{\n    config::{ServerUserManager, method_support_eih},\n    context::Context,\n    crypto::{CipherKind, v2::tcp::TcpCipher},\n};\n\n#[inline]\nfn get_now_timestamp() -> u64 {\n    match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) {\n        Ok(n) => n.as_secs(),\n        Err(_) => panic!(\"SystemTime::now() is before UNIX Epoch!\"),\n    }\n}\n\n/// AEAD packet payload must be smaller than 0xFFFF (u16::MAX)\npub const MAX_PACKET_SIZE: usize = 0xFFFF;\n\nconst AEAD2022_EIH_SUBKEY_CONTEXT: &str = \"shadowsocks 2022 identity subkey\";\n\n/// AEAD 2022 Protocol Error\n#[derive(thiserror::Error, Debug)]\npub enum ProtocolError {\n    #[error(transparent)]\n    IoError(#[from] io::Error),\n    #[error(\"header too short, expecting {0} bytes, but found {1} bytes\")]\n    HeaderTooShort(usize, usize),\n    #[error(\"missing extended identity header\")]\n    MissingExtendedIdentityHeader,\n    #[error(\"invalid client user identity {:?}\", ByteStr::new(.0))]\n    InvalidClientUser(Bytes),\n    #[error(\"decrypt header chunk failed\")]\n    DecryptHeaderChunkError,\n    #[error(\"decrypt data failed\")]\n    DecryptDataError,\n    #[error(\"decrypt length failed\")]\n    DecryptLengthError,\n    #[error(\"invalid stream type, expecting {0:#x}, but found {1:#x}\")]\n    InvalidStreamType(u8, u8),\n    #[error(\"invalid timestamp {0} - now {1} = {ts_diff}\", ts_diff = *.0 as i64 - *.1 as i64)]\n    InvalidTimestamp(u64, u64),\n}\n\n/// AEAD 2022 Protocol result\npub type ProtocolResult<T> = Result<T, ProtocolError>;\n\nimpl From<ProtocolError> for io::Error {\n    fn from(e: ProtocolError) -> Self {\n        match e {\n            ProtocolError::IoError(err) => err,\n            _ => Self::other(e),\n        }\n    }\n}\n\nenum DecryptReadState {\n    ReadHeader { key: Bytes },\n    ReadLength,\n    ReadData { length: usize },\n    BufferedData { pos: usize },\n}\n\n/// Reader wrapper that will decrypt data automatically\npub struct DecryptedReader {\n    stream_ty: StreamType,\n    state: DecryptReadState,\n    cipher: Option<TcpCipher>,\n    buffer: BytesMut,\n    method: CipherKind,\n    salt: Option<Bytes>,\n    request_salt: Option<Bytes>,\n    data_chunk_count: u64,\n    user_manager: Option<Arc<ServerUserManager>>,\n    user_key: Option<Bytes>,\n    has_handshaked: bool,\n}\n\nimpl DecryptedReader {\n    pub fn new(stream_ty: StreamType, method: CipherKind, key: &[u8]) -> Self {\n        Self::with_user_manager(stream_ty, method, key, None)\n    }\n\n    pub fn with_user_manager(\n        stream_ty: StreamType,\n        method: CipherKind,\n        key: &[u8],\n        user_manager: Option<Arc<ServerUserManager>>,\n    ) -> Self {\n        if method.salt_len() > 0 {\n            Self {\n                stream_ty,\n                state: DecryptReadState::ReadHeader {\n                    key: Bytes::copy_from_slice(key),\n                },\n                cipher: None,\n                buffer: BytesMut::new(),\n                method,\n                salt: None,\n                request_salt: None,\n                data_chunk_count: 0,\n                user_manager,\n                user_key: None,\n                has_handshaked: false,\n            }\n        } else {\n            Self {\n                stream_ty,\n                state: DecryptReadState::ReadHeader {\n                    key: Bytes::new(), // EMPTY SALT, no allocation\n                },\n                cipher: Some(TcpCipher::new(method, key, &[])),\n                buffer: BytesMut::new(),\n                method,\n                salt: None,\n                request_salt: None,\n                data_chunk_count: 0,\n                user_manager,\n                user_key: None,\n                has_handshaked: false,\n            }\n        }\n    }\n\n    pub fn salt(&self) -> Option<&[u8]> {\n        self.salt.as_deref()\n    }\n\n    pub fn request_salt(&self) -> Option<&[u8]> {\n        self.request_salt.as_deref().filter(|&n| !n.is_empty())\n    }\n\n    /// Attempt to read decrypted data from stream\n    pub fn poll_read_decrypted<S>(\n        &mut self,\n        cx: &mut task::Context<'_>,\n        context: &Context,\n        stream: &mut S,\n        buf: &mut ReadBuf<'_>,\n    ) -> Poll<ProtocolResult<()>>\n    where\n        S: AsyncRead + Unpin + ?Sized,\n    {\n        loop {\n            match self.state {\n                DecryptReadState::ReadHeader { ref key } => {\n                    let key = unsafe { &*(key.as_ref() as *const _) };\n                    match ready!(self.poll_read_header(cx, context, stream, key))? {\n                        None => {\n                            return Ok(()).into();\n                        }\n                        Some(length) => {\n                            self.buffer.clear();\n                            self.state = DecryptReadState::ReadData { length };\n                            self.buffer.reserve(length + self.method.tag_len());\n                            self.has_handshaked = true;\n                        }\n                    }\n                }\n                DecryptReadState::ReadLength => match ready!(self.poll_read_length(cx, stream))? {\n                    None => {\n                        return Ok(()).into();\n                    }\n                    Some(length) => {\n                        self.buffer.clear();\n                        self.state = DecryptReadState::ReadData { length };\n                        self.buffer.reserve(length + self.method.tag_len());\n                    }\n                },\n                DecryptReadState::ReadData { length } => {\n                    ready!(self.poll_read_data(cx, stream, length))?;\n\n                    self.state = DecryptReadState::BufferedData { pos: 0 };\n                    self.data_chunk_count = self.data_chunk_count.wrapping_add(1);\n                }\n                DecryptReadState::BufferedData { ref mut pos } => {\n                    if *pos < self.buffer.len() {\n                        let buffered = &self.buffer[*pos..];\n\n                        let consumed = usize::min(buffered.len(), buf.remaining());\n                        buf.put_slice(&buffered[..consumed]);\n\n                        *pos += consumed;\n\n                        return Ok(()).into();\n                    }\n\n                    self.buffer.clear();\n                    self.state = DecryptReadState::ReadLength;\n                    self.buffer.reserve(2 + self.method.tag_len());\n                }\n            }\n        }\n    }\n\n    fn poll_read_header<S>(\n        &mut self,\n        cx: &mut task::Context<'_>,\n        context: &Context,\n        stream: &mut S,\n        key: &[u8],\n    ) -> Poll<ProtocolResult<Option<usize>>>\n    where\n        S: AsyncRead + Unpin + ?Sized,\n    {\n        let salt_len = self.method.salt_len();\n\n        // Header chunk, SALE + AEAD(TYPE + TIMESTAMP [+ REQUEST_SALT] + LENGTH) must be read in one call\n        let request_salt_len = match self.stream_ty {\n            StreamType::Client => salt_len,\n            StreamType::Server => 0,\n        };\n        let require_eih =\n            self.stream_ty == StreamType::Server && method_support_eih(self.method) && self.user_manager.is_some();\n        let eih_len = if require_eih { 16 } else { 0 };\n        let header_len = salt_len + eih_len + 1 + 8 + request_salt_len + 2 + self.method.tag_len();\n        if self.buffer.len() < header_len {\n            self.buffer.resize(header_len, 0);\n        }\n        let mut read_buf = ReadBuf::new(&mut self.buffer[..header_len]);\n        ready!(Pin::new(stream).poll_read(cx, &mut read_buf))?;\n        let header_buf = read_buf.filled_mut();\n        if header_buf.is_empty() {\n            // EOF.\n            return Ok(None).into();\n        } else if header_buf.len() != header_len {\n            return Err(ProtocolError::HeaderTooShort(header_len, header_buf.len())).into();\n        }\n\n        let (salt, mut header_chunk) = header_buf.split_at_mut(salt_len);\n\n        trace!(\"got AEAD salt {:?}\", ByteStr::new(salt));\n\n        // Extensible Identity Header\n        // https://github.com/Shadowsocks-NET/shadowsocks-specs/blob/main/2022-2-shadowsocks-2022-extensible-identity-headers.md\n        let mut cipher = if require_eih {\n            match self.user_manager {\n                Some(ref user_manager) => {\n                    // Assume we have at least 1 EIH\n                    if header_chunk.len() < 16 {\n                        error!(\"expecting EIH, but header chunk len: {}\", header_chunk.len());\n                        return Err(ProtocolError::MissingExtendedIdentityHeader).into();\n                    }\n\n                    let (eih, remain_header_chunk) = header_chunk.split_at_mut(16);\n                    header_chunk = remain_header_chunk;\n\n                    let key_material = [key, salt].concat();\n                    let identity_sub_key = blake3::derive_key(AEAD2022_EIH_SUBKEY_CONTEXT, &key_material);\n                    let mut user_hash = Block::from([0u8; 16]);\n                    match self.method {\n                        CipherKind::AEAD2022_BLAKE3_AES_128_GCM => {\n                            let cipher = Aes128::new_from_slice(&identity_sub_key[0..16]).expect(\"AES-128\");\n                            cipher.decrypt_block_b2b(Block::from_slice(eih), &mut user_hash);\n                        }\n                        CipherKind::AEAD2022_BLAKE3_AES_256_GCM => {\n                            let cipher = Aes256::new_from_slice(&identity_sub_key[0..32]).expect(\"AES-256\");\n                            cipher.decrypt_block_b2b(Block::from_slice(eih), &mut user_hash);\n                        }\n                        _ => unreachable!(\"{} doesn't support EIH\", self.method),\n                    }\n\n                    let user_hash = user_hash.as_slice();\n                    trace!(\n                        \"server EIH {:?}, hash: {:?}\",\n                        ByteStr::new(eih),\n                        ByteStr::new(user_hash)\n                    );\n\n                    match user_manager.get_user_by_hash(user_hash) {\n                        None => {\n                            return Err(ProtocolError::InvalidClientUser(Bytes::copy_from_slice(user_hash))).into();\n                        }\n                        Some(user) => {\n                            trace!(\"{:?} chosen by EIH\", user);\n                            self.user_key = Some(Bytes::copy_from_slice(user.key()));\n                            TcpCipher::new(self.method, user.key(), salt)\n                        }\n                    }\n                }\n                _ => {\n                    unreachable!(\"user_manager must not be None\")\n                }\n            }\n        } else {\n            TcpCipher::new(self.method, key, salt)\n        };\n\n        // Decrypt the header chunk\n        if !cipher.decrypt_packet(header_chunk) {\n            return Err(ProtocolError::DecryptHeaderChunkError).into();\n        }\n\n        let mut header_reader = Cursor::new(header_chunk);\n\n        let stream_ty = header_reader.get_u8();\n        let expected_stream_ty = match self.stream_ty {\n            StreamType::Client => 1, // Receive from server, so type == SERVER (1)\n            StreamType::Server => 0,\n        };\n        if stream_ty != expected_stream_ty {\n            return Err(ProtocolError::InvalidStreamType(expected_stream_ty, stream_ty)).into();\n        }\n\n        let timestamp = header_reader.get_u64();\n        let now = get_now_timestamp();\n        if now.abs_diff(timestamp) > SERVER_STREAM_TIMESTAMP_MAX_DIFF {\n            return Err(ProtocolError::InvalidTimestamp(timestamp, now)).into();\n        }\n\n        // Server respond packet will contain a request salt\n        if request_salt_len > 0 {\n            let mut request_salt = BytesMut::with_capacity(salt_len);\n            request_salt.resize(salt_len, 0);\n            header_reader.read_exact(&mut request_salt)?;\n            self.request_salt = Some(request_salt.freeze());\n        }\n\n        let data_length = header_reader.get_u16();\n\n        trace!(\n            \"got AEAD header stream_type: {}, timestamp: {}, length: {}, request_salt: {:?}\",\n            stream_ty,\n            timestamp,\n            data_length,\n            self.request_salt.as_deref().map(ByteStr::new)\n        );\n\n        // Salt doesn't need to be checked in client, because it has request_salt in respond header\n        if self.stream_ty == StreamType::Server {\n            // Check repeated salt after first successful decryption #442\n            //\n            // If we check salt right here will allow attacker to flood our filter and eventually block all of our legitimate clients' requests.\n\n            context.check_nonce_replay(self.method, salt)?;\n        }\n\n        self.salt = Some(Bytes::copy_from_slice(salt));\n\n        self.cipher = Some(cipher);\n        Ok(Some(data_length as usize)).into()\n    }\n\n    fn poll_read_length<S>(&mut self, cx: &mut task::Context<'_>, stream: &mut S) -> Poll<io::Result<Option<usize>>>\n    where\n        S: AsyncRead + Unpin + ?Sized,\n    {\n        let length_len = 2 + self.method.tag_len();\n\n        let n = ready!(self.poll_read_exact(cx, stream, length_len))?;\n        if n == 0 {\n            return Ok(None).into();\n        }\n\n        let cipher = self.cipher.as_mut().expect(\"cipher is None\");\n\n        let m = &mut self.buffer[..length_len];\n        let length = Self::decrypt_length(cipher, m)?;\n\n        Ok(Some(length)).into()\n    }\n\n    fn poll_read_data<S>(&mut self, cx: &mut task::Context<'_>, stream: &mut S, size: usize) -> Poll<ProtocolResult<()>>\n    where\n        S: AsyncRead + Unpin + ?Sized,\n    {\n        let data_len = size + self.method.tag_len();\n\n        let n = ready!(self.poll_read_exact(cx, stream, data_len))?;\n        if n == 0 {\n            return Err(io::Error::from(ErrorKind::UnexpectedEof).into()).into();\n        }\n\n        let cipher = self.cipher.as_mut().expect(\"cipher is None\");\n\n        let m = &mut self.buffer[..data_len];\n        if !cipher.decrypt_packet(m) {\n            return Err(ProtocolError::DecryptDataError).into();\n        }\n\n        // Remote TAG\n        self.buffer.truncate(size);\n\n        Ok(()).into()\n    }\n\n    fn poll_read_exact<S>(&mut self, cx: &mut task::Context<'_>, stream: &mut S, size: usize) -> Poll<io::Result<usize>>\n    where\n        S: AsyncRead + Unpin + ?Sized,\n    {\n        assert!(size != 0);\n\n        while self.buffer.len() < size {\n            let remaining = size - self.buffer.len();\n            let buffer = &mut self.buffer.chunk_mut()[..remaining];\n\n            let mut read_buf =\n                ReadBuf::uninit(unsafe { slice::from_raw_parts_mut(buffer.as_mut_ptr() as *mut _, remaining) });\n            ready!(Pin::new(&mut *stream).poll_read(cx, &mut read_buf))?;\n\n            let n = read_buf.filled().len();\n            if n == 0 {\n                if !self.buffer.is_empty() {\n                    return Err(ErrorKind::UnexpectedEof.into()).into();\n                } else {\n                    return Ok(0).into();\n                }\n            }\n\n            unsafe {\n                self.buffer.advance_mut(n);\n            }\n        }\n\n        Ok(size).into()\n    }\n\n    fn decrypt_length(cipher: &mut TcpCipher, m: &mut [u8]) -> ProtocolResult<usize> {\n        let plen = {\n            if !cipher.decrypt_packet(m) {\n                return Err(ProtocolError::DecryptLengthError);\n            }\n\n            u16::from_be_bytes([m[0], m[1]]) as usize\n        };\n\n        Ok(plen)\n    }\n\n    /// Get remaining bytes in the current data chunk\n    ///\n    /// Returning (DataChunkCount, RemainingBytes)\n    pub fn current_data_chunk_remaining(&self) -> (u64, usize) {\n        match self.state {\n            DecryptReadState::BufferedData { pos } => (self.data_chunk_count, self.buffer.len() - pos),\n            _ => (self.data_chunk_count, 0),\n        }\n    }\n\n    /// Get authenticated user key\n    pub fn user_key(&self) -> Option<&[u8]> {\n        self.user_key.as_deref()\n    }\n\n    /// Check if handshake finished\n    pub fn handshaked(&self) -> bool {\n        self.has_handshaked\n    }\n}\n\nenum EncryptWriteState {\n    AssembleHeader,\n    AssemblePacket,\n    Writing { pos: usize },\n}\n\n/// Writer wrapper that will encrypt data automatically\npub struct EncryptedWriter {\n    stream_ty: StreamType,\n    cipher: TcpCipher,\n    method: CipherKind,\n    buffer: BytesMut,\n    state: EncryptWriteState,\n    salt: Bytes,\n    request_salt: Option<Bytes>,\n}\n\nimpl EncryptedWriter {\n    /// Creates a new EncryptedWriter\n    pub fn new(stream_ty: StreamType, method: CipherKind, key: &[u8], nonce: &[u8]) -> Self {\n        const EMPTY_IDENTITY: [Bytes; 0] = [];\n        Self::with_identity(stream_ty, method, key, nonce, &EMPTY_IDENTITY)\n    }\n\n    /// Creates a new EncryptedWriter with identities\n    pub fn with_identity(\n        stream_ty: StreamType,\n        method: CipherKind,\n        key: &[u8],\n        nonce: &[u8],\n        identity_keys: &[Bytes],\n    ) -> Self {\n        // nonce should be sent with the first packet\n        let mut buffer = BytesMut::with_capacity(nonce.len() + identity_keys.len() * 16);\n        buffer.put(nonce);\n\n        // Extensible Identity Headers\n        // https://github.com/Shadowsocks-NET/shadowsocks-specs/blob/main/2022-2-shadowsocks-2022-extensible-identity-headers.md\n        #[inline]\n        fn make_eih(method: CipherKind, sub_key: &[u8], ipsk: &[u8], buffer: &mut BytesMut) {\n            let ipsk_hash = blake3::hash(ipsk);\n            let ipsk_plain_text = &ipsk_hash.as_bytes()[0..16];\n\n            match method {\n                CipherKind::AEAD2022_BLAKE3_AES_128_GCM => {\n                    let enc_key = &sub_key[0..16];\n                    let cipher = Aes128::new_from_slice(enc_key).expect(\"AES-128\");\n\n                    let ipsk_plain_text = Block::from_slice(ipsk_plain_text);\n                    let mut block = Block::from([0u8; 16]);\n                    cipher.encrypt_block_b2b(ipsk_plain_text, &mut block);\n\n                    trace!(\n                        \"client EIH {:?}, hash: {:?}\",\n                        ByteStr::new(block.as_slice()),\n                        ByteStr::new(ipsk_plain_text)\n                    );\n                    buffer.put(block.as_slice());\n                }\n                CipherKind::AEAD2022_BLAKE3_AES_256_GCM => {\n                    let enc_key = &sub_key[0..32];\n                    let cipher = Aes256::new_from_slice(enc_key).expect(\"AES-256\");\n\n                    let ipsk_plain_text = Block::from_slice(ipsk_plain_text);\n                    let mut block = Block::from([0u8; 16]);\n                    cipher.encrypt_block_b2b(ipsk_plain_text, &mut block);\n\n                    trace!(\n                        \"client EIH {:?}, hash: {:?}\",\n                        ByteStr::new(block.as_slice()),\n                        ByteStr::new(ipsk_plain_text)\n                    );\n                    buffer.put(block.as_slice());\n                }\n                _ => unreachable!(\"{} doesn't support EIH\", method),\n            }\n        }\n\n        if stream_ty == StreamType::Client && method_support_eih(method) {\n            let mut sub_key: Option<[u8; blake3::OUT_LEN]> = None;\n\n            for ipsk in identity_keys {\n                if let Some(ref sub_key) = sub_key {\n                    make_eih(method, sub_key, ipsk, &mut buffer);\n                }\n\n                let key_material = [ipsk, nonce].concat();\n                sub_key = Some(blake3::derive_key(AEAD2022_EIH_SUBKEY_CONTEXT, &key_material));\n            }\n\n            if let Some(ref sub_key) = sub_key {\n                make_eih(method, sub_key, key, &mut buffer);\n            }\n        }\n\n        Self {\n            stream_ty,\n            cipher: TcpCipher::new(method, key, nonce),\n            method,\n            buffer,\n            state: EncryptWriteState::AssembleHeader,\n            salt: Bytes::copy_from_slice(nonce),\n            request_salt: None,\n        }\n    }\n\n    /// Salt (nonce)\n    pub fn salt(&self) -> &[u8] {\n        self.salt.as_ref()\n    }\n\n    /// Set request salt (for server stream type)\n    pub fn set_request_salt(&mut self, request_salt: Bytes) {\n        debug_assert!(self.stream_ty == StreamType::Server);\n        self.request_salt = Some(request_salt);\n    }\n\n    /// Reset cipher with key\n    pub fn reset_cipher_with_key(&mut self, key: &[u8]) {\n        self.cipher = TcpCipher::new(self.method, key, &self.salt);\n    }\n\n    /// Attempt to write encrypted data into the writer\n    pub fn poll_write_encrypted<S>(\n        &mut self,\n        cx: &mut task::Context<'_>,\n        stream: &mut S,\n        mut buf: &[u8],\n    ) -> Poll<io::Result<usize>>\n    where\n        S: AsyncWrite + Unpin + ?Sized,\n    {\n        if buf.len() > MAX_PACKET_SIZE {\n            buf = &buf[..MAX_PACKET_SIZE];\n        }\n\n        loop {\n            match self.state {\n                EncryptWriteState::AssembleHeader => {\n                    // Step 1. AEAD(TYPE + TIMESTAMP [+ REQUEST_SALT] + LENGTH)\n                    let request_salt_len = match self.request_salt {\n                        None => 0,\n                        Some(ref salt) => salt.len(),\n                    };\n                    let header_len = 1 + 8 + request_salt_len + 2 + self.cipher.tag_len();\n                    self.buffer.reserve(header_len);\n\n                    let mbuf = &mut self.buffer.chunk_mut()[..header_len];\n                    let mbuf = unsafe { slice::from_raw_parts_mut(mbuf.as_mut_ptr(), mbuf.len()) };\n\n                    let stream_ty = match self.stream_ty {\n                        StreamType::Client => 0,\n                        StreamType::Server => 1,\n                    };\n                    self.buffer.put_u8(stream_ty);\n                    self.buffer.put_u64(get_now_timestamp());\n                    if let Some(ref salt) = self.request_salt {\n                        self.buffer.put_slice(salt);\n                    }\n                    self.buffer.put_u16(buf.len() as u16);\n                    self.cipher.encrypt_packet(mbuf);\n                    unsafe { self.buffer.advance_mut(self.cipher.tag_len()) };\n\n                    // Step 2. Data Chunk\n                    let data_size = buf.len() + self.cipher.tag_len();\n                    self.buffer.reserve(data_size);\n\n                    let mbuf = &mut self.buffer.chunk_mut()[..data_size];\n                    let mbuf = unsafe { slice::from_raw_parts_mut(mbuf.as_mut_ptr(), mbuf.len()) };\n\n                    self.buffer.put_slice(buf);\n                    self.cipher.encrypt_packet(mbuf);\n                    unsafe { self.buffer.advance_mut(self.cipher.tag_len()) };\n\n                    // Step 3. Write all\n                    self.state = EncryptWriteState::Writing { pos: 0 };\n                }\n\n                EncryptWriteState::AssemblePacket => {\n                    // Step 1. Append Length\n                    let length_size = 2 + self.cipher.tag_len();\n                    self.buffer.reserve(length_size);\n\n                    let mbuf = &mut self.buffer.chunk_mut()[..length_size];\n                    let mbuf = unsafe { slice::from_raw_parts_mut(mbuf.as_mut_ptr(), mbuf.len()) };\n\n                    self.buffer.put_u16(buf.len() as u16);\n                    self.cipher.encrypt_packet(mbuf);\n                    unsafe { self.buffer.advance_mut(self.cipher.tag_len()) };\n\n                    // Step 2. Append data\n                    let data_size = buf.len() + self.cipher.tag_len();\n                    self.buffer.reserve(data_size);\n\n                    let mbuf = &mut self.buffer.chunk_mut()[..data_size];\n                    let mbuf = unsafe { slice::from_raw_parts_mut(mbuf.as_mut_ptr(), mbuf.len()) };\n\n                    self.buffer.put_slice(buf);\n                    self.cipher.encrypt_packet(mbuf);\n                    unsafe { self.buffer.advance_mut(self.cipher.tag_len()) };\n\n                    // Step 3. Write all\n                    self.state = EncryptWriteState::Writing { pos: 0 };\n                }\n                EncryptWriteState::Writing { ref mut pos } => {\n                    while *pos < self.buffer.len() {\n                        let n = ready!(Pin::new(&mut *stream).poll_write(cx, &self.buffer[*pos..]))?;\n                        if n == 0 {\n                            return Err(ErrorKind::UnexpectedEof.into()).into();\n                        }\n                        *pos += n;\n                    }\n\n                    // Reset state\n                    self.state = EncryptWriteState::AssemblePacket;\n                    self.buffer.clear();\n\n                    return Ok(buf.len()).into();\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/relay/tcprelay/crypto_io.rs",
    "content": "//! IO facilities for TCP relay\n\nuse std::{\n    fmt, io,\n    marker::Unpin,\n    pin::Pin,\n    sync::Arc,\n    task::{self, Poll},\n};\n\n#[cfg(any(feature = \"stream-cipher\", feature = \"aead-cipher\", feature = \"aead-cipher-2022\"))]\nuse byte_string::ByteStr;\nuse bytes::Bytes;\nuse futures::ready;\n#[cfg(any(feature = \"stream-cipher\", feature = \"aead-cipher\", feature = \"aead-cipher-2022\"))]\nuse log::trace;\nuse tokio::io::{AsyncRead, AsyncWrite, ReadBuf};\n\nuse crate::{\n    config::ServerUserManager,\n    context::Context,\n    crypto::{CipherCategory, CipherKind},\n};\n\n#[cfg(feature = \"aead-cipher\")]\nuse super::aead::{DecryptedReader as AeadDecryptedReader, EncryptedWriter as AeadEncryptedWriter};\n#[cfg(feature = \"aead-cipher-2022\")]\nuse super::aead_2022::{DecryptedReader as Aead2022DecryptedReader, EncryptedWriter as Aead2022EncryptedWriter};\n#[cfg(feature = \"stream-cipher\")]\nuse super::stream::{DecryptedReader as StreamDecryptedReader, EncryptedWriter as StreamEncryptedWriter};\n\n/// TCP shadowsocks protocol error\n#[derive(thiserror::Error, Debug)]\npub enum ProtocolError {\n    #[error(transparent)]\n    IoError(#[from] io::Error),\n    #[cfg(feature = \"stream-cipher\")]\n    #[error(transparent)]\n    StreamError(#[from] super::stream::ProtocolError),\n    #[cfg(feature = \"aead-cipher\")]\n    #[error(transparent)]\n    AeadError(#[from] super::aead::ProtocolError),\n    #[cfg(feature = \"aead-cipher-2022\")]\n    #[error(transparent)]\n    Aead2022Error(#[from] super::aead_2022::ProtocolError),\n}\n\n/// TCP shadowsocks protocol result\npub type ProtocolResult<T> = Result<T, ProtocolError>;\n\nimpl From<ProtocolError> for io::Error {\n    fn from(e: ProtocolError) -> Self {\n        match e {\n            ProtocolError::IoError(err) => err,\n            #[cfg(feature = \"stream-cipher\")]\n            ProtocolError::StreamError(err) => err.into(),\n            #[cfg(feature = \"aead-cipher\")]\n            ProtocolError::AeadError(err) => err.into(),\n            #[cfg(feature = \"aead-cipher-2022\")]\n            ProtocolError::Aead2022Error(err) => err.into(),\n        }\n    }\n}\n\n/// The type of TCP stream\n#[derive(Clone, Copy, Debug, Eq, PartialEq)]\npub enum StreamType {\n    /// Client -> Server\n    Client,\n    /// Server -> Client\n    Server,\n}\n\n/// Reader for reading encrypted data stream from shadowsocks' tunnel\n#[allow(clippy::large_enum_variant)]\npub enum DecryptedReader {\n    None,\n    #[cfg(feature = \"aead-cipher\")]\n    Aead(AeadDecryptedReader),\n    #[cfg(feature = \"stream-cipher\")]\n    Stream(StreamDecryptedReader),\n    #[cfg(feature = \"aead-cipher-2022\")]\n    Aead2022(Aead2022DecryptedReader),\n}\n\nimpl DecryptedReader {\n    /// Create a new reader for reading encrypted data\n    pub fn new(stream_ty: StreamType, method: CipherKind, key: &[u8]) -> Self {\n        Self::with_user_manager(stream_ty, method, key, None)\n    }\n\n    /// Create a new reader for reading encrypted data\n    pub fn with_user_manager(\n        stream_ty: StreamType,\n        method: CipherKind,\n        key: &[u8],\n        user_manager: Option<Arc<ServerUserManager>>,\n    ) -> Self {\n        if cfg!(not(feature = \"aead-cipher-2022\")) {\n            let _ = stream_ty;\n            let _ = user_manager;\n        }\n\n        match method.category() {\n            #[cfg(feature = \"stream-cipher\")]\n            CipherCategory::Stream => Self::Stream(StreamDecryptedReader::new(method, key)),\n            #[cfg(feature = \"aead-cipher\")]\n            CipherCategory::Aead => Self::Aead(AeadDecryptedReader::new(method, key)),\n            CipherCategory::None => {\n                let _ = method;\n                let _ = key;\n                Self::None\n            }\n            #[cfg(feature = \"aead-cipher-2022\")]\n            CipherCategory::Aead2022 => Self::Aead2022(Aead2022DecryptedReader::with_user_manager(\n                stream_ty,\n                method,\n                key,\n                user_manager,\n            )),\n        }\n    }\n\n    /// Attempt to read decrypted data from `stream`\n    #[inline]\n    pub fn poll_read_decrypted<S>(\n        &mut self,\n        cx: &mut task::Context<'_>,\n        context: &Context,\n        stream: &mut S,\n        buf: &mut ReadBuf<'_>,\n    ) -> Poll<ProtocolResult<()>>\n    where\n        S: AsyncRead + Unpin + ?Sized,\n    {\n        match *self {\n            #[cfg(feature = \"stream-cipher\")]\n            Self::Stream(ref mut reader) => reader.poll_read_decrypted(cx, context, stream, buf).map_err(Into::into),\n            #[cfg(feature = \"aead-cipher\")]\n            Self::Aead(ref mut reader) => reader.poll_read_decrypted(cx, context, stream, buf).map_err(Into::into),\n            Self::None => {\n                let _ = context;\n                Pin::new(stream).poll_read(cx, buf).map_err(Into::into)\n            }\n            #[cfg(feature = \"aead-cipher-2022\")]\n            Self::Aead2022(ref mut reader) => reader.poll_read_decrypted(cx, context, stream, buf).map_err(Into::into),\n        }\n    }\n\n    /// Get received IV (Stream) or Salt (AEAD, AEAD2022)\n    pub fn nonce(&self) -> Option<&[u8]> {\n        match *self {\n            #[cfg(feature = \"stream-cipher\")]\n            Self::Stream(ref reader) => reader.iv(),\n            #[cfg(feature = \"aead-cipher\")]\n            Self::Aead(ref reader) => reader.salt(),\n            Self::None => None,\n            #[cfg(feature = \"aead-cipher-2022\")]\n            Self::Aead2022(ref reader) => reader.salt(),\n        }\n    }\n\n    /// Get received request Salt (AEAD2022)\n    pub fn request_nonce(&self) -> Option<&[u8]> {\n        match *self {\n            #[cfg(feature = \"stream-cipher\")]\n            Self::Stream(..) => None,\n            #[cfg(feature = \"aead-cipher\")]\n            Self::Aead(..) => None,\n            Self::None => None,\n            #[cfg(feature = \"aead-cipher-2022\")]\n            Self::Aead2022(ref reader) => reader.request_salt(),\n        }\n    }\n\n    /// Get authenticated user key (AEAD2022)\n    pub fn user_key(&self) -> Option<&[u8]> {\n        match *self {\n            #[cfg(feature = \"stream-cipher\")]\n            Self::Stream(..) => None,\n            #[cfg(feature = \"aead-cipher\")]\n            Self::Aead(..) => None,\n            Self::None => None,\n            #[cfg(feature = \"aead-cipher-2022\")]\n            Self::Aead2022(ref reader) => reader.user_key(),\n        }\n    }\n\n    pub fn handshaked(&self) -> bool {\n        match *self {\n            #[cfg(feature = \"stream-cipher\")]\n            Self::Stream(ref reader) => reader.handshaked(),\n            #[cfg(feature = \"aead-cipher\")]\n            Self::Aead(ref reader) => reader.handshaked(),\n            Self::None => true,\n            #[cfg(feature = \"aead-cipher-2022\")]\n            Self::Aead2022(ref reader) => reader.handshaked(),\n        }\n    }\n}\n\n/// Writer for writing encrypted data stream into shadowsocks' tunnel\n#[allow(clippy::large_enum_variant)]\npub enum EncryptedWriter {\n    None,\n    #[cfg(feature = \"aead-cipher\")]\n    Aead(AeadEncryptedWriter),\n    #[cfg(feature = \"stream-cipher\")]\n    Stream(StreamEncryptedWriter),\n    #[cfg(feature = \"aead-cipher-2022\")]\n    Aead2022(Aead2022EncryptedWriter),\n}\n\nimpl EncryptedWriter {\n    /// Create a new writer for writing encrypted data\n    pub fn new(stream_ty: StreamType, method: CipherKind, key: &[u8], nonce: &[u8]) -> Self {\n        if cfg!(not(feature = \"aead-cipher-2022\")) {\n            let _ = stream_ty;\n        }\n\n        match method.category() {\n            #[cfg(feature = \"stream-cipher\")]\n            CipherCategory::Stream => Self::Stream(StreamEncryptedWriter::new(method, key, nonce)),\n            #[cfg(feature = \"aead-cipher\")]\n            CipherCategory::Aead => Self::Aead(AeadEncryptedWriter::new(method, key, nonce)),\n            CipherCategory::None => {\n                let _ = key;\n                let _ = nonce;\n                Self::None\n            }\n            #[cfg(feature = \"aead-cipher-2022\")]\n            CipherCategory::Aead2022 => Self::Aead2022(Aead2022EncryptedWriter::new(stream_ty, method, key, nonce)),\n        }\n    }\n\n    /// Create a new writer for writing encrypted data\n    pub fn with_identity(\n        stream_ty: StreamType,\n        method: CipherKind,\n        key: &[u8],\n        nonce: &[u8],\n        identity_keys: &[Bytes],\n    ) -> Self {\n        if cfg!(not(feature = \"aead-cipher-2022\")) {\n            let _ = stream_ty;\n            let _ = identity_keys;\n        }\n\n        match method.category() {\n            #[cfg(feature = \"stream-cipher\")]\n            CipherCategory::Stream => Self::Stream(StreamEncryptedWriter::new(method, key, nonce)),\n            #[cfg(feature = \"aead-cipher\")]\n            CipherCategory::Aead => Self::Aead(AeadEncryptedWriter::new(method, key, nonce)),\n            CipherCategory::None => {\n                let _ = key;\n                let _ = nonce;\n                Self::None\n            }\n            #[cfg(feature = \"aead-cipher-2022\")]\n            CipherCategory::Aead2022 => Self::Aead2022(Aead2022EncryptedWriter::with_identity(\n                stream_ty,\n                method,\n                key,\n                nonce,\n                identity_keys,\n            )),\n        }\n    }\n\n    /// Attempt to write encrypted data to `stream`\n    #[inline]\n    pub fn poll_write_encrypted<S>(\n        &mut self,\n        cx: &mut task::Context<'_>,\n        stream: &mut S,\n        buf: &[u8],\n    ) -> Poll<ProtocolResult<usize>>\n    where\n        S: AsyncWrite + Unpin + ?Sized,\n    {\n        match *self {\n            #[cfg(feature = \"stream-cipher\")]\n            Self::Stream(ref mut writer) => writer.poll_write_encrypted(cx, stream, buf).map_err(Into::into),\n            #[cfg(feature = \"aead-cipher\")]\n            Self::Aead(ref mut writer) => writer.poll_write_encrypted(cx, stream, buf).map_err(Into::into),\n            Self::None => Pin::new(stream).poll_write(cx, buf).map_err(Into::into),\n            #[cfg(feature = \"aead-cipher-2022\")]\n            Self::Aead2022(ref mut writer) => writer.poll_write_encrypted(cx, stream, buf).map_err(Into::into),\n        }\n    }\n\n    /// Get sent IV (Stream) or Salt (AEAD, AEAD2022)\n    pub fn nonce(&self) -> &[u8] {\n        match *self {\n            #[cfg(feature = \"stream-cipher\")]\n            Self::Stream(ref writer) => writer.iv(),\n            #[cfg(feature = \"aead-cipher\")]\n            Self::Aead(ref writer) => writer.salt(),\n            Self::None => &[],\n            #[cfg(feature = \"aead-cipher-2022\")]\n            Self::Aead2022(ref writer) => writer.salt(),\n        }\n    }\n\n    /// Set request nonce (for server stream of AEAD2022)\n    pub fn set_request_nonce(&mut self, request_nonce: Bytes) {\n        match *self {\n            #[cfg(feature = \"aead-cipher-2022\")]\n            Self::Aead2022(ref mut writer) => writer.set_request_salt(request_nonce),\n            _ => {\n                let _ = request_nonce;\n                panic!(\"only AEAD-2022 cipher could send request salt\");\n            }\n        }\n    }\n\n    /// Reset cipher with authenticated user key\n    pub fn reset_cipher_with_key(&mut self, key: &[u8]) {\n        match *self {\n            #[cfg(feature = \"aead-cipher-2022\")]\n            Self::Aead2022(ref mut writer) => writer.reset_cipher_with_key(key),\n            _ => {\n                let _ = key;\n                panic!(\"only AEAD-2022 cipher could authenticate with multiple users\");\n            }\n        }\n    }\n}\n\n/// A bidirectional stream for read/write encrypted data in shadowsocks' tunnel\npub struct CryptoStream<S> {\n    stream: S,\n    dec: DecryptedReader,\n    enc: EncryptedWriter,\n    method: CipherKind,\n    has_handshaked: bool,\n}\n\nimpl<S> fmt::Debug for CryptoStream<S> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"CryptoStream\")\n            .field(\"method\", &self.method)\n            .field(\"has_handshaked\", &self.has_handshaked)\n            .finish()\n    }\n}\n\nimpl<S> CryptoStream<S> {\n    /// Create a new CryptoStream with the underlying stream connection\n    pub fn from_stream(context: &Context, stream: S, stream_ty: StreamType, method: CipherKind, key: &[u8]) -> Self {\n        const EMPTY_IDENTITY: [Bytes; 0] = [];\n        Self::from_stream_with_identity(context, stream, stream_ty, method, key, &EMPTY_IDENTITY, None)\n    }\n\n    /// Create a new CryptoStream with the underlying stream connection\n    pub fn from_stream_with_identity(\n        context: &Context,\n        stream: S,\n        stream_ty: StreamType,\n        method: CipherKind,\n        key: &[u8],\n        identity_keys: &[Bytes],\n        user_manager: Option<Arc<ServerUserManager>>,\n    ) -> Self {\n        let category = method.category();\n\n        if category == CipherCategory::None {\n            // Fast-path for none cipher\n            return Self::new_none(stream, method);\n        }\n\n        let prev_len = match category {\n            #[cfg(feature = \"stream-cipher\")]\n            CipherCategory::Stream => method.iv_len(),\n            #[cfg(feature = \"aead-cipher\")]\n            CipherCategory::Aead => method.salt_len(),\n            CipherCategory::None => 0,\n            #[cfg(feature = \"aead-cipher-2022\")]\n            CipherCategory::Aead2022 => method.salt_len(),\n        };\n\n        let iv = match category {\n            #[cfg(feature = \"stream-cipher\")]\n            CipherCategory::Stream => {\n                let mut local_iv = vec![0u8; prev_len];\n                context.generate_nonce(method, &mut local_iv, true);\n                trace!(\"generated Stream cipher IV {:?}\", ByteStr::new(&local_iv));\n                local_iv\n            }\n            #[cfg(feature = \"aead-cipher\")]\n            CipherCategory::Aead => {\n                let mut local_salt = vec![0u8; prev_len];\n                context.generate_nonce(method, &mut local_salt, true);\n                trace!(\"generated AEAD cipher salt {:?}\", ByteStr::new(&local_salt));\n                local_salt\n            }\n            CipherCategory::None => {\n                debug_assert_eq!(prev_len, 0);\n                let _ = context;\n                Vec::new()\n            }\n            #[cfg(feature = \"aead-cipher-2022\")]\n            CipherCategory::Aead2022 => {\n                // AEAD-2022 has a request-salt in respond header, so the generated salt doesn't need to be remembered.\n\n                let mut local_salt = vec![0u8; prev_len];\n                context.generate_nonce(method, &mut local_salt, false);\n                trace!(\"generated AEAD cipher salt {:?}\", ByteStr::new(&local_salt));\n                local_salt\n            }\n        };\n\n        Self {\n            stream,\n            dec: DecryptedReader::with_user_manager(stream_ty, method, key, user_manager),\n            enc: EncryptedWriter::with_identity(stream_ty, method, key, &iv, identity_keys),\n            method,\n            has_handshaked: false,\n        }\n    }\n\n    fn new_none(stream: S, method: CipherKind) -> Self {\n        Self {\n            stream,\n            dec: DecryptedReader::None,\n            enc: EncryptedWriter::None,\n            method,\n            has_handshaked: false,\n        }\n    }\n\n    /// Return a reference to the underlying stream\n    pub fn get_ref(&self) -> &S {\n        &self.stream\n    }\n\n    /// Return a mutable reference to the underlying stream\n    pub fn get_mut(&mut self) -> &mut S {\n        &mut self.stream\n    }\n\n    /// Consume the CryptoStream and return the internal stream instance\n    pub fn into_inner(self) -> S {\n        self.stream\n    }\n\n    /// Get received IV (Stream) or Salt (AEAD, AEAD2022)\n    #[inline]\n    pub fn received_nonce(&self) -> Option<&[u8]> {\n        self.dec.nonce()\n    }\n\n    /// Get sent IV (Stream) or Salt (AEAD, AEAD2022)\n    #[inline]\n    pub fn sent_nonce(&self) -> &[u8] {\n        self.enc.nonce()\n    }\n\n    /// Received request salt from server (AEAD2022)\n    #[inline]\n    pub fn received_request_nonce(&self) -> Option<&[u8]> {\n        self.dec.request_nonce()\n    }\n\n    /// Set request nonce (for server stream of AEAD2022)\n    #[inline]\n    pub fn set_request_nonce(&mut self, request_nonce: &[u8]) {\n        self.enc.set_request_nonce(Bytes::copy_from_slice(request_nonce))\n    }\n\n    #[cfg(feature = \"aead-cipher-2022\")]\n    pub(crate) fn set_request_nonce_with_received(&mut self) -> bool {\n        match self.dec.nonce() {\n            None => false,\n            Some(nonce) => {\n                self.enc.set_request_nonce(Bytes::copy_from_slice(nonce));\n                true\n            }\n        }\n    }\n\n    /// Get remaining bytes in the current data chunk\n    ///\n    /// Returning (DataChunkCount, RemainingBytes)\n    #[cfg(feature = \"aead-cipher-2022\")]\n    pub(crate) fn current_data_chunk_remaining(&self) -> (u64, usize) {\n        match self.dec {\n            DecryptedReader::Aead2022(ref dec) => dec.current_data_chunk_remaining(),\n            _ => {\n                panic!(\"only AEAD-2022 protocol has data chunk counter\");\n            }\n        }\n    }\n}\n\n/// Cryptographic reader trait\npub trait CryptoRead {\n    fn poll_read_decrypted(\n        self: Pin<&mut Self>,\n        cx: &mut task::Context<'_>,\n        context: &Context,\n        buf: &mut ReadBuf<'_>,\n    ) -> Poll<ProtocolResult<()>>;\n}\n\n/// Cryptographic writer trait\npub trait CryptoWrite {\n    fn poll_write_encrypted(\n        self: Pin<&mut Self>,\n        cx: &mut task::Context<'_>,\n        buf: &[u8],\n    ) -> Poll<ProtocolResult<usize>>;\n}\n\nimpl<S> CryptoStream<S> {\n    /// Get encryption method\n    pub fn method(&self) -> CipherKind {\n        self.method\n    }\n}\n\nimpl<S> CryptoRead for CryptoStream<S>\nwhere\n    S: AsyncRead + AsyncWrite + Unpin,\n{\n    /// Attempt to read decrypted data from `stream`\n    #[inline]\n    fn poll_read_decrypted(\n        mut self: Pin<&mut Self>,\n        cx: &mut task::Context<'_>,\n        context: &Context,\n        buf: &mut ReadBuf<'_>,\n    ) -> Poll<ProtocolResult<()>> {\n        let Self {\n            ref mut dec,\n            ref mut enc,\n            ref mut stream,\n            ref mut has_handshaked,\n            ..\n        } = *self;\n        ready!(dec.poll_read_decrypted(cx, context, stream, buf))?;\n\n        if !*has_handshaked && dec.handshaked() {\n            *has_handshaked = true;\n\n            // Reset writer cipher with authenticated user key\n            if let Some(user_key) = dec.user_key() {\n                enc.reset_cipher_with_key(user_key);\n            }\n        }\n\n        Ok(()).into()\n    }\n}\n\nimpl<S> CryptoWrite for CryptoStream<S>\nwhere\n    S: AsyncRead + AsyncWrite + Unpin,\n{\n    /// Attempt to write encrypted data to `stream`\n    #[inline]\n    fn poll_write_encrypted(\n        mut self: Pin<&mut Self>,\n        cx: &mut task::Context<'_>,\n        buf: &[u8],\n    ) -> Poll<ProtocolResult<usize>> {\n        let Self {\n            ref mut enc,\n            ref mut stream,\n            ..\n        } = *self;\n        enc.poll_write_encrypted(cx, stream, buf)\n    }\n}\n\nimpl<S> CryptoStream<S>\nwhere\n    S: AsyncRead + AsyncWrite + Unpin,\n{\n    /// Polls `flush` on the underlying stream\n    #[inline]\n    pub fn poll_flush(&mut self, cx: &mut task::Context<'_>) -> Poll<ProtocolResult<()>> {\n        Pin::new(&mut self.stream).poll_flush(cx).map_err(Into::into)\n    }\n\n    /// Polls `shutdown` on the underlying stream\n    #[inline]\n    pub fn poll_shutdown(&mut self, cx: &mut task::Context<'_>) -> Poll<ProtocolResult<()>> {\n        Pin::new(&mut self.stream).poll_shutdown(cx).map_err(Into::into)\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/relay/tcprelay/mod.rs",
    "content": "//! TCP relay\n\npub use self::{\n    proxy_listener::ProxyListener,\n    proxy_stream::{ProxyClientStream, ProxyServerStream},\n};\n\n#[cfg(feature = \"aead-cipher\")]\nmod aead;\n#[cfg(feature = \"aead-cipher-2022\")]\nmod aead_2022;\npub mod crypto_io;\npub mod proxy_listener;\npub mod proxy_stream;\n#[cfg(feature = \"stream-cipher\")]\nmod stream;\npub mod utils;\n\n/// Connection direction type\n#[derive(Debug, Clone, Copy, PartialEq, Eq)]\npub enum StreamType {\n    /// Connection initiated from client to server\n    Client,\n    /// Connection initiated from server to client\n    Server,\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/relay/tcprelay/proxy_listener.rs",
    "content": "//! A TCP listener for accepting shadowsocks' client connection\n\nuse std::{\n    io,\n    net::SocketAddr,\n    sync::{Arc, LazyLock},\n};\n\nuse tokio::{\n    io::{AsyncRead, AsyncWrite},\n    net::TcpStream,\n};\n\nuse crate::{\n    config::{ServerAddr, ServerConfig, ServerUserManager},\n    context::SharedContext,\n    crypto::CipherKind,\n    net::{AcceptOpts, TcpListener},\n    relay::tcprelay::proxy_stream::server::ProxyServerStream,\n};\n\n/// A TCP listener for accepting shadowsocks' client connection\n#[derive(Debug)]\npub struct ProxyListener {\n    listener: TcpListener,\n    method: CipherKind,\n    key: Box<[u8]>,\n    context: SharedContext,\n    user_manager: Option<Arc<ServerUserManager>>,\n}\n\nstatic DEFAULT_ACCEPT_OPTS: LazyLock<AcceptOpts> = LazyLock::new(Default::default);\n\nimpl ProxyListener {\n    /// Create a `ProxyListener` binding to a specific address\n    pub async fn bind(context: SharedContext, svr_cfg: &ServerConfig) -> io::Result<Self> {\n        Self::bind_with_opts(context, svr_cfg, DEFAULT_ACCEPT_OPTS.clone()).await\n    }\n\n    /// Create a `ProxyListener` binding to a specific address with opts\n    pub async fn bind_with_opts(\n        context: SharedContext,\n        svr_cfg: &ServerConfig,\n        accept_opts: AcceptOpts,\n    ) -> io::Result<Self> {\n        let listener = match svr_cfg.tcp_external_addr() {\n            ServerAddr::SocketAddr(sa) => TcpListener::bind_with_opts(sa, accept_opts).await?,\n            ServerAddr::DomainName(domain, port) => {\n                lookup_then!(&context, domain, *port, |addr| {\n                    TcpListener::bind_with_opts(&addr, accept_opts.clone()).await\n                })?\n                .1\n            }\n        };\n        Ok(Self::from_listener(context, listener, svr_cfg))\n    }\n\n    /// Create a `ProxyListener` from a `TcpListener`\n    pub fn from_listener(context: SharedContext, listener: TcpListener, svr_cfg: &ServerConfig) -> Self {\n        Self {\n            listener,\n            method: svr_cfg.method(),\n            key: svr_cfg.key().to_vec().into_boxed_slice(),\n            context,\n            user_manager: svr_cfg.clone_user_manager(),\n        }\n    }\n\n    /// Accepts a shadowsocks' client connection\n    #[inline]\n    pub async fn accept(&self) -> io::Result<(ProxyServerStream<TcpStream>, SocketAddr)> {\n        self.accept_map(|s| s).await\n    }\n\n    /// Accepts a shadowsocks' client connection and maps the accepted `TcpStream` to another stream type\n    pub async fn accept_map<F, S>(&self, map_fn: F) -> io::Result<(ProxyServerStream<S>, SocketAddr)>\n    where\n        F: FnOnce(TcpStream) -> S,\n        S: AsyncRead + AsyncWrite + Unpin,\n    {\n        let (stream, peer_addr) = self.listener.accept().await?;\n        let stream = map_fn(stream);\n\n        // Create a ProxyServerStream and read the target address from it\n        let stream = ProxyServerStream::from_stream_with_user_manager(\n            self.context.clone(),\n            stream,\n            self.method,\n            &self.key,\n            self.user_manager.clone(),\n        );\n\n        Ok((stream, peer_addr))\n    }\n\n    /// Get local binded address\n    pub fn local_addr(&self) -> io::Result<SocketAddr> {\n        self.listener.local_addr()\n    }\n\n    /// Get reference to the internal listener\n    pub fn get_ref(&self) -> &TcpListener {\n        &self.listener\n    }\n\n    /// Consumes the `ProxyListener` and return the internal listener\n    pub fn into_inner(self) -> TcpListener {\n        self.listener\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/relay/tcprelay/proxy_stream/client.rs",
    "content": "//! TCP stream for communicating with shadowsocks' proxy server\n\nuse std::{\n    io::{self, ErrorKind},\n    pin::Pin,\n    sync::LazyLock,\n    task::{self, Poll},\n};\n\nuse bytes::{BufMut, BytesMut};\nuse cfg_if::cfg_if;\nuse futures::ready;\nuse log::trace;\nuse pin_project::pin_project;\nuse tokio::{\n    io::{AsyncRead, AsyncWrite, ReadBuf},\n    time,\n};\n\n#[cfg(feature = \"aead-cipher-2022\")]\nuse crate::relay::get_aead_2022_padding_size;\nuse crate::{\n    config::ServerConfig,\n    context::SharedContext,\n    crypto::CipherKind,\n    net::{ConnectOpts, TcpStream as OutboundTcpStream},\n    relay::{\n        socks5::Address,\n        tcprelay::crypto_io::{CryptoRead, CryptoStream, CryptoWrite, StreamType},\n    },\n};\n\n#[derive(Debug)]\nenum ProxyClientStreamWriteState {\n    Connect(Address),\n    Connecting(BytesMut),\n    Connected,\n}\n\n#[derive(Debug)]\nenum ProxyClientStreamReadState {\n    #[cfg(feature = \"aead-cipher-2022\")]\n    CheckRequestNonce,\n    Established,\n}\n\n/// A stream for sending / receiving data stream from remote server via shadowsocks' proxy server\n#[derive(Debug)]\n#[pin_project]\npub struct ProxyClientStream<S> {\n    #[pin]\n    stream: CryptoStream<S>,\n    writer_state: ProxyClientStreamWriteState,\n    reader_state: ProxyClientStreamReadState,\n    context: SharedContext,\n}\n\nstatic DEFAULT_CONNECT_OPTS: LazyLock<ConnectOpts> = LazyLock::new(Default::default);\n\nimpl ProxyClientStream<OutboundTcpStream> {\n    /// Connect to target `addr` via shadowsocks' server configured by `svr_cfg`\n    pub async fn connect<A>(context: SharedContext, svr_cfg: &ServerConfig, addr: A) -> io::Result<Self>\n    where\n        A: Into<Address>,\n    {\n        Self::connect_with_opts(context, svr_cfg, addr, &DEFAULT_CONNECT_OPTS).await\n    }\n\n    /// Connect to target `addr` via shadowsocks' server configured by `svr_cfg`\n    pub async fn connect_with_opts<A>(\n        context: SharedContext,\n        svr_cfg: &ServerConfig,\n        addr: A,\n        opts: &ConnectOpts,\n    ) -> io::Result<Self>\n    where\n        A: Into<Address>,\n    {\n        Self::connect_with_opts_map(context, svr_cfg, addr, opts, |s| s).await\n    }\n}\n\nimpl<S> ProxyClientStream<S>\nwhere\n    S: AsyncRead + AsyncWrite + Unpin,\n{\n    /// Connect to target `addr` via shadowsocks' server configured by `svr_cfg`, maps `TcpStream` to customized stream with `map_fn`\n    pub async fn connect_map<A, F>(\n        context: SharedContext,\n        svr_cfg: &ServerConfig,\n        addr: A,\n        map_fn: F,\n    ) -> io::Result<Self>\n    where\n        A: Into<Address>,\n        F: FnOnce(OutboundTcpStream) -> S,\n    {\n        Self::connect_with_opts_map(context, svr_cfg, addr, &DEFAULT_CONNECT_OPTS, map_fn).await\n    }\n\n    /// Connect to target `addr` via shadowsocks' server configured by `svr_cfg`, maps `TcpStream` to customized stream with `map_fn`\n    pub async fn connect_with_opts_map<A, F>(\n        context: SharedContext,\n        svr_cfg: &ServerConfig,\n        addr: A,\n        opts: &ConnectOpts,\n        map_fn: F,\n    ) -> io::Result<Self>\n    where\n        A: Into<Address>,\n        F: FnOnce(OutboundTcpStream) -> S,\n    {\n        let stream = match svr_cfg.timeout() {\n            Some(d) => {\n                match time::timeout(\n                    d,\n                    OutboundTcpStream::connect_server_with_opts(&context, svr_cfg.tcp_external_addr(), opts),\n                )\n                .await\n                {\n                    Ok(Ok(s)) => s,\n                    Ok(Err(e)) => return Err(e),\n                    Err(..) => {\n                        return Err(io::Error::new(\n                            ErrorKind::TimedOut,\n                            format!(\"connect {} timeout\", svr_cfg.addr()),\n                        ));\n                    }\n                }\n            }\n            None => OutboundTcpStream::connect_server_with_opts(&context, svr_cfg.tcp_external_addr(), opts).await?,\n        };\n\n        trace!(\n            \"connected tcp remote {} (outbound: {}) with {:?}\",\n            svr_cfg.addr(),\n            svr_cfg.tcp_external_addr(),\n            opts\n        );\n\n        Ok(Self::from_stream(context, map_fn(stream), svr_cfg, addr))\n    }\n\n    /// Create a `ProxyClientStream` with a connected `stream` to a shadowsocks' server\n    ///\n    /// NOTE: `stream` must be connected to the server with the same configuration as `svr_cfg`, otherwise strange errors would occurs\n    pub fn from_stream<A>(context: SharedContext, stream: S, svr_cfg: &ServerConfig, addr: A) -> Self\n    where\n        A: Into<Address>,\n    {\n        let addr = addr.into();\n        let stream = CryptoStream::from_stream_with_identity(\n            &context,\n            stream,\n            StreamType::Client,\n            svr_cfg.method(),\n            svr_cfg.key(),\n            svr_cfg.identity_keys(),\n            None,\n        );\n\n        #[cfg(not(feature = \"aead-cipher-2022\"))]\n        let reader_state = ProxyClientStreamReadState::Established;\n\n        #[cfg(feature = \"aead-cipher-2022\")]\n        let reader_state = if svr_cfg.method().is_aead_2022() {\n            // AEAD 2022 has a respond header\n            ProxyClientStreamReadState::CheckRequestNonce\n        } else {\n            ProxyClientStreamReadState::Established\n        };\n\n        Self {\n            stream,\n            writer_state: ProxyClientStreamWriteState::Connect(addr),\n            reader_state,\n            context,\n        }\n    }\n\n    /// Get reference to the underlying stream\n    pub fn get_ref(&self) -> &S {\n        self.stream.get_ref()\n    }\n\n    /// Get mutable reference to the underlying stream\n    pub fn get_mut(&mut self) -> &mut S {\n        self.stream.get_mut()\n    }\n\n    /// Consumes the `ProxyClientStream` and return the underlying stream\n    pub fn into_inner(self) -> S {\n        self.stream.into_inner()\n    }\n}\n\nimpl<S> AsyncRead for ProxyClientStream<S>\nwhere\n    S: AsyncRead + AsyncWrite + Unpin,\n{\n    #[inline]\n    fn poll_read(self: Pin<&mut Self>, cx: &mut task::Context<'_>, buf: &mut ReadBuf<'_>) -> Poll<io::Result<()>> {\n        #[allow(unused_mut)]\n        let mut this = self.project();\n\n        #[allow(clippy::never_loop)]\n        loop {\n            match this.reader_state {\n                ProxyClientStreamReadState::Established => {\n                    return this\n                        .stream\n                        .poll_read_decrypted(cx, this.context, buf)\n                        .map_err(Into::into);\n                }\n                #[cfg(feature = \"aead-cipher-2022\")]\n                ProxyClientStreamReadState::CheckRequestNonce => {\n                    ready!(this.stream.as_mut().poll_read_decrypted(cx, this.context, buf))?;\n\n                    // REQUEST_NONCE should be in the respond packet (header) of AEAD-2022.\n                    //\n                    // If received_request_nonce() is None, then:\n                    // 1. method.salt_len() == 0, no checking required.\n                    // 2. TCP stream read() returns EOF before receiving the header, no checking required.\n                    //\n                    // poll_read_decrypted will wait until the first non-zero size data chunk.\n                    let (data_chunk_count, _) = this.stream.current_data_chunk_remaining();\n                    if data_chunk_count > 0 {\n                        // data_chunk_count > 0, so the reader received at least 1 data chunk.\n\n                        let sent_nonce = this.stream.sent_nonce();\n                        let sent_nonce = if sent_nonce.is_empty() { None } else { Some(sent_nonce) };\n                        if sent_nonce != this.stream.received_request_nonce() {\n                            return Err(io::Error::other(\"received TCP response header with unmatched salt\")).into();\n                        }\n\n                        *(this.reader_state) = ProxyClientStreamReadState::Established;\n                    }\n\n                    return Ok(()).into();\n                }\n            }\n        }\n    }\n}\n\n#[inline]\nfn make_first_packet_buffer(method: CipherKind, addr: &Address, buf: &[u8]) -> BytesMut {\n    // Target Address should be sent with the first packet together,\n    // which would prevent from being detected.\n\n    let addr_length = addr.serialized_len();\n    let mut buffer = BytesMut::new();\n\n    cfg_if! {\n        if #[cfg(feature = \"aead-cipher-2022\")] {\n            let padding_size = get_aead_2022_padding_size(buf);\n            let header_length = if method.is_aead_2022() {\n                addr_length + 2 + padding_size + buf.len()\n            } else {\n                addr_length + buf.len()\n            };\n        } else {\n            let _ = method;\n            let header_length = addr_length + buf.len();\n        }\n    }\n\n    buffer.reserve(header_length);\n\n    // STREAM / AEAD / AEAD2022 protocol, append the Address before payload\n    addr.write_to_buf(&mut buffer);\n\n    #[cfg(feature = \"aead-cipher-2022\")]\n    if method.is_aead_2022() {\n        buffer.put_u16(padding_size as u16);\n\n        if padding_size > 0 {\n            unsafe {\n                buffer.advance_mut(padding_size);\n            }\n        }\n    }\n\n    buffer.put_slice(buf);\n\n    buffer\n}\n\nimpl<S> AsyncWrite for ProxyClientStream<S>\nwhere\n    S: AsyncRead + AsyncWrite + Unpin,\n{\n    fn poll_write(self: Pin<&mut Self>, cx: &mut task::Context<'_>, buf: &[u8]) -> Poll<Result<usize, io::Error>> {\n        let this = self.project();\n\n        loop {\n            match this.writer_state {\n                &mut ProxyClientStreamWriteState::Connect(ref addr) => {\n                    let buffer = make_first_packet_buffer(this.stream.method(), addr, buf);\n\n                    // Save the concatenated buffer before it is written successfully.\n                    // APIs require buffer to be kept alive before Poll::Ready\n                    //\n                    // Proactor APIs like IOCP on Windows, pointers of buffers have to be kept alive\n                    // before IO completion.\n                    *(this.writer_state) = ProxyClientStreamWriteState::Connecting(buffer);\n                }\n                &mut ProxyClientStreamWriteState::Connecting(ref buffer) => {\n                    let n = ready!(this.stream.poll_write_encrypted(cx, buffer))?;\n\n                    // In general, poll_write_encrypted should perform like write_all.\n                    debug_assert!(n == buffer.len());\n\n                    *(this.writer_state) = ProxyClientStreamWriteState::Connected;\n\n                    // NOTE:\n                    // poll_write will return Ok(0) if buf.len() == 0\n                    // But for the first call, this function will eventually send the handshake packet (IV/Salt + ADDR) to the remote address.\n                    //\n                    // https://github.com/shadowsocks/shadowsocks-rust/issues/232\n                    //\n                    // For protocols that requires *Server Hello* message, like FTP, clients won't send anything to the server until server sends handshake messages.\n                    // This could be achieved by calling poll_write with an empty input buffer.\n                    return Ok(buf.len()).into();\n                }\n                ProxyClientStreamWriteState::Connected => {\n                    return this.stream.poll_write_encrypted(cx, buf).map_err(Into::into);\n                }\n            }\n        }\n    }\n\n    #[inline]\n    fn poll_flush(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Result<(), io::Error>> {\n        self.project().stream.poll_flush(cx).map_err(Into::into)\n    }\n\n    #[inline]\n    fn poll_shutdown(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Result<(), io::Error>> {\n        self.project().stream.poll_shutdown(cx).map_err(Into::into)\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/relay/tcprelay/proxy_stream/mod.rs",
    "content": "//! Stream interface for communicating with shadowsocks proxy servers\n\n// pub use self::{\n//     client::{ProxyClientStream, ProxyClientStreamReadHalf, ProxyClientStreamWriteHalf},\n//     server::{ProxyServerStream, ProxyServerStreamReadHalf, ProxyServerStreamWriteHalf},\n// };\n\npub use self::{client::ProxyClientStream, server::ProxyServerStream};\n\npub mod client;\npub mod protocol;\npub mod server;\n"
  },
  {
    "path": "crates/shadowsocks/src/relay/tcprelay/proxy_stream/protocol/mod.rs",
    "content": "//! Shadowsocks TCP protocol\n\nuse std::io;\n\nuse bytes::BufMut;\nuse tokio::io::AsyncRead;\n\nuse crate::{\n    crypto::{CipherCategory, CipherKind},\n    relay::socks5::Address,\n};\n\npub use self::v1::{StreamTcpRequestHeader, StreamTcpRequestHeaderRef};\n#[cfg(feature = \"aead-cipher-2022\")]\npub use self::v2::{Aead2022TcpRequestHeader, Aead2022TcpRequestHeaderRef};\n\npub mod v1;\n#[cfg(feature = \"aead-cipher-2022\")]\npub mod v2;\n\n#[derive(Debug)]\npub enum TcpRequestHeader {\n    Stream(StreamTcpRequestHeader),\n    #[cfg(feature = \"aead-cipher-2022\")]\n    Aead2022(Aead2022TcpRequestHeader),\n}\n\nimpl TcpRequestHeader {\n    pub async fn read_from<R: AsyncRead + Unpin>(method: CipherKind, reader: &mut R) -> io::Result<Self> {\n        match method.category() {\n            CipherCategory::None => Ok(Self::Stream(StreamTcpRequestHeader::read_from(reader).await?)),\n            #[cfg(feature = \"aead-cipher\")]\n            CipherCategory::Aead => Ok(Self::Stream(StreamTcpRequestHeader::read_from(reader).await?)),\n            #[cfg(feature = \"stream-cipher\")]\n            CipherCategory::Stream => Ok(Self::Stream(StreamTcpRequestHeader::read_from(reader).await?)),\n            #[cfg(feature = \"aead-cipher-2022\")]\n            CipherCategory::Aead2022 => Ok(Self::Aead2022(Aead2022TcpRequestHeader::read_from(reader).await?)),\n        }\n    }\n\n    pub fn write_to_buf<B: BufMut>(&self, buf: &mut B) {\n        match *self {\n            Self::Stream(ref h) => h.write_to_buf(buf),\n            #[cfg(feature = \"aead-cipher-2022\")]\n            Self::Aead2022(ref h) => h.write_to_buf(buf),\n        }\n    }\n\n    pub fn addr(self) -> Address {\n        match self {\n            Self::Stream(h) => h.addr,\n            #[cfg(feature = \"aead-cipher-2022\")]\n            Self::Aead2022(h) => h.addr,\n        }\n    }\n\n    pub fn addr_ref(&self) -> &Address {\n        match *self {\n            Self::Stream(ref h) => &h.addr,\n            #[cfg(feature = \"aead-cipher-2022\")]\n            Self::Aead2022(ref h) => &h.addr,\n        }\n    }\n\n    pub fn serialized_len(&self) -> usize {\n        match *self {\n            Self::Stream(ref h) => h.serialized_len(),\n            #[cfg(feature = \"aead-cipher-2022\")]\n            Self::Aead2022(ref h) => h.serialized_len(),\n        }\n    }\n}\n\n#[derive(Debug)]\npub enum TcpRequestHeaderRef<'a> {\n    Stream(StreamTcpRequestHeaderRef<'a>),\n    #[cfg(feature = \"aead-cipher-2022\")]\n    Aead2022(Aead2022TcpRequestHeaderRef<'a>),\n}\n\nimpl TcpRequestHeaderRef<'_> {\n    pub fn write_to_buf<B: BufMut>(&self, buf: &mut B) {\n        match *self {\n            TcpRequestHeaderRef::Stream(ref h) => h.write_to_buf(buf),\n            #[cfg(feature = \"aead-cipher-2022\")]\n            TcpRequestHeaderRef::Aead2022(ref h) => h.write_to_buf(buf),\n        }\n    }\n\n    pub fn serialized_len(&self) -> usize {\n        match *self {\n            TcpRequestHeaderRef::Stream(ref h) => h.serialized_len(),\n            #[cfg(feature = \"aead-cipher-2022\")]\n            TcpRequestHeaderRef::Aead2022(ref h) => h.serialized_len(),\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/relay/tcprelay/proxy_stream/protocol/v1.rs",
    "content": "//! Shadowsocks Stream / AEAD header protocol\n\nuse std::io;\n\nuse bytes::BufMut;\nuse tokio::io::AsyncRead;\n\nuse crate::relay::socks5::Address;\n\n#[derive(Debug)]\npub struct StreamTcpRequestHeader {\n    pub addr: Address,\n}\n\nimpl StreamTcpRequestHeader {\n    pub async fn read_from<R: AsyncRead + Unpin>(reader: &mut R) -> io::Result<Self> {\n        Ok(Self {\n            addr: Address::read_from(reader).await?,\n        })\n    }\n\n    pub fn write_to_buf<B: BufMut>(&self, buf: &mut B) {\n        StreamTcpRequestHeaderRef { addr: &self.addr }.write_to_buf(buf)\n    }\n\n    pub fn serialized_len(&self) -> usize {\n        StreamTcpRequestHeaderRef { addr: &self.addr }.serialized_len()\n    }\n}\n\n#[derive(Debug)]\npub struct StreamTcpRequestHeaderRef<'a> {\n    pub addr: &'a Address,\n}\n\nimpl StreamTcpRequestHeaderRef<'_> {\n    pub fn write_to_buf<B: BufMut>(&self, buf: &mut B) {\n        self.addr.write_to_buf(buf);\n    }\n\n    pub fn serialized_len(&self) -> usize {\n        self.addr.serialized_len()\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/relay/tcprelay/proxy_stream/protocol/v2.rs",
    "content": "//! Shadowsocks AEAD 2022 header protocol\n\nuse std::io;\n\nuse bytes::BufMut;\nuse tokio::io::{AsyncRead, AsyncReadExt};\n\nuse crate::relay::Address;\n\n/// Maximum padding length\npub const MAX_PADDING_SIZE: usize = 900;\n\n/// Stream (Client & Server) timestamp max differences (ABS)\npub const SERVER_STREAM_TIMESTAMP_MAX_DIFF: u64 = 30;\n\n/// TCP Request Header\n///\n/// +-------+-------+-------+-------+-------+-------+-------+-------+-------+\n/// | ADDR (Variable ...)\n/// +-------+-------+-------+-------+-------+-------+-------+-------+-------+\n/// | PADDING SIZE  | PADDING (Variable ...)\n/// +-------+-------+-------+-------+-------+-------+-------+-------+-------+\n#[derive(Debug, Clone)]\npub struct Aead2022TcpRequestHeader {\n    pub addr: Address,\n    pub padding_size: u16,\n}\n\nimpl Aead2022TcpRequestHeader {\n    pub async fn read_from<R: AsyncRead + Unpin>(reader: &mut R) -> io::Result<Self> {\n        let addr = Address::read_from(reader).await?;\n\n        let mut padding_size_buffer = [0u8; 2];\n        reader.read_exact(&mut padding_size_buffer).await?;\n\n        let padding_size = u16::from_be_bytes(padding_size_buffer);\n        if padding_size > 0 {\n            let mut take_reader = reader.take(padding_size as u64);\n            let mut buffer = [0u8; 64];\n            loop {\n                match take_reader.read(&mut buffer).await {\n                    Ok(0) => break,\n                    Ok(..) => continue,\n                    Err(err) => return Err(err),\n                }\n            }\n        }\n\n        Ok(Self { addr, padding_size })\n    }\n\n    pub fn write_to_buf<B: BufMut>(&self, buf: &mut B) {\n        Aead2022TcpRequestHeaderRef {\n            addr: &self.addr,\n            padding_size: self.padding_size,\n        }\n        .write_to_buf(buf)\n    }\n\n    pub fn serialized_len(&self) -> usize {\n        Aead2022TcpRequestHeaderRef {\n            addr: &self.addr,\n            padding_size: self.padding_size,\n        }\n        .serialized_len()\n    }\n}\n\n#[derive(Debug)]\npub struct Aead2022TcpRequestHeaderRef<'a> {\n    pub addr: &'a Address,\n    pub padding_size: u16,\n}\n\nimpl Aead2022TcpRequestHeaderRef<'_> {\n    pub fn write_to_buf<B: BufMut>(&self, buf: &mut B) {\n        assert!(\n            self.padding_size as usize <= MAX_PADDING_SIZE,\n            \"padding length must be in [0, {MAX_PADDING_SIZE}]\"\n        );\n\n        buf.put_u16(self.padding_size);\n        if self.padding_size > 0 {\n            unsafe {\n                buf.advance_mut(self.padding_size as usize);\n            }\n        }\n    }\n\n    pub fn serialized_len(&self) -> usize {\n        self.addr.serialized_len() + 2 + self.padding_size as usize\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/relay/tcprelay/proxy_stream/server.rs",
    "content": "//! A TCP stream for communicating with shadowsocks' proxy client\n\nuse std::{\n    io,\n    pin::Pin,\n    sync::Arc,\n    task::{self, Poll},\n};\n\nuse bytes::Bytes;\nuse futures::ready;\nuse pin_project::pin_project;\nuse tokio::io::{AsyncRead, AsyncWrite, ReadBuf};\n\nuse crate::{\n    config::ServerUserManager,\n    context::SharedContext,\n    crypto::CipherKind,\n    relay::{\n        socks5::Address,\n        tcprelay::{\n            crypto_io::{CryptoRead, CryptoStream, CryptoWrite, StreamType},\n            proxy_stream::protocol::TcpRequestHeader,\n        },\n    },\n};\n\n#[derive(Debug)]\nenum ProxyServerStreamWriteState {\n    #[cfg(feature = \"aead-cipher-2022\")]\n    PrepareHeader(Option<std::task::Waker>),\n    Established,\n}\n\n/// A stream for communicating with shadowsocks' proxy client\n#[derive(Debug)]\n#[pin_project]\npub struct ProxyServerStream<S> {\n    #[pin]\n    stream: CryptoStream<S>,\n    context: SharedContext,\n    writer_state: ProxyServerStreamWriteState,\n    has_handshaked: bool,\n}\n\nimpl<S> ProxyServerStream<S> {\n    /// Create a `ProxyServerStream` from a connection stream\n    pub fn from_stream(context: SharedContext, stream: S, method: CipherKind, key: &[u8]) -> Self {\n        Self::from_stream_with_user_manager(context, stream, method, key, None)\n    }\n\n    /// Create a `ProxyServerStream` from a connection stream\n    ///\n    /// Set `user_manager` to enable support of verifying EIH users.\n    pub fn from_stream_with_user_manager(\n        context: SharedContext,\n        stream: S,\n        method: CipherKind,\n        key: &[u8],\n        user_manager: Option<Arc<ServerUserManager>>,\n    ) -> Self {\n        #[cfg(feature = \"aead-cipher-2022\")]\n        let writer_state = if method.is_aead_2022() {\n            ProxyServerStreamWriteState::PrepareHeader(None)\n        } else {\n            ProxyServerStreamWriteState::Established\n        };\n\n        #[cfg(not(feature = \"aead-cipher-2022\"))]\n        let writer_state = ProxyServerStreamWriteState::Established;\n\n        const EMPTY_IDENTITY: [Bytes; 0] = [];\n        Self {\n            stream: CryptoStream::from_stream_with_identity(\n                &context,\n                stream,\n                StreamType::Server,\n                method,\n                key,\n                &EMPTY_IDENTITY,\n                user_manager,\n            ),\n            context,\n            writer_state,\n            has_handshaked: false,\n        }\n    }\n\n    /// Get reference of the internal stream\n    pub fn get_ref(&self) -> &S {\n        self.stream.get_ref()\n    }\n\n    /// Get mutable reference of the internal stream\n    pub fn get_mut(&mut self) -> &mut S {\n        self.stream.get_mut()\n    }\n\n    /// Consumes the object and return the internal stream\n    pub fn into_inner(self) -> S {\n        self.stream.into_inner()\n    }\n}\n\nimpl<S> ProxyServerStream<S>\nwhere\n    S: AsyncRead + AsyncWrite + Unpin,\n{\n    /// Handshaking. Getting the destination address from client\n    ///\n    /// This method should be called only once after accepted.\n    pub async fn handshake(&mut self) -> io::Result<Address> {\n        if self.has_handshaked {\n            return Err(io::Error::other(\"stream is already handshaked\"));\n        }\n\n        self.has_handshaked = true;\n        let header = TcpRequestHeader::read_from(self.stream.method(), self).await?;\n\n        #[cfg(feature = \"aead-cipher-2022\")]\n        if let TcpRequestHeader::Aead2022(ref header) = header {\n            use log::warn;\n\n            // AEAD-2022 SPEC\n            //\n            // Padding: If the client is not sending payload along with the header, a random padding MUST be added.\n            //\n            // Check here preventing security risk causing by misimplementation clients.\n            if header.padding_size == 0 {\n                let (chunk_count, chunk_remaining) = self.stream.current_data_chunk_remaining();\n                if chunk_count == 1 && chunk_remaining == 0 {\n                    // Header is the end of the data chunk, so no payload is in the first chunk, and padding == 0.\n                    // REJECT insecure clients.\n                    return Err(io::Error::other(\"no payload in first data chunk, and padding is 0\"));\n                } else if chunk_count > 1 {\n                    warn!(\n                        \"tcp header is separated in {} chunks, client is not following the AEAD-2022 spec\",\n                        chunk_count,\n                    );\n                }\n            }\n        }\n        Ok(header.addr())\n    }\n}\n\nimpl<S> AsyncRead for ProxyServerStream<S>\nwhere\n    S: AsyncRead + AsyncWrite + Unpin,\n{\n    #[inline]\n    fn poll_read(self: Pin<&mut Self>, cx: &mut task::Context<'_>, buf: &mut ReadBuf<'_>) -> Poll<io::Result<()>> {\n        if !self.has_handshaked {\n            return Err(io::Error::other(\"stream is not handshaked yet\")).into();\n        }\n\n        let this = self.project();\n        ready!(this.stream.poll_read_decrypted(cx, this.context, buf))?;\n\n        // Wakeup writer task because we have already received the salt\n        #[cfg(feature = \"aead-cipher-2022\")]\n        if let ProxyServerStreamWriteState::PrepareHeader(waker) = this.writer_state\n            && let Some(waker) = waker.take()\n        {\n            waker.wake();\n        }\n\n        Ok(()).into()\n    }\n}\n\nimpl<S> AsyncWrite for ProxyServerStream<S>\nwhere\n    S: AsyncRead + AsyncWrite + Unpin,\n{\n    #[inline]\n    fn poll_write(self: Pin<&mut Self>, cx: &mut task::Context<'_>, buf: &[u8]) -> Poll<Result<usize, io::Error>> {\n        #[allow(unused_mut)]\n        let mut this = self.project();\n\n        #[allow(clippy::never_loop)]\n        loop {\n            match *this.writer_state {\n                ProxyServerStreamWriteState::Established => {\n                    return this.stream.poll_write_encrypted(cx, buf).map_err(Into::into);\n                }\n                #[cfg(feature = \"aead-cipher-2022\")]\n                ProxyServerStreamWriteState::PrepareHeader(ref mut waker) => {\n                    if this.stream.set_request_nonce_with_received() {\n                        *(this.writer_state) = ProxyServerStreamWriteState::Established;\n                    } else {\n                        // Reader didn't receive the salt from client yet.\n                        if let Some(waker) = waker.take()\n                            && !waker.will_wake(cx.waker())\n                        {\n                            waker.wake();\n                        }\n                        *waker = Some(cx.waker().clone());\n                        return Poll::Pending;\n                    }\n                }\n            }\n        }\n    }\n\n    #[inline]\n    fn poll_flush(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Result<(), io::Error>> {\n        self.project().stream.poll_flush(cx).map_err(Into::into)\n    }\n\n    #[inline]\n    fn poll_shutdown(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Result<(), io::Error>> {\n        self.project().stream.poll_shutdown(cx).map_err(Into::into)\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/relay/tcprelay/stream.rs",
    "content": "//! Stream protocol implementation\nuse std::{\n    io::{self, ErrorKind},\n    marker::Unpin,\n    pin::Pin,\n    slice,\n    task::{self, Poll},\n};\n\nuse byte_string::ByteStr;\nuse bytes::{BufMut, Bytes, BytesMut};\nuse futures::ready;\nuse log::trace;\nuse tokio::io::{AsyncRead, AsyncWrite, ReadBuf};\n\nuse crate::{\n    context::Context,\n    crypto::{CipherKind, v1::Cipher},\n};\n\n/// Stream protocol error\n#[derive(thiserror::Error, Debug)]\npub enum ProtocolError {\n    #[error(transparent)]\n    IoError(#[from] io::Error),\n    #[error(\"decrypt failed\")]\n    DecryptError,\n}\n\n/// Stream protocol result\npub type ProtocolResult<T> = Result<T, ProtocolError>;\n\nimpl From<ProtocolError> for io::Error {\n    fn from(e: ProtocolError) -> Self {\n        match e {\n            ProtocolError::IoError(err) => err,\n            _ => Self::other(e),\n        }\n    }\n}\n\nenum DecryptReadState {\n    WaitIv { key: Bytes },\n    Read,\n}\n\n/// Reader wrapper that will decrypt data automatically\npub struct DecryptedReader {\n    state: DecryptReadState,\n    cipher: Option<Cipher>,\n    buffer: BytesMut,\n    method: CipherKind,\n    iv: Option<Bytes>,\n    has_handshaked: bool,\n}\n\nimpl DecryptedReader {\n    pub fn new(method: CipherKind, key: &[u8]) -> Self {\n        if method.iv_len() > 0 {\n            Self {\n                state: DecryptReadState::WaitIv {\n                    key: Bytes::copy_from_slice(key),\n                },\n                cipher: None,\n                buffer: BytesMut::with_capacity(method.iv_len()),\n                method,\n                iv: None,\n                has_handshaked: false,\n            }\n        } else {\n            Self {\n                state: DecryptReadState::Read,\n                cipher: Some(Cipher::new(method, key, &[])),\n                buffer: BytesMut::new(),\n                method,\n                iv: Some(Bytes::new()),\n                has_handshaked: false,\n            }\n        }\n    }\n\n    pub fn iv(&self) -> Option<&[u8]> {\n        self.iv.as_deref()\n    }\n\n    /// Attempt to read decrypted data from reader\n    pub fn poll_read_decrypted<S>(\n        &mut self,\n        cx: &mut task::Context<'_>,\n        context: &Context,\n        stream: &mut S,\n        buf: &mut ReadBuf<'_>,\n    ) -> Poll<ProtocolResult<()>>\n    where\n        S: AsyncRead + Unpin + ?Sized,\n    {\n        loop {\n            match self.state {\n                DecryptReadState::WaitIv { ref key } => {\n                    let key = unsafe { &*(key.as_ref() as *const _) };\n                    ready!(self.poll_read_iv(cx, context, stream, key))?;\n\n                    self.buffer.clear();\n                    self.buffer.truncate(0);\n                    self.state = DecryptReadState::Read;\n                    self.has_handshaked = true;\n                }\n                DecryptReadState::Read => {\n                    let before_n = buf.filled().len();\n                    ready!(Pin::new(stream).poll_read(cx, buf))?;\n                    let after_n = buf.filled().len();\n                    if before_n == after_n {\n                        return Ok(()).into();\n                    }\n\n                    let m = &mut buf.filled_mut()[before_n..];\n\n                    let cipher = self.cipher.as_mut().expect(\"cipher is None\");\n                    if !cipher.decrypt_packet(m) {\n                        return Err(ProtocolError::DecryptError).into();\n                    }\n\n                    return Ok(()).into();\n                }\n            }\n        }\n    }\n\n    fn poll_read_iv<S>(\n        &mut self,\n        cx: &mut task::Context<'_>,\n        context: &Context,\n        stream: &mut S,\n        key: &[u8],\n    ) -> Poll<ProtocolResult<()>>\n    where\n        S: AsyncRead + Unpin + ?Sized,\n    {\n        let iv_len = self.method.iv_len();\n\n        let n = ready!(self.poll_read_exact(cx, stream, iv_len))?;\n        if n < iv_len {\n            return Err(io::Error::from(ErrorKind::UnexpectedEof).into()).into();\n        }\n\n        let iv = &self.buffer[..iv_len];\n        context.check_nonce_replay(self.method, iv)?;\n\n        trace!(\"got stream iv {:?}\", ByteStr::new(iv));\n\n        // Stores IV\n        self.iv = Some(Bytes::copy_from_slice(iv));\n\n        let cipher = Cipher::new(self.method, key, iv);\n        self.cipher = Some(cipher);\n\n        Ok(()).into()\n    }\n\n    fn poll_read_exact<S>(&mut self, cx: &mut task::Context<'_>, stream: &mut S, size: usize) -> Poll<io::Result<usize>>\n    where\n        S: AsyncRead + Unpin + ?Sized,\n    {\n        assert!(size != 0);\n\n        while self.buffer.len() < size {\n            let remaining = size - self.buffer.len();\n            let buffer = &mut self.buffer.chunk_mut()[..remaining];\n\n            let mut read_buf =\n                ReadBuf::uninit(unsafe { slice::from_raw_parts_mut(buffer.as_mut_ptr() as *mut _, remaining) });\n            ready!(Pin::new(&mut *stream).poll_read(cx, &mut read_buf))?;\n\n            let n = read_buf.filled().len();\n            if n == 0 {\n                if !self.buffer.is_empty() {\n                    return Err(ErrorKind::UnexpectedEof.into()).into();\n                } else {\n                    return Ok(0).into();\n                }\n            }\n\n            unsafe {\n                self.buffer.advance_mut(n);\n            }\n        }\n\n        Ok(size).into()\n    }\n\n    /// Check if handshake finished\n    pub fn handshaked(&self) -> bool {\n        self.has_handshaked\n    }\n}\n\nenum EncryptWriteState {\n    AssemblePacket,\n    Writing { pos: usize },\n}\n\n/// Writer wrapper that will encrypt data automatically\npub struct EncryptedWriter {\n    cipher: Cipher,\n    buffer: BytesMut,\n    state: EncryptWriteState,\n    iv: Bytes,\n}\n\nimpl EncryptedWriter {\n    /// Creates a new EncryptedWriter\n    pub fn new(method: CipherKind, key: &[u8], nonce: &[u8]) -> Self {\n        // nonce should be sent with the first packet\n        let mut buffer = BytesMut::with_capacity(nonce.len());\n        buffer.put(nonce);\n\n        Self {\n            cipher: Cipher::new(method, key, nonce),\n            buffer,\n            state: EncryptWriteState::AssemblePacket,\n            iv: Bytes::copy_from_slice(nonce),\n        }\n    }\n\n    /// IV\n    pub fn iv(&self) -> &[u8] {\n        self.iv.as_ref()\n    }\n\n    /// Attempt to write encrypted data into the writer\n    pub fn poll_write_encrypted<S>(\n        &mut self,\n        cx: &mut task::Context<'_>,\n        stream: &mut S,\n        buf: &[u8],\n    ) -> Poll<ProtocolResult<usize>>\n    where\n        S: AsyncWrite + Unpin + ?Sized,\n    {\n        loop {\n            match self.state {\n                EncryptWriteState::AssemblePacket => {\n                    let n = self.buffer.len();\n                    self.buffer.put_slice(buf);\n                    self.cipher.encrypt_packet(&mut self.buffer[n..]);\n                    self.state = EncryptWriteState::Writing { pos: 0 };\n                }\n                EncryptWriteState::Writing { ref mut pos } => {\n                    while *pos < self.buffer.len() {\n                        let n = ready!(Pin::new(&mut *stream).poll_write(cx, &self.buffer[*pos..]))?;\n                        if n == 0 {\n                            return Err(io::Error::from(ErrorKind::UnexpectedEof).into()).into();\n                        }\n                        *pos += n;\n                    }\n\n                    // Reset state\n                    self.state = EncryptWriteState::AssemblePacket;\n                    self.buffer.clear();\n\n                    return Ok(buf.len()).into();\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/relay/tcprelay/utils.rs",
    "content": "//! Utilities for TCP relay\n//!\n//! The `CopyBuffer`, `Copy` and `CopyBidirection` are borrowed from the [tokio](https://github.com/tokio-rs/tokio) project.\n//! LICENSE MIT\n\nuse std::{\n    fmt::{self, Debug},\n    future::Future,\n    io,\n    pin::Pin,\n    task::{Context, Poll},\n};\n\nuse futures::ready;\nuse log::{debug, trace};\nuse pin_project::pin_project;\nuse tokio::io::{AsyncRead, AsyncWrite, ReadBuf};\n\nuse crate::crypto::{CipherCategory, CipherKind};\n\nstruct CopyBuffer {\n    read_done: bool,\n    pos: usize,\n    cap: usize,\n    amt: u64,\n    buf: Box<[u8]>,\n}\n\nimpl Debug for CopyBuffer {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        f.debug_struct(\"CopyBuffer\")\n            .field(\"read_done\", &self.read_done)\n            .field(\"pos\", &self.pos)\n            .field(\"cap\", &self.cap)\n            .field(\"amt\", &self.amt)\n            .finish_non_exhaustive()\n    }\n}\n\nimpl CopyBuffer {\n    fn new(buffer_size: usize) -> Self {\n        Self {\n            read_done: false,\n            pos: 0,\n            cap: 0,\n            amt: 0,\n            buf: vec![0; buffer_size].into_boxed_slice(),\n        }\n    }\n\n    fn poll_copy<R, W>(\n        &mut self,\n        cx: &mut Context<'_>,\n        mut reader: Pin<&mut R>,\n        mut writer: Pin<&mut W>,\n    ) -> Poll<io::Result<u64>>\n    where\n        R: AsyncRead + Unpin + ?Sized,\n        W: AsyncWrite + Unpin + ?Sized,\n    {\n        loop {\n            // If our buffer is empty, then we need to read some data to\n            // continue.\n            if self.pos == self.cap && !self.read_done {\n                let me = &mut *self;\n                let mut buf = ReadBuf::new(&mut me.buf);\n                ready!(reader.as_mut().poll_read(cx, &mut buf))?;\n                let n = buf.filled().len();\n                if n == 0 {\n                    self.read_done = true;\n                } else {\n                    self.pos = 0;\n                    self.cap = n;\n                }\n            }\n\n            // If our buffer has some data, let's write it out!\n            while self.pos < self.cap {\n                let me = &mut *self;\n                let i = ready!(writer.as_mut().poll_write(cx, &me.buf[me.pos..me.cap]))?;\n                if i == 0 {\n                    return Poll::Ready(Err(io::Error::new(\n                        io::ErrorKind::WriteZero,\n                        \"write zero byte into writer\",\n                    )));\n                } else {\n                    self.pos += i;\n                    self.amt += i as u64;\n                }\n            }\n\n            // If we've written all the data and we've seen EOF, flush out the\n            // data and finish the transfer.\n            if self.pos == self.cap && self.read_done {\n                ready!(writer.as_mut().poll_flush(cx))?;\n                return Poll::Ready(Ok(self.amt));\n            }\n        }\n    }\n}\n\n/// A future that asynchronously copies the entire contents of a reader into a\n/// writer.\n#[derive(Debug)]\n#[pin_project]\n#[must_use = \"futures do nothing unless you `.await` or poll them\"]\nstruct Copy<'a, R: ?Sized, W: ?Sized> {\n    #[pin]\n    reader: &'a mut R,\n    #[pin]\n    writer: &'a mut W,\n    buf: CopyBuffer,\n}\n\nimpl<R, W> Future for Copy<'_, R, W>\nwhere\n    R: AsyncRead + Unpin + ?Sized,\n    W: AsyncWrite + Unpin + ?Sized,\n{\n    type Output = io::Result<u64>;\n\n    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<u64>> {\n        let this = self.project();\n        this.buf.poll_copy(cx, this.reader, this.writer)\n    }\n}\n\n/// Copy data from encrypted reader to plain writer\npub async fn copy_from_encrypted<ER, PW>(method: CipherKind, reader: &mut ER, writer: &mut PW) -> io::Result<u64>\nwhere\n    ER: AsyncRead + Unpin + ?Sized,\n    PW: AsyncWrite + Unpin + ?Sized,\n{\n    Copy {\n        reader,\n        writer,\n        buf: CopyBuffer::new(plain_read_buffer_size(method)),\n    }\n    .await\n}\n\n/// Copy data from plain reader to encrypted writer\npub async fn copy_to_encrypted<PR, EW>(method: CipherKind, reader: &mut PR, writer: &mut EW) -> io::Result<u64>\nwhere\n    PR: AsyncRead + Unpin + ?Sized,\n    EW: AsyncWrite + Unpin + ?Sized,\n{\n    Copy {\n        reader,\n        writer,\n        buf: CopyBuffer::new(plain_read_buffer_size(method)),\n    }\n    .await\n}\n\nfn plain_read_buffer_size(method: CipherKind) -> usize {\n    match method.category() {\n        #[cfg(feature = \"aead-cipher\")]\n        CipherCategory::Aead => super::aead::MAX_PACKET_SIZE,\n        #[cfg(feature = \"stream-cipher\")]\n        CipherCategory::Stream => 1 << 14,\n        CipherCategory::None => 1 << 14,\n        #[cfg(feature = \"aead-cipher-2022\")]\n        CipherCategory::Aead2022 => super::aead_2022::MAX_PACKET_SIZE,\n    }\n}\n\n/// Create a buffer for reading from plain channel (not encrypted), for copying data into encrypted channel\n#[inline]\npub fn alloc_plain_read_buffer(method: CipherKind) -> Box<[u8]> {\n    vec![0u8; plain_read_buffer_size(method)].into_boxed_slice()\n}\n\n#[derive(Debug)]\nenum TransferState {\n    Running(CopyBuffer),\n    ShuttingDown(u64),\n    Done(u64),\n}\n\n#[pin_project(project = CopyBidirectionalProj)]\nstruct CopyBidirectional<'a, A: ?Sized, B: ?Sized> {\n    #[pin]\n    a: &'a mut A,\n    #[pin]\n    b: &'a mut B,\n    a_to_b: TransferState,\n    b_to_a: TransferState,\n}\n\nfn transfer_one_direction<A, B>(\n    cx: &mut Context<'_>,\n    state: &mut TransferState,\n    mut r: Pin<&mut A>,\n    mut w: Pin<&mut B>,\n) -> Poll<io::Result<u64>>\nwhere\n    A: AsyncRead + AsyncWrite + Unpin + ?Sized,\n    B: AsyncRead + AsyncWrite + Unpin + ?Sized,\n{\n    loop {\n        match state {\n            TransferState::Running(buf) => {\n                let count = ready!(buf.poll_copy(cx, r.as_mut(), w.as_mut()))?;\n                *state = TransferState::ShuttingDown(count);\n            }\n            TransferState::ShuttingDown(count) => {\n                ready!(w.as_mut().poll_shutdown(cx))?;\n                *state = TransferState::Done(*count);\n            }\n            TransferState::Done(count) => return Poll::Ready(Ok(*count)),\n        }\n    }\n}\n\nimpl<A, B> CopyBidirectional<'_, A, B>\nwhere\n    A: AsyncRead + AsyncWrite + Unpin + ?Sized,\n    B: AsyncRead + AsyncWrite + Unpin + ?Sized,\n{\n    #[inline(always)]\n    fn poll_impl(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<(u64, u64)>> {\n        // Unpack self into mut refs to each field to avoid borrow check issues.\n        let CopyBidirectionalProj {\n            mut a,\n            mut b,\n            a_to_b,\n            b_to_a,\n        } = self.project();\n\n        let poll_a_to_b = transfer_one_direction(cx, a_to_b, a.as_mut(), b.as_mut())?;\n        let poll_b_to_a = transfer_one_direction(cx, b_to_a, b.as_mut(), a.as_mut())?;\n\n        // It is not a problem if ready! returns early because transfer_one_direction for the\n        // other direction will keep returning TransferState::Done(count) in future calls to poll\n        let a_to_b = ready!(poll_a_to_b);\n        let b_to_a = ready!(poll_b_to_a);\n\n        Poll::Ready(Ok((a_to_b, b_to_a)))\n    }\n}\n\nimpl<A, B> Future for CopyBidirectional<'_, A, B>\nwhere\n    A: AsyncRead + AsyncWrite + Unpin + ?Sized,\n    B: AsyncRead + AsyncWrite + Unpin + ?Sized,\n{\n    type Output = io::Result<(u64, u64)>;\n\n    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {\n        match self.as_mut().poll_impl(cx) {\n            Poll::Pending => Poll::Pending,\n            Poll::Ready(r) => {\n                match r {\n                    Ok(..) => {\n                        trace!(\n                            \"copy bidirection ends, a_to_b: {:?}, b_to_a: {:?}\",\n                            self.a_to_b, self.b_to_a\n                        );\n                    }\n                    Err(ref err) => {\n                        debug!(\n                            \"copy bidirection ends with error: {}, a_to_b: {:?}, b_to_a: {:?}\",\n                            err, self.a_to_b, self.b_to_a\n                        );\n                    }\n                }\n                Poll::Ready(r)\n            }\n        }\n    }\n}\n\n/// Copies data in both directions between `encrypted` stream and `plain` stream.\n///\n/// This function returns a future that will read from both streams,\n/// writing any data read to the opposing stream.\n/// This happens in both directions concurrently.\n///\n/// If an EOF is observed on one stream, [`shutdown()`] will be invoked on\n/// the other, and reading from that stream will stop. Copying of data in\n/// the other direction will continue.\n///\n/// The future will complete successfully once both directions of communication has been shut down.\n/// A direction is shut down when the reader reports EOF,\n/// at which point [`shutdown()`] is called on the corresponding writer. When finished,\n/// it will return a tuple of the number of bytes copied from encrypted to plain\n/// and the number of bytes copied from plain to encrypted, in that order.\n///\n/// [`shutdown()`]: tokio::io::AsyncWriteExt::shutdown\n///\n/// # Errors\n///\n/// The future will immediately return an error if any IO operation on `encrypted`\n/// or `plain` returns an error. Some data read from either stream may be lost (not\n/// written to the other stream) in this case.\n///\n/// # Return value\n///\n/// Returns a tuple of bytes copied `encrypted` to `plain` and bytes copied `plain` to `encrypted`.\npub async fn copy_encrypted_bidirectional<E, P>(\n    method: CipherKind,\n    encrypted: &mut E,\n    plain: &mut P,\n) -> io::Result<(u64, u64)>\nwhere\n    E: AsyncRead + AsyncWrite + Unpin + ?Sized,\n    P: AsyncRead + AsyncWrite + Unpin + ?Sized,\n{\n    CopyBidirectional {\n        a: encrypted,\n        b: plain,\n        a_to_b: TransferState::Running(CopyBuffer::new(plain_read_buffer_size(method))),\n        b_to_a: TransferState::Running(CopyBuffer::new(plain_read_buffer_size(method))),\n    }\n    .await\n}\n\n/// Copies data in both directions\n///\n/// This function returns a future that will read from both streams,\n/// writing any data read to the opposing stream.\n/// This happens in both directions concurrently.\n///\n/// If an EOF is observed on one stream, [`shutdown()`] will be invoked on\n/// the other, and reading from that stream will stop. Copying of data in\n/// the other direction will continue.\n///\n/// The future will complete successfully once both directions of communication has been shut down.\n/// A direction is shut down when the reader reports EOF,\n/// at which point [`shutdown()`] is called on the corresponding writer. When finished,\n/// it will return a tuple of the number of bytes copied from encrypted to plain\n/// and the number of bytes copied from plain to encrypted, in that order.\n///\n/// [`shutdown()`]: tokio::io::AsyncWriteExt::shutdown\n///\n/// # Errors\n///\n/// The future will immediately return an error if any IO operation any of the streams\n/// returns an error. Some data read from either stream may be lost (not\n/// written to the other stream) in this case.\n///\n/// # Return value\n///\n/// Returns a tuple of bytes copied on both directions\npub async fn copy_bidirectional<A, B>(a: &mut A, b: &mut B) -> io::Result<(u64, u64)>\nwhere\n    A: AsyncRead + AsyncWrite + Unpin + ?Sized,\n    B: AsyncRead + AsyncWrite + Unpin + ?Sized,\n{\n    CopyBidirectional {\n        a,\n        b,\n        a_to_b: TransferState::Running(CopyBuffer::new(8192)),\n        b_to_a: TransferState::Running(CopyBuffer::new(8192)),\n    }\n    .await\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/relay/udprelay/aead.rs",
    "content": "//! Shadowsocks UDP AEAD protocol\n//!\n//! Payload with AEAD cipher\n//!\n//! ```plain\n//! UDP (after encryption, *ciphertext*)\n//! +--------+-----------+-----------+\n//! | NONCE  |  *Data*   |  Data_TAG |\n//! +--------+-----------+-----------+\n//! | Fixed  | Variable  |   Fixed   |\n//! +--------+-----------+-----------+\n//! ```\n\nuse std::io::Cursor;\n\nuse byte_string::ByteStr;\nuse bytes::{BufMut, BytesMut};\nuse log::trace;\n\nuse crate::{\n    context::Context,\n    crypto::{CipherKind, v1::Cipher},\n    relay::socks5::{Address, Error as Socks5Error},\n};\n\n/// AEAD protocol error\n#[derive(thiserror::Error, Debug)]\npub enum ProtocolError {\n    #[error(\"packet too short for salt, at least {0} bytes, but only {1} bytes\")]\n    PacketTooShortForSalt(usize, usize),\n    #[error(\"packet too short for tag, at least {0} bytes, but only {1} bytes\")]\n    PacketTooShortForTag(usize, usize),\n    #[error(\"invalid address in packet, {0}\")]\n    InvalidAddress(Socks5Error),\n    #[error(\"decrypt payload failed\")]\n    DecryptPayloadError,\n}\n\n/// AEAD protocol result\npub type ProtocolResult<T> = Result<T, ProtocolError>;\n\n/// Encrypt UDP AEAD protocol packet\npub fn encrypt_payload_aead(\n    context: &Context,\n    method: CipherKind,\n    key: &[u8],\n    addr: &Address,\n    payload: &[u8],\n    dst: &mut BytesMut,\n) {\n    let salt_len = method.salt_len();\n    let addr_len = addr.serialized_len();\n\n    // Packet = IV + ADDRESS + PAYLOAD + TAG\n    dst.reserve(salt_len + addr_len + payload.len() + method.tag_len());\n\n    // Generate IV\n    dst.resize(salt_len, 0);\n    let salt = &mut dst[..salt_len];\n\n    if salt_len > 0 {\n        context.generate_nonce(method, salt, false);\n        trace!(\"UDP packet generated aead salt {:?}\", ByteStr::new(salt));\n    }\n\n    let mut cipher = Cipher::new(method, key, salt);\n\n    addr.write_to_buf(dst);\n    dst.put_slice(payload);\n\n    unsafe {\n        dst.advance_mut(method.tag_len());\n    }\n\n    let m = &mut dst[salt_len..];\n    cipher.encrypt_packet(m);\n}\n\n/// Decrypt UDP AEAD protocol packet\npub fn decrypt_payload_aead(\n    _context: &Context,\n    method: CipherKind,\n    key: &[u8],\n    payload: &mut [u8],\n) -> ProtocolResult<(usize, Address)> {\n    let plen = payload.len();\n    let salt_len = method.salt_len();\n    if plen < salt_len {\n        return Err(ProtocolError::PacketTooShortForSalt(salt_len, plen));\n    }\n\n    let (salt, data) = payload.split_at_mut(salt_len);\n    // context.check_nonce_replay(salt)?;\n\n    trace!(\"UDP packet got AEAD salt {:?}\", ByteStr::new(salt));\n\n    let mut cipher = Cipher::new(method, key, salt);\n    let tag_len = cipher.tag_len();\n\n    if data.len() < tag_len {\n        return Err(ProtocolError::PacketTooShortForTag(tag_len, data.len()));\n    }\n\n    if !cipher.decrypt_packet(data) {\n        return Err(ProtocolError::DecryptPayloadError);\n    }\n\n    // Truncate TAG\n    let data_len = data.len() - tag_len;\n    let data = &mut data[..data_len];\n\n    let (dn, addr) = parse_packet(data)?;\n\n    let data_length = data_len - dn;\n    let data_start_idx = salt_len + dn;\n    let data_end_idx = data_start_idx + data_length;\n\n    payload.copy_within(data_start_idx..data_end_idx, 0);\n\n    Ok((data_length, addr))\n}\n\n#[inline]\nfn parse_packet(buf: &[u8]) -> ProtocolResult<(usize, Address)> {\n    let mut cur = Cursor::new(buf);\n    match Address::read_cursor(&mut cur) {\n        Ok(address) => {\n            let pos = cur.position() as usize;\n            Ok((pos, address))\n        }\n        Err(err) => Err(ProtocolError::InvalidAddress(err)),\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/relay/udprelay/aead_2022.rs",
    "content": "//! Shadowsocks UDP AEAD 2022 protocol\n//!\n//! Payload with AEAD 2022 cipher\n//!\n//! Client -> Server\n//!\n//! ```plain\n//! +-------+-------+-------+-------+-------+-------+-------+-------+\n//! | Client Session ID                                             |\n//! +-------+-------+-------+-------+-------+-------+-------+-------+\n//! | Packet ID                                                     |\n//! +-------+-------+-------+-------+-------+-------+-------+-------+\n//! | TYPE  |\n//! +-------+-------+-------+-------+-------+-------+-------+-------+\n//! | UNIX Epoch Timestamp                                          |\n//! +-------+-------+-------+-------+-------+-------+-------+-------+\n//! | PADDING SIZE  | Padding (Variable ...)\n//! +-------+-------+-------+-------+-------+-------+-------+-------+\n//! | Address (Variable ...)\n//! +-------+-------+-------+-------+-------+-------+-------+-------+\n//! | Payload (Variable ...)\n//! +-------+-------+-------+-------+-------+-------+-------+-------+\n//! ```\n//!\n//! Server -> Client\n//!\n//! ```plain\n//! +-------+-------+-------+-------+-------+-------+-------+-------+\n//! | Server Session ID                                             |\n//! +-------+-------+-------+-------+-------+-------+-------+-------+\n//! | Packet ID                                                     |\n//! +-------+-------+-------+-------+-------+-------+-------+-------+\n//! | TYPE  |\n//! +-------+-------+-------+-------+-------+-------+-------+-------+\n//! | UNIX Epoch Timestamp                                          |\n//! +-------+-------+-------+-------+-------+-------+-------+-------+\n//! | Client Session ID                                             |\n//! +-------+-------+-------+-------+-------+-------+-------+-------+\n//! | PADDING SIZE  | Padding (Variable ...)\n//! +-------+-------+-------+-------+-------+-------+-------+-------+\n//! | Address (Variable ...)\n//! +-------+-------+-------+-------+-------+-------+-------+-------+\n//! | Payload (Variable ...)\n//! +-------+-------+-------+-------+-------+-------+-------+-------+\n//! ```\n\nuse std::{\n    cell::RefCell,\n    cmp::Ordering,\n    collections::hash_map::DefaultHasher,\n    hash::{Hash, Hasher},\n    io::{self, Cursor, Seek, SeekFrom},\n    rc::Rc,\n    slice,\n    sync::Arc,\n    time::{Duration, SystemTime},\n};\n\nuse aes::{\n    Aes128, Aes256, Block,\n    cipher::{BlockDecrypt, BlockEncrypt, KeyInit},\n};\nuse byte_string::ByteStr;\nuse bytes::{Buf, BufMut, Bytes, BytesMut};\nuse log::{error, trace};\nuse lru_time_cache::LruCache;\n\n#[cfg(feature = \"aead-cipher-2022-extra\")]\nuse crate::crypto::v2::udp::ChaCha8Poly1305Cipher;\nuse crate::{\n    config::{ServerUser, ServerUserManager, method_support_eih},\n    context::Context,\n    crypto::{\n        CipherKind,\n        v2::udp::{ChaCha20Poly1305Cipher, UdpCipher},\n    },\n    relay::{\n        get_aead_2022_padding_size,\n        socks5::{Address, Error as Socks5Error},\n    },\n};\n\nuse super::options::UdpSocketControlData;\n\nconst CLIENT_SOCKET_TYPE: u8 = 0;\nconst SERVER_SOCKET_TYPE: u8 = 1;\nconst SERVER_PACKET_TIMESTAMP_MAX_DIFF: u64 = 30;\n\n/// AEAD 2022 protocol error\n#[derive(thiserror::Error, Debug)]\npub enum ProtocolError {\n    #[error(\"packet too short, at least {0} bytes, but found {1} bytes\")]\n    PacketTooShort(usize, usize),\n    #[error(\"invalid address in packet, {0}\")]\n    InvalidAddress(Socks5Error),\n    #[error(\"decrypt payload error\")]\n    DecryptPayloadError,\n    #[error(\"invalid client user identity {:?}\", ByteStr::new(.0))]\n    InvalidClientUser(Bytes),\n    #[error(\"invalid socket type, expecting {0:#x}, but found {1:#x}\")]\n    InvalidSocketType(u8, u8),\n    #[error(\"invalid timestamp {0} - now {1} = {ts_diff}\", ts_diff = *.0 as i64 - *.1 as i64)]\n    InvalidTimestamp(u64, u64),\n    #[error(transparent)]\n    IoError(#[from] io::Error),\n}\n\n/// AEAD 2022 protocol result\npub type ProtocolResult<T> = Result<T, ProtocolError>;\n\n#[derive(PartialEq, Eq, Hash, Clone, Debug)]\nstruct CipherKey {\n    method: CipherKind,\n    key: usize,\n    session_id: u64,\n}\n\nimpl PartialOrd for CipherKey {\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        Some(self.cmp(other))\n    }\n}\n\nimpl Ord for CipherKey {\n    fn cmp(&self, other: &Self) -> Ordering {\n        let hash1 = {\n            let mut hasher = DefaultHasher::new();\n            self.hash(&mut hasher);\n            hasher.finish()\n        };\n        let hash2 = {\n            let mut hasher = DefaultHasher::new();\n            other.hash(&mut hasher);\n            hasher.finish()\n        };\n\n        hash1.cmp(&hash2)\n    }\n}\n\nconst CIPHER_CACHE_DURATION: Duration = Duration::from_secs(30);\nconst CIPHER_CACHE_LIMIT: usize = 102400;\n\nthread_local! {\n    static CIPHER_CACHE: RefCell<LruCache<CipherKey, Rc<UdpCipher>>> =\n        RefCell::new(LruCache::with_expiry_duration_and_capacity(CIPHER_CACHE_DURATION, CIPHER_CACHE_LIMIT));\n}\n\n#[inline]\npub fn get_now_timestamp() -> u64 {\n    match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) {\n        Ok(n) => n.as_secs(),\n        Err(_) => panic!(\"SystemTime::now() is before UNIX Epoch!\"),\n    }\n}\n\nfn get_cipher(method: CipherKind, key: &[u8], session_id: u64) -> Rc<UdpCipher> {\n    CIPHER_CACHE.with(|cache| {\n        let mut cache = cache.borrow_mut();\n\n        let cache_key = CipherKey {\n            method,\n            // The key is stored in ServerConfig structure, so the address of it won't change.\n            key: key.as_ptr() as usize,\n            session_id,\n        };\n\n        cache\n            .entry(cache_key)\n            .or_insert_with(|| Rc::new(UdpCipher::new(method, key, session_id)))\n            .clone()\n    })\n}\n\nfn encrypt_message(\n    _context: &Context,\n    method: CipherKind,\n    ipsk: &[u8],\n    key: &[u8],\n    packet: &mut BytesMut,\n    session_id: u64,\n    eih_len: usize,\n) {\n    unsafe {\n        packet.advance_mut(method.tag_len());\n    }\n\n    match method {\n        CipherKind::AEAD2022_BLAKE3_CHACHA20_POLY1305 => {\n            // ChaCha20-Poly1305 uses PSK as key, prepended nonce in packet\n            let nonce_size = ChaCha20Poly1305Cipher::nonce_size();\n\n            let cipher = get_cipher(method, key, session_id);\n\n            let (nonce, message) = packet.split_at_mut(nonce_size);\n            cipher.encrypt_packet(nonce, message);\n        }\n        #[cfg(feature = \"aead-cipher-2022-extra\")]\n        CipherKind::AEAD2022_BLAKE3_CHACHA8_POLY1305 => {\n            // ChaCha8-Poly1305 uses PSK as key, prepended nonce in packet\n            let nonce_size = ChaCha8Poly1305Cipher::nonce_size();\n\n            let cipher = get_cipher(method, key, session_id);\n\n            let (nonce, message) = packet.split_at_mut(nonce_size);\n            cipher.encrypt_packet(nonce, message);\n        }\n        CipherKind::AEAD2022_BLAKE3_AES_128_GCM | CipherKind::AEAD2022_BLAKE3_AES_256_GCM => {\n            // AES-*-GCM uses derived key, and part of the packet header as nonce\n\n            let cipher = get_cipher(method, key, session_id);\n\n            // Encrypt the rest of the packet with AEAD cipher (AES-*-GCM)\n            let (packet_header, mut message) = packet.split_at_mut(16);\n            let nonce = &packet_header[4..16];\n\n            if eih_len > 0 {\n                message = &mut message[eih_len..];\n            }\n\n            cipher.encrypt_packet(nonce, message);\n\n            // [SessionID + PacketID] is encrypted with AES-ECB with PSK\n            // No padding is required because these 2 fields are 128-bits, which is exactly the same as AES's block size\n            match method {\n                CipherKind::AEAD2022_BLAKE3_AES_128_GCM => {\n                    let cipher = Aes128::new_from_slice(ipsk).expect(\"AES-128 init\");\n                    let block = Block::from_mut_slice(packet_header);\n                    cipher.encrypt_block(block);\n                }\n                CipherKind::AEAD2022_BLAKE3_AES_256_GCM => {\n                    let cipher = Aes256::new_from_slice(ipsk).expect(\"AES-256 init\");\n                    let block = Block::from_mut_slice(packet_header);\n                    cipher.encrypt_block(block);\n                }\n                _ => unreachable!(\"{} is not an AES-*-GCM cipher\", method),\n            }\n        }\n        _ => unreachable!(\"{} is not an AEAD 2022 cipher\", method),\n    }\n}\n\nfn decrypt_message(\n    _context: &Context,\n    method: CipherKind,\n    key: &[u8],\n    packet: &mut [u8],\n    user_manager: Option<&ServerUserManager>,\n) -> ProtocolResult<Option<Arc<ServerUser>>> {\n    let mut client_user = None;\n\n    match method {\n        CipherKind::AEAD2022_BLAKE3_CHACHA20_POLY1305 => {\n            // ChaCha20-Poly1305 uses PSK as key, prepended nonce in packet\n            let nonce_size = ChaCha20Poly1305Cipher::nonce_size();\n\n            let (nonce, message) = packet.split_at_mut(nonce_size);\n\n            // NOTE: ChaCha20-Poly1305's session_id is not required because it uses PSK directly\n            //\n            // But still, we get the session_id for cache\n            let session_id = {\n                let session_id_buf = &message[0..8];\n                let session_id_slice: &[u64] = unsafe { slice::from_raw_parts(session_id_buf.as_ptr() as *const _, 1) };\n                u64::from_be(session_id_slice[0])\n            };\n\n            let cipher = get_cipher(method, key, session_id);\n\n            if !cipher.decrypt_packet(nonce, message) {\n                return Err(ProtocolError::DecryptPayloadError);\n            }\n        }\n        #[cfg(feature = \"aead-cipher-2022-extra\")]\n        CipherKind::AEAD2022_BLAKE3_CHACHA8_POLY1305 => {\n            // ChaCha8-Poly1305 uses PSK as key, prepended nonce in packet\n            let nonce_size = ChaCha8Poly1305Cipher::nonce_size();\n\n            let (nonce, message) = packet.split_at_mut(nonce_size);\n\n            // NOTE: ChaCha20-Poly1305's session_id is not required because it uses PSK directly\n            //\n            // But still, we get the session_id for cache\n            let session_id = {\n                let session_id_buf = &message[0..8];\n                let session_id_slice: &[u64] = unsafe { slice::from_raw_parts(session_id_buf.as_ptr() as *const _, 1) };\n                u64::from_be(session_id_slice[0])\n            };\n\n            let cipher = get_cipher(method, key, session_id);\n\n            if !cipher.decrypt_packet(nonce, message) {\n                return Err(ProtocolError::DecryptPayloadError);\n            }\n        }\n        CipherKind::AEAD2022_BLAKE3_AES_128_GCM | CipherKind::AEAD2022_BLAKE3_AES_256_GCM => {\n            // AES-*-GCM uses derived key, and part of the packet header as nonce\n            //\n            // Decrypt the header block first\n            // [SessionID + PacketID] is encrypted with AES-ECB with PSK\n            // No padding is required because these 2 fields are 128-bits, which is exactly the same as AES's block size\n\n            let (packet_header, mut message) = packet.split_at_mut(16);\n\n            match method {\n                CipherKind::AEAD2022_BLAKE3_AES_128_GCM => {\n                    let cipher = Aes128::new_from_slice(key).expect(\"AES-128 init\");\n                    let block = Block::from_mut_slice(packet_header);\n                    cipher.decrypt_block(block);\n                }\n                CipherKind::AEAD2022_BLAKE3_AES_256_GCM => {\n                    let cipher = Aes256::new_from_slice(key).expect(\"AES-256 init\");\n                    let block = Block::from_mut_slice(packet_header);\n                    cipher.decrypt_block(block);\n                }\n                _ => unreachable!(\"{} is not an AES-*-GCM cipher\", method),\n            }\n\n            // Session ID is the first 64-bits\n\n            let session_id = {\n                let session_id_buf = &packet_header[0..8];\n                let session_id_slice: &[u64] = unsafe { slice::from_raw_parts(session_id_buf.as_ptr() as *const _, 1) };\n                u64::from_be(session_id_slice[0])\n            };\n\n            let cipher = if method_support_eih(method) {\n                if let Some(user_manager) = user_manager {\n                    // Extensible Identity Header\n                    // https://github.com/Shadowsocks-NET/shadowsocks-specs/blob/main/2022-2-shadowsocks-2022-extensible-identity-headers.md\n\n                    let (eih, remain_message) = message.split_at_mut(16);\n                    message = remain_message;\n\n                    let session_id_packet_id = &packet_header[0..16];\n\n                    trace!(\n                        \"server EIH {:?}, session_id_packet_id: {:?}\",\n                        ByteStr::new(eih),\n                        ByteStr::new(session_id_packet_id)\n                    );\n\n                    match method {\n                        CipherKind::AEAD2022_BLAKE3_AES_128_GCM => {\n                            let cipher = Aes128::new_from_slice(key).expect(\"AES-128 init\");\n                            cipher.decrypt_block(Block::from_mut_slice(eih));\n                        }\n                        CipherKind::AEAD2022_BLAKE3_AES_256_GCM => {\n                            let cipher = Aes256::new_from_slice(key).expect(\"AES-256 init\");\n                            cipher.decrypt_block(Block::from_mut_slice(eih))\n                        }\n                        _ => unreachable!(\"{} doesn't support EIH\", method),\n                    }\n\n                    for i in 0..16 {\n                        eih[i] ^= session_id_packet_id[i];\n                    }\n\n                    match user_manager.clone_user_by_hash(eih) {\n                        None => {\n                            error!(\"user with identity {:?} not found\", ByteStr::new(eih));\n                            return Err(ProtocolError::InvalidClientUser(Bytes::copy_from_slice(eih)));\n                        }\n                        Some(user) => {\n                            trace!(\"{:?} chosen by EIH\", user);\n                            let cipher = get_cipher(method, user.key(), session_id);\n                            client_user = Some(user);\n                            cipher\n                        }\n                    }\n                } else {\n                    get_cipher(method, key, session_id)\n                }\n            } else {\n                get_cipher(method, key, session_id)\n            };\n\n            let nonce = &packet_header[4..16];\n            if !cipher.decrypt_packet(nonce, message) {\n                return Err(ProtocolError::DecryptPayloadError);\n            }\n        }\n        _ => unreachable!(\"{} is not an AEAD 2022 cipher\", method),\n    }\n\n    Ok(client_user)\n}\n\n#[inline]\nfn get_nonce_len(method: CipherKind) -> usize {\n    match method {\n        CipherKind::AEAD2022_BLAKE3_AES_128_GCM | CipherKind::AEAD2022_BLAKE3_AES_256_GCM => 0,\n        CipherKind::AEAD2022_BLAKE3_CHACHA20_POLY1305 => method.nonce_len(),\n        #[cfg(feature = \"aead-cipher-2022-extra\")]\n        CipherKind::AEAD2022_BLAKE3_CHACHA8_POLY1305 => method.nonce_len(),\n        _ => unreachable!(\"{} is not an AEAD 2022 cipher\", method),\n    }\n}\n\n/// Encrypt `Client -> Server` UDP AEAD protocol packet\n#[allow(clippy::too_many_arguments)]\npub fn encrypt_client_payload_aead_2022(\n    context: &Context,\n    method: CipherKind,\n    key: &[u8],\n    addr: &Address,\n    control: &UdpSocketControlData,\n    identity_keys: &[Bytes],\n    payload: &[u8],\n    dst: &mut BytesMut,\n) {\n    let padding_size = get_aead_2022_padding_size(payload);\n    let nonce_size = get_nonce_len(method);\n    let require_eih = method_support_eih(method) && !identity_keys.is_empty();\n    let eih_size = if require_eih { identity_keys.len() * 16 } else { 0 };\n\n    dst.reserve(\n        nonce_size\n            + 8\n            + 8\n            + eih_size\n            + 1\n            + 8\n            + 2\n            + padding_size\n            + addr.serialized_len()\n            + payload.len()\n            + method.tag_len(),\n    );\n\n    // Generate IV\n    if nonce_size > 0 {\n        unsafe {\n            dst.advance_mut(nonce_size);\n        }\n        let nonce = &mut dst[..nonce_size];\n\n        context.generate_nonce(method, nonce, false);\n        trace!(\"UDP packet generated aead nonce {:?}\", ByteStr::new(nonce));\n    }\n\n    // Add header fields\n    dst.put_u64(control.client_session_id);\n    dst.put_u64(control.packet_id);\n\n    // Extensible Identity Header\n    // https://github.com/Shadowsocks-NET/shadowsocks-specs/blob/main/2022-2-shadowsocks-2022-extensible-identity-headers.md\n    if require_eih {\n        #[inline]\n        fn make_eih(\n            method: CipherKind,\n            ipsk: &[u8],\n            ipskn: &[u8],\n            session_id_packet_id: &[u8],\n            identity_header: &mut [u8; 16],\n        ) {\n            let ipskn_hash = blake3::hash(ipskn);\n            let plain_text = &ipskn_hash.as_bytes()[0..16];\n\n            identity_header.copy_from_slice(plain_text);\n\n            for i in 0..16 {\n                identity_header[i] ^= session_id_packet_id[i];\n            }\n\n            match method {\n                CipherKind::AEAD2022_BLAKE3_AES_128_GCM => {\n                    let cipher = Aes128::new_from_slice(ipsk).expect(\"AES-128 init\");\n                    cipher.encrypt_block(Block::from_mut_slice(identity_header));\n                }\n                CipherKind::AEAD2022_BLAKE3_AES_256_GCM => {\n                    let cipher = Aes256::new_from_slice(ipsk).expect(\"AES-256 init\");\n                    cipher.encrypt_block(Block::from_mut_slice(identity_header));\n                }\n                _ => unreachable!(\"{} doesn't support EIH\", method),\n            }\n\n            trace!(\n                \"client EIH {:?}, hash: {:?}\",\n                ByteStr::new(identity_header),\n                ByteStr::new(plain_text)\n            );\n        }\n\n        for (ipsk, ipskn) in identity_keys\n            .iter()\n            .map(AsRef::as_ref)\n            .zip(identity_keys.iter().map(AsRef::as_ref).skip(1).chain(Some(key)))\n        {\n            let session_id_packet_id = &dst[nonce_size..nonce_size + 16];\n\n            let mut identity_header = [0u8; 16];\n            make_eih(method, ipsk, ipskn, session_id_packet_id, &mut identity_header);\n\n            dst.put(identity_header.as_slice());\n        }\n    }\n\n    dst.put_u8(CLIENT_SOCKET_TYPE);\n    dst.put_u64(get_now_timestamp());\n    dst.put_u16(padding_size as u16);\n    if padding_size > 0 {\n        unsafe {\n            dst.advance_mut(padding_size);\n        }\n    }\n    addr.write_to_buf(dst);\n    dst.put_slice(payload);\n\n    let ipsk = if identity_keys.is_empty() {\n        key\n    } else {\n        &identity_keys[0]\n    };\n    encrypt_message(context, method, ipsk, key, dst, control.client_session_id, eih_size);\n}\n\n/// Decrypt `Client -> Server` UDP AEAD protocol packet\npub fn decrypt_client_payload_aead_2022(\n    context: &Context,\n    method: CipherKind,\n    key: &[u8],\n    payload: &mut [u8],\n    user_manager: Option<&ServerUserManager>,\n) -> ProtocolResult<(usize, Address, UdpSocketControlData)> {\n    let nonce_len = get_nonce_len(method);\n    let tag_len = method.tag_len();\n    let require_eih = method_support_eih(method) && user_manager.is_some();\n    let eih_len = if require_eih { 16 } else { 0 };\n\n    let header_len = nonce_len + tag_len + 8 + 8 + eih_len + 1 + 8 + 2;\n    if payload.len() < header_len {\n        return Err(ProtocolError::PacketTooShort(header_len, payload.len()));\n    }\n\n    let user = decrypt_message(context, method, key, payload, user_manager)?;\n\n    let data = &payload[nonce_len..payload.len() - tag_len];\n    let mut cursor = Cursor::new(data);\n\n    let client_session_id = cursor.get_u64();\n    let packet_id = cursor.get_u64();\n\n    if require_eih {\n        cursor.advance(16);\n    }\n\n    let socket_type = cursor.get_u8();\n    if socket_type != CLIENT_SOCKET_TYPE {\n        return Err(ProtocolError::InvalidSocketType(CLIENT_SOCKET_TYPE, socket_type));\n    }\n    let timestamp = cursor.get_u64();\n\n    let now = get_now_timestamp();\n    if now.abs_diff(timestamp) > SERVER_PACKET_TIMESTAMP_MAX_DIFF {\n        return Err(ProtocolError::InvalidTimestamp(timestamp, now));\n    }\n\n    let padding_size = cursor.get_u16() as usize;\n    if padding_size > 0 {\n        cursor.seek(SeekFrom::Current(padding_size as i64))?;\n    }\n\n    let control = UdpSocketControlData {\n        client_session_id,\n        server_session_id: 0,\n        packet_id,\n        user,\n    };\n\n    let addr = match Address::read_cursor(&mut cursor) {\n        Ok(a) => a,\n        Err(err) => return Err(ProtocolError::InvalidAddress(err)),\n    };\n\n    let payload_start = cursor.position() as usize;\n    let payload_len = data.len() - payload_start;\n\n    payload.copy_within(nonce_len + payload_start..nonce_len + payload_start + payload_len, 0);\n\n    Ok((payload_len, addr, control))\n}\n\n/// Encrypt `Server -> Client` UDP AEAD protocol packet\npub fn encrypt_server_payload_aead_2022(\n    context: &Context,\n    method: CipherKind,\n    key: &[u8],\n    addr: &Address,\n    control: &UdpSocketControlData,\n    payload: &[u8],\n    dst: &mut BytesMut,\n) {\n    let padding_size = get_aead_2022_padding_size(payload);\n    let nonce_size = get_nonce_len(method);\n\n    dst.reserve(\n        nonce_size + 8 + 8 + 1 + 8 + 8 + 2 + padding_size + addr.serialized_len() + payload.len() + method.tag_len(),\n    );\n\n    // Generate IV\n    if nonce_size > 0 {\n        unsafe {\n            dst.advance_mut(nonce_size);\n        }\n        let nonce = &mut dst[..nonce_size];\n\n        context.generate_nonce(method, nonce, false);\n        trace!(\"UDP packet generated aead nonce {:?}\", ByteStr::new(nonce));\n    }\n\n    // Add header fields\n    dst.put_u64(control.server_session_id);\n    dst.put_u64(control.packet_id);\n    dst.put_u8(SERVER_SOCKET_TYPE);\n    dst.put_u64(get_now_timestamp());\n    dst.put_u64(control.client_session_id);\n    dst.put_u16(padding_size as u16);\n    if padding_size > 0 {\n        unsafe {\n            dst.advance_mut(padding_size);\n        }\n    }\n    addr.write_to_buf(dst);\n    dst.put_slice(payload);\n\n    encrypt_message(context, method, key, key, dst, control.server_session_id, 0);\n}\n\n/// Decrypt `Server -> Client` UDP AEAD protocol packet\npub fn decrypt_server_payload_aead_2022(\n    context: &Context,\n    method: CipherKind,\n    key: &[u8],\n    payload: &mut [u8],\n) -> ProtocolResult<(usize, Address, UdpSocketControlData)> {\n    let nonce_len = get_nonce_len(method);\n    let tag_len = method.tag_len();\n    let header_len = nonce_len + tag_len + 8 + 8 + 1 + 8 + 2;\n    if payload.len() < header_len {\n        return Err(ProtocolError::PacketTooShort(header_len, payload.len()));\n    }\n\n    let user = decrypt_message(context, method, key, payload, None)?;\n    debug_assert!(user.is_none(), \"server respond packet shouldn't have EIH\");\n\n    let data = &payload[nonce_len..payload.len() - tag_len];\n    let mut cursor = Cursor::new(data);\n\n    let server_session_id = cursor.get_u64();\n    let packet_id = cursor.get_u64();\n    let socket_type = cursor.get_u8();\n    if socket_type != SERVER_SOCKET_TYPE {\n        return Err(ProtocolError::InvalidSocketType(SERVER_SOCKET_TYPE, socket_type));\n    }\n    let timestamp = cursor.get_u64();\n\n    let now = get_now_timestamp();\n    if now.abs_diff(timestamp) > SERVER_PACKET_TIMESTAMP_MAX_DIFF {\n        return Err(ProtocolError::InvalidTimestamp(timestamp, now));\n    }\n\n    let client_session_id = cursor.get_u64();\n\n    let padding_size = cursor.get_u16() as usize;\n    if padding_size > 0 {\n        cursor.seek(SeekFrom::Current(padding_size as i64))?;\n    }\n\n    let control = UdpSocketControlData {\n        client_session_id,\n        server_session_id,\n        packet_id,\n        user: None,\n    };\n\n    let addr = match Address::read_cursor(&mut cursor) {\n        Ok(a) => a,\n        Err(err) => return Err(ProtocolError::InvalidAddress(err)),\n    };\n\n    let payload_start = cursor.position() as usize;\n    let payload_len = data.len() - payload_start;\n\n    payload.copy_within(nonce_len + payload_start..nonce_len + payload_start + payload_len, 0);\n\n    Ok((payload_len, addr, control))\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/relay/udprelay/compat.rs",
    "content": "use std::{\n    future::Future,\n    io,\n    net::SocketAddr,\n    ops::Deref,\n    pin::Pin,\n    task::{Context, Poll},\n};\n\nuse futures::ready;\nuse pin_project::pin_project;\nuse tokio::io::ReadBuf;\n\nuse crate::net::UdpSocket;\n\n/// A socket I/O object that can transport datagram\npub trait DatagramSocket {\n    /// Local binded address\n    fn local_addr(&self) -> io::Result<SocketAddr>;\n}\n\n/// A socket I/O object that can receive datagram\npub trait DatagramReceive {\n    /// `recv` data into `buf`\n    fn poll_recv(&self, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>) -> Poll<io::Result<()>>;\n    /// `recv` data into `buf` with source address\n    fn poll_recv_from(&self, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>) -> Poll<io::Result<SocketAddr>>;\n    /// Check if the underlying I/O object is ready for `recv`\n    fn poll_recv_ready(&self, cx: &mut Context<'_>) -> Poll<io::Result<()>>;\n}\n\n/// A socket I/O object that can send datagram\npub trait DatagramSend {\n    /// `send` data with `buf`, returning the sent bytes\n    fn poll_send(&self, cx: &mut Context<'_>, buf: &[u8]) -> Poll<io::Result<usize>>;\n    /// `send` data with `buf` to `target`, returning the sent bytes\n    fn poll_send_to(&self, cx: &mut Context<'_>, buf: &[u8], target: SocketAddr) -> Poll<io::Result<usize>>;\n    /// Check if the underlying I/O object is ready for `send`\n    fn poll_send_ready(&self, cx: &mut Context<'_>) -> Poll<io::Result<()>>;\n}\n\nimpl DatagramSocket for UdpSocket {\n    fn local_addr(&self) -> io::Result<SocketAddr> {\n        self.deref().local_addr()\n    }\n}\n\nimpl DatagramReceive for UdpSocket {\n    fn poll_recv(&self, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>) -> Poll<io::Result<()>> {\n        Self::poll_recv(self, cx, buf)\n    }\n\n    fn poll_recv_from(&self, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>) -> Poll<io::Result<SocketAddr>> {\n        Self::poll_recv_from(self, cx, buf)\n    }\n\n    fn poll_recv_ready(&self, cx: &mut Context<'_>) -> Poll<io::Result<()>> {\n        self.deref().poll_recv_ready(cx)\n    }\n}\n\nimpl DatagramSend for UdpSocket {\n    fn poll_send(&self, cx: &mut Context<'_>, buf: &[u8]) -> Poll<io::Result<usize>> {\n        Self::poll_send(self, cx, buf)\n    }\n\n    fn poll_send_to(&self, cx: &mut Context<'_>, buf: &[u8], target: SocketAddr) -> Poll<io::Result<usize>> {\n        Self::poll_send_to(self, cx, buf, target)\n    }\n\n    fn poll_send_ready(&self, cx: &mut Context<'_>) -> Poll<io::Result<()>> {\n        self.deref().poll_send_ready(cx)\n    }\n}\n\n/// Future for `recv`\n#[pin_project]\npub struct RecvFut<'a, S: DatagramReceive + ?Sized> {\n    #[pin]\n    io: &'a S,\n    buf: &'a mut [u8],\n}\n\nimpl<S: DatagramReceive + ?Sized> Future for RecvFut<'_, S> {\n    type Output = io::Result<usize>;\n\n    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {\n        let this = self.project();\n\n        let mut read_buf = ReadBuf::new(this.buf);\n        ready!(this.io.poll_recv(cx, &mut read_buf))?;\n        Ok(read_buf.filled().len()).into()\n    }\n}\n\n/// Future for `recv_from`\n#[pin_project]\npub struct RecvFromFut<'a, S: DatagramReceive + ?Sized> {\n    #[pin]\n    io: &'a S,\n    buf: &'a mut [u8],\n}\n\nimpl<S: DatagramReceive + ?Sized> Future for RecvFromFut<'_, S> {\n    type Output = io::Result<(usize, SocketAddr)>;\n\n    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {\n        let this = self.project();\n\n        let mut read_buf = ReadBuf::new(this.buf);\n        let src_addr = ready!(this.io.poll_recv_from(cx, &mut read_buf))?;\n        Ok((read_buf.filled().len(), src_addr)).into()\n    }\n}\n\n/// Future for `recv_ready`\npub struct RecvReadyFut<'a, S: DatagramReceive + ?Sized> {\n    io: &'a S,\n}\n\nimpl<S: DatagramReceive + ?Sized> Future for RecvReadyFut<'_, S> {\n    type Output = io::Result<()>;\n\n    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {\n        self.io.poll_recv_ready(cx)\n    }\n}\n\n/// Future for `send`\npub struct SendFut<'a, S: DatagramSend + ?Sized> {\n    io: &'a S,\n    buf: &'a [u8],\n}\n\nimpl<S: DatagramSend + ?Sized> Future for SendFut<'_, S> {\n    type Output = io::Result<usize>;\n\n    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {\n        self.io.poll_send(cx, self.buf)\n    }\n}\n\n/// Future for `send_to`\npub struct SendToFut<'a, S: DatagramSend + ?Sized> {\n    io: &'a S,\n    target: SocketAddr,\n    buf: &'a [u8],\n}\n\nimpl<S: DatagramSend + ?Sized> Future for SendToFut<'_, S> {\n    type Output = io::Result<usize>;\n\n    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {\n        self.io.poll_send_to(cx, self.buf, self.target)\n    }\n}\n\n/// Future for `recv_ready`\npub struct SendReadyFut<'a, S: DatagramSend + ?Sized> {\n    io: &'a S,\n}\n\nimpl<S: DatagramSend + ?Sized> Future for SendReadyFut<'_, S> {\n    type Output = io::Result<()>;\n\n    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {\n        self.io.poll_send_ready(cx)\n    }\n}\n\n/// Extension methods for `DatagramReceive`\npub trait DatagramReceiveExt: DatagramReceive {\n    /// Async method for `poll_recv`\n    fn recv<'a>(&'a self, buf: &'a mut [u8]) -> RecvFut<'a, Self> {\n        RecvFut { io: self, buf }\n    }\n\n    /// Async method for `poll_recv_from`\n    fn recv_from<'a>(&'a self, buf: &'a mut [u8]) -> RecvFromFut<'a, Self> {\n        RecvFromFut { io: self, buf }\n    }\n\n    /// Async method for `poll_recv_ready`\n    fn recv_ready(&self) -> RecvReadyFut<'_, Self> {\n        RecvReadyFut { io: self }\n    }\n}\n\nimpl<S: DatagramReceive> DatagramReceiveExt for S {}\n\n/// Extension methods for `DatagramSend`\npub trait DatagramSendExt: DatagramSend {\n    /// Async method for `poll_send`\n    fn send<'a>(&'a self, buf: &'a [u8]) -> SendFut<'a, Self> {\n        SendFut { io: self, buf }\n    }\n\n    /// Async method for `poll_send_to`\n    fn send_to<'a>(&'a self, buf: &'a [u8], target: SocketAddr) -> SendToFut<'a, Self> {\n        SendToFut { io: self, target, buf }\n    }\n\n    /// Async method for `poll_send_ready`\n    fn send_ready(&self) -> SendReadyFut<'_, Self> {\n        SendReadyFut { io: self }\n    }\n}\n\nimpl<S: DatagramSend> DatagramSendExt for S {}\n"
  },
  {
    "path": "crates/shadowsocks/src/relay/udprelay/crypto_io.rs",
    "content": "//! Crypto protocol for ShadowSocks UDP\n//!\n//! Payload with stream cipher\n//! ```plain\n//! +-------+----------+\n//! |  IV   | Payload  |\n//! +-------+----------+\n//! | Fixed | Variable |\n//! +-------+----------+\n//! ```\n//!\n//! Payload with AEAD cipher\n//!\n//! ```plain\n//! UDP (after encryption, *ciphertext*)\n//! +--------+-----------+-----------+\n//! | NONCE  |  *Data*   |  Data_TAG |\n//! +--------+-----------+-----------+\n//! | Fixed  | Variable  |   Fixed   |\n//! +--------+-----------+-----------+\n//! ```\nuse std::io::Cursor;\n\nuse bytes::{BufMut, Bytes, BytesMut};\n\nuse crate::{\n    config::ServerUserManager,\n    context::Context,\n    crypto::{CipherCategory, CipherKind},\n    relay::socks5::{Address, Error as Socks5Error},\n};\n\n#[cfg(feature = \"aead-cipher\")]\nuse super::aead::{decrypt_payload_aead, encrypt_payload_aead};\n#[cfg(feature = \"aead-cipher-2022\")]\nuse super::aead_2022::{\n    decrypt_client_payload_aead_2022, decrypt_server_payload_aead_2022, encrypt_client_payload_aead_2022,\n    encrypt_server_payload_aead_2022,\n};\nuse super::options::UdpSocketControlData;\n#[cfg(feature = \"stream-cipher\")]\nuse super::stream::{decrypt_payload_stream, encrypt_payload_stream};\n\n/// UDP shadowsocks protocol errors\n#[derive(thiserror::Error, Debug)]\npub enum ProtocolError {\n    #[error(\"invalid address in packet, {0}\")]\n    InvalidAddress(Socks5Error),\n    #[cfg(feature = \"stream-cipher\")]\n    #[error(transparent)]\n    StreamError(#[from] super::stream::ProtocolError),\n    #[cfg(feature = \"aead-cipher\")]\n    #[error(transparent)]\n    AeadError(#[from] super::aead::ProtocolError),\n    #[cfg(feature = \"aead-cipher-2022\")]\n    #[error(transparent)]\n    Aead2022Error(#[from] super::aead_2022::ProtocolError),\n}\n\n/// UDP shadowsocks protocol errors\npub type ProtocolResult<T> = Result<T, ProtocolError>;\n\n/// Encrypt `Client -> Server` payload into ShadowSocks UDP encrypted packet\n#[allow(clippy::too_many_arguments)]\npub fn encrypt_client_payload(\n    context: &Context,\n    method: CipherKind,\n    key: &[u8],\n    addr: &Address,\n    control: &UdpSocketControlData,\n    identity_keys: &[Bytes],\n    payload: &[u8],\n    dst: &mut BytesMut,\n) {\n    match method.category() {\n        CipherCategory::None => {\n            let _ = context;\n            let _ = key;\n            let _ = control;\n            let _ = identity_keys;\n            dst.reserve(addr.serialized_len() + payload.len());\n            addr.write_to_buf(dst);\n            dst.put_slice(payload);\n        }\n        #[cfg(feature = \"stream-cipher\")]\n        CipherCategory::Stream => {\n            let _ = control;\n            let _ = identity_keys;\n            encrypt_payload_stream(context, method, key, addr, payload, dst)\n        }\n        #[cfg(feature = \"aead-cipher\")]\n        CipherCategory::Aead => {\n            let _ = control;\n            let _ = identity_keys;\n            encrypt_payload_aead(context, method, key, addr, payload, dst)\n        }\n        #[cfg(feature = \"aead-cipher-2022\")]\n        CipherCategory::Aead2022 => {\n            encrypt_client_payload_aead_2022(context, method, key, addr, control, identity_keys, payload, dst)\n        }\n    }\n}\n\n/// Encrypt `Server -> Client` payload into ShadowSocks UDP encrypted packet\npub fn encrypt_server_payload(\n    context: &Context,\n    method: CipherKind,\n    key: &[u8],\n    addr: &Address,\n    control: &UdpSocketControlData,\n    payload: &[u8],\n    dst: &mut BytesMut,\n) {\n    match method.category() {\n        CipherCategory::None => {\n            let _ = context;\n            let _ = key;\n            let _ = control;\n            dst.reserve(addr.serialized_len() + payload.len());\n            addr.write_to_buf(dst);\n            dst.put_slice(payload);\n        }\n        #[cfg(feature = \"stream-cipher\")]\n        CipherCategory::Stream => {\n            let _ = control;\n            encrypt_payload_stream(context, method, key, addr, payload, dst)\n        }\n        #[cfg(feature = \"aead-cipher\")]\n        CipherCategory::Aead => {\n            let _ = control;\n            encrypt_payload_aead(context, method, key, addr, payload, dst)\n        }\n        #[cfg(feature = \"aead-cipher-2022\")]\n        CipherCategory::Aead2022 => encrypt_server_payload_aead_2022(context, method, key, addr, control, payload, dst),\n    }\n}\n\n/// Decrypt `Client -> Server` payload from ShadowSocks UDP encrypted packet\npub fn decrypt_client_payload(\n    context: &Context,\n    method: CipherKind,\n    key: &[u8],\n    payload: &mut [u8],\n    user_manager: Option<&ServerUserManager>,\n) -> ProtocolResult<(usize, Address, Option<UdpSocketControlData>)> {\n    match method.category() {\n        CipherCategory::None => {\n            let _ = context;\n            let _ = key;\n            let _ = user_manager;\n            let mut cur = Cursor::new(payload);\n            match Address::read_cursor(&mut cur) {\n                Ok(address) => {\n                    let pos = cur.position() as usize;\n                    let payload = cur.into_inner();\n                    payload.copy_within(pos.., 0);\n                    Ok((payload.len() - pos, address, None))\n                }\n                Err(err) => Err(ProtocolError::InvalidAddress(err)),\n            }\n        }\n        #[cfg(feature = \"stream-cipher\")]\n        CipherCategory::Stream => {\n            let _ = user_manager;\n            decrypt_payload_stream(context, method, key, payload)\n                .map(|(n, a)| (n, a, None))\n                .map_err(Into::into)\n        }\n        #[cfg(feature = \"aead-cipher\")]\n        CipherCategory::Aead => {\n            let _ = user_manager;\n            decrypt_payload_aead(context, method, key, payload)\n                .map(|(n, a)| (n, a, None))\n                .map_err(Into::into)\n        }\n        #[cfg(feature = \"aead-cipher-2022\")]\n        CipherCategory::Aead2022 => decrypt_client_payload_aead_2022(context, method, key, payload, user_manager)\n            .map(|(n, a, c)| (n, a, Some(c)))\n            .map_err(Into::into),\n    }\n}\n\n/// Decrypt `Server -> Client` payload from ShadowSocks UDP encrypted packet\npub fn decrypt_server_payload(\n    context: &Context,\n    method: CipherKind,\n    key: &[u8],\n    payload: &mut [u8],\n) -> ProtocolResult<(usize, Address, Option<UdpSocketControlData>)> {\n    match method.category() {\n        CipherCategory::None => {\n            let _ = context;\n            let _ = key;\n\n            let mut cur = Cursor::new(payload);\n            match Address::read_cursor(&mut cur) {\n                Ok(address) => {\n                    let pos = cur.position() as usize;\n                    let payload = cur.into_inner();\n                    payload.copy_within(pos.., 0);\n                    Ok((payload.len() - pos, address, None))\n                }\n                Err(err) => Err(ProtocolError::InvalidAddress(err)),\n            }\n        }\n        #[cfg(feature = \"stream-cipher\")]\n        CipherCategory::Stream => decrypt_payload_stream(context, method, key, payload)\n            .map(|(n, a)| (n, a, None))\n            .map_err(Into::into),\n        #[cfg(feature = \"aead-cipher\")]\n        CipherCategory::Aead => decrypt_payload_aead(context, method, key, payload)\n            .map(|(n, a)| (n, a, None))\n            .map_err(Into::into),\n        #[cfg(feature = \"aead-cipher-2022\")]\n        CipherCategory::Aead2022 => decrypt_server_payload_aead_2022(context, method, key, payload)\n            .map(|(n, a, c)| (n, a, Some(c)))\n            .map_err(Into::into),\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/relay/udprelay/mod.rs",
    "content": "//! Relay for UDP implementation\n//!\n//! ## ShadowSocks UDP protocol\n//!\n//! SOCKS5 UDP Request\n//! ```ignore\n//! +----+------+------+----------+----------+----------+\n//! |RSV | FRAG | ATYP | DST.ADDR | DST.PORT |   DATA   |\n//! +----+------+------+----------+----------+----------+\n//! | 2  |  1   |  1   | Variable |    2     | Variable |\n//! +----+------+------+----------+----------+----------+\n//! ```\n//!\n//! SOCKS5 UDP Response\n//! ```ignore\n//! +----+------+------+----------+----------+----------+\n//! |RSV | FRAG | ATYP | DST.ADDR | DST.PORT |   DATA   |\n//! +----+------+------+----------+----------+----------+\n//! | 2  |  1   |  1   | Variable |    2     | Variable |\n//! +----+------+------+----------+----------+----------+\n//! ```\n//!\n//! shadowsocks UDP Request (before encrypted)\n//! ```ignore\n//! +------+----------+----------+----------+\n//! | ATYP | DST.ADDR | DST.PORT |   DATA   |\n//! +------+----------+----------+----------+\n//! |  1   | Variable |    2     | Variable |\n//! +------+----------+----------+----------+\n//! ```\n//!\n//! shadowsocks UDP Response (before encrypted)\n//! ```ignore\n//! +------+----------+----------+----------+\n//! | ATYP | DST.ADDR | DST.PORT |   DATA   |\n//! +------+----------+----------+----------+\n//! |  1   | Variable |    2     | Variable |\n//! +------+----------+----------+----------+\n//! ```\n//!\n//! shadowsocks UDP Request and Response (after encrypted)\n//! ```ignore\n//! +-------+--------------+\n//! |   IV  |    PAYLOAD   |\n//! +-------+--------------+\n//! | Fixed |   Variable   |\n//! +-------+--------------+\n//! ```\n\nuse std::time::Duration;\n\npub use self::proxy_socket::ProxySocket;\npub use compat::{DatagramReceive, DatagramReceiveExt, DatagramSend, DatagramSendExt, DatagramSocket};\n\n#[cfg(feature = \"aead-cipher\")]\nmod aead;\n#[cfg(feature = \"aead-cipher-2022\")]\nmod aead_2022;\nmod compat;\npub mod crypto_io;\npub mod options;\npub mod proxy_socket;\n#[cfg(feature = \"stream-cipher\")]\nmod stream;\n\n/// The maximum UDP payload size (defined in the original shadowsocks Python)\n///\n/// *I cannot find any references about why clowwindy used this value as the maximum\n/// Socks5 UDP ASSOCIATE packet size. The only thing I can find is\n/// [here](http://support.microsoft.com/kb/822061/)*\npub const MAXIMUM_UDP_PAYLOAD_SIZE: usize = 65536;\n\n/// Default association expire time\npub const DEFAULT_TIMEOUT: Duration = Duration::from_secs(5 * 60);\n"
  },
  {
    "path": "crates/shadowsocks/src/relay/udprelay/options.rs",
    "content": "//! UDP Socket options and extra data\n\nuse std::sync::Arc;\n\nuse crate::config::ServerUser;\n\n#[derive(Debug, Clone, Default)]\n#[non_exhaustive]\npub struct UdpSocketControlData {\n    /// Session ID in client.\n    ///\n    /// For identifying an unique association in client\n    pub client_session_id: u64,\n    /// Session ID in server.\n    ///\n    /// For identifying an unique association in server\n    pub server_session_id: u64,\n    /// Packet counter\n    pub packet_id: u64,\n    /// Server user instance\n    pub user: Option<Arc<ServerUser>>,\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/relay/udprelay/proxy_socket.rs",
    "content": "//! UDP socket for communicating with shadowsocks' proxy server\n\n#[cfg(unix)]\nuse std::os::fd::{AsFd, AsRawFd, BorrowedFd, IntoRawFd, RawFd};\n#[cfg(windows)]\nuse std::os::windows::io::{AsRawSocket, AsSocket, BorrowedSocket, IntoRawSocket, RawSocket};\nuse std::{\n    io::{self, ErrorKind},\n    net::SocketAddr,\n    sync::{Arc, LazyLock},\n    task::{Context, Poll, ready},\n    time::Duration,\n};\n\nuse byte_string::ByteStr;\nuse bytes::{Bytes, BytesMut};\nuse log::{info, trace, warn};\nuse tokio::{io::ReadBuf, time};\n\nuse crate::{\n    config::{ServerAddr, ServerConfig, ServerUserManager},\n    context::SharedContext,\n    crypto::CipherKind,\n    net::{AcceptOpts, ConnectOpts, UdpSocket as ShadowUdpSocket},\n    relay::{socks5::Address, udprelay::options::UdpSocketControlData},\n};\n\nuse super::{\n    compat::{DatagramReceive, DatagramReceiveExt, DatagramSend, DatagramSendExt, DatagramSocket},\n    crypto_io::{\n        ProtocolError, ProtocolResult, decrypt_client_payload, decrypt_server_payload, encrypt_client_payload,\n        encrypt_server_payload,\n    },\n};\n\nstatic DEFAULT_CONNECT_OPTS: LazyLock<ConnectOpts> = LazyLock::new(Default::default);\nstatic DEFAULT_SOCKET_CONTROL: LazyLock<UdpSocketControlData> = LazyLock::new(UdpSocketControlData::default);\n\n/// UDP socket type, defining whether the socket is used in Client or Server\n#[derive(Debug, Clone, Copy, PartialEq, Eq)]\npub enum UdpSocketType {\n    /// Socket used for `Client -> Server`\n    Client,\n    /// Socket used for `Server -> Client`\n    Server,\n}\n\n/// `ProxySocket` error type\n#[derive(thiserror::Error, Debug)]\npub enum ProxySocketError {\n    /// std::io::Error\n    #[error(transparent)]\n    IoError(#[from] io::Error),\n    #[error(transparent)]\n    ProtocolError(ProtocolError),\n    #[error(\"peer: {0}, {1}\")]\n    ProtocolErrorWithPeer(SocketAddr, ProtocolError),\n    #[error(\"invalid server user identity {:?}\", ByteStr::new(.0))]\n    InvalidServerUser(Bytes),\n}\n\nimpl From<ProxySocketError> for io::Error {\n    fn from(e: ProxySocketError) -> Self {\n        match e {\n            ProxySocketError::IoError(e) => e,\n            _ => Self::other(e),\n        }\n    }\n}\n\n/// `ProxySocket` result type\npub type ProxySocketResult<T> = Result<T, ProxySocketError>;\n\n/// UDP client for communicating with ShadowSocks' server\n#[derive(Debug)]\npub struct ProxySocket<S> {\n    socket_type: UdpSocketType,\n    io: S,\n    method: CipherKind,\n    key: Box<[u8]>,\n    send_timeout: Option<Duration>,\n    recv_timeout: Option<Duration>,\n    context: SharedContext,\n    identity_keys: Arc<Vec<Bytes>>,\n    user_manager: Option<Arc<ServerUserManager>>,\n}\n\nimpl ProxySocket<ShadowUdpSocket> {\n    /// Create a client to communicate with Shadowsocks' UDP server (outbound)\n    pub async fn connect(context: SharedContext, svr_cfg: &ServerConfig) -> ProxySocketResult<Self> {\n        Self::connect_with_opts(context, svr_cfg, &DEFAULT_CONNECT_OPTS).await\n    }\n\n    /// Create a client to communicate with Shadowsocks' UDP server (outbound)\n    pub async fn connect_with_opts(\n        context: SharedContext,\n        svr_cfg: &ServerConfig,\n        opts: &ConnectOpts,\n    ) -> ProxySocketResult<Self> {\n        // Note: Plugins doesn't support UDP relay\n\n        let socket = ShadowUdpSocket::connect_server_with_opts(&context, svr_cfg.udp_external_addr(), opts).await?;\n\n        trace!(\n            \"connected udp remote {} (outbound: {}) with {:?}\",\n            svr_cfg.addr(),\n            svr_cfg.udp_external_addr(),\n            opts\n        );\n\n        Ok(Self::from_socket(UdpSocketType::Client, context, svr_cfg, socket))\n    }\n\n    /// Create a `ProxySocket` binding to a specific address (inbound)\n    pub async fn bind(context: SharedContext, svr_cfg: &ServerConfig) -> ProxySocketResult<Self> {\n        Self::bind_with_opts(context, svr_cfg, AcceptOpts::default()).await\n    }\n\n    /// Create a `ProxySocket` binding to a specific address (inbound)\n    pub async fn bind_with_opts(\n        context: SharedContext,\n        svr_cfg: &ServerConfig,\n        opts: AcceptOpts,\n    ) -> ProxySocketResult<Self> {\n        // Plugins doesn't support UDP\n        let socket = match svr_cfg.udp_external_addr() {\n            ServerAddr::SocketAddr(sa) => ShadowUdpSocket::listen_with_opts(sa, opts).await?,\n            ServerAddr::DomainName(domain, port) => {\n                lookup_then!(&context, domain, *port, |addr| {\n                    ShadowUdpSocket::listen_with_opts(&addr, opts.clone()).await\n                })?\n                .1\n            }\n        };\n        Ok(Self::from_socket(UdpSocketType::Server, context, svr_cfg, socket))\n    }\n}\n\nimpl<S> ProxySocket<S> {\n    /// Create a `ProxySocket` from a I/O object that impls `DatagramTransport`\n    pub fn from_socket(socket_type: UdpSocketType, context: SharedContext, svr_cfg: &ServerConfig, socket: S) -> Self {\n        let key = svr_cfg.key().to_vec().into_boxed_slice();\n        let method = svr_cfg.method();\n\n        // NOTE: svr_cfg.timeout() is not for this socket, but for associations.\n        Self {\n            socket_type,\n            io: socket,\n            method,\n            key,\n            send_timeout: None,\n            recv_timeout: None,\n            context,\n            identity_keys: match socket_type {\n                UdpSocketType::Client => svr_cfg.clone_identity_keys(),\n                UdpSocketType::Server => Arc::new(Vec::new()),\n            },\n            user_manager: match socket_type {\n                UdpSocketType::Client => None,\n                UdpSocketType::Server => svr_cfg.clone_user_manager(),\n            },\n        }\n    }\n\n    /// Set `send` timeout, `None` will clear timeout\n    pub fn set_send_timeout(&mut self, t: Option<Duration>) {\n        self.send_timeout = t;\n    }\n\n    /// Set `recv` timeout, `None` will clear timeout\n    pub fn set_recv_timeout(&mut self, t: Option<Duration>) {\n        self.recv_timeout = t;\n    }\n}\n\nimpl<S> ProxySocket<S>\nwhere\n    S: DatagramSend,\n{\n    fn encrypt_send_buffer(\n        &self,\n        addr: &Address,\n        control: &UdpSocketControlData,\n        identity_keys: &[Bytes],\n        payload: &[u8],\n        send_buf: &mut BytesMut,\n    ) -> ProxySocketResult<()> {\n        match self.socket_type {\n            UdpSocketType::Client => encrypt_client_payload(\n                &self.context,\n                self.method,\n                &self.key,\n                addr,\n                control,\n                identity_keys,\n                payload,\n                send_buf,\n            ),\n            UdpSocketType::Server => {\n                let mut key = self.key.as_ref();\n\n                if let Some(ref user) = control.user {\n                    trace!(\"udp encrypt with {:?} identity\", user);\n                    key = user.key();\n                }\n\n                encrypt_server_payload(&self.context, self.method, key, addr, control, payload, send_buf)\n            }\n        }\n\n        Ok(())\n    }\n\n    /// Send a UDP packet to addr through proxy\n    #[inline]\n    pub async fn send(&self, addr: &Address, payload: &[u8]) -> ProxySocketResult<usize> {\n        self.send_with_ctrl(addr, &DEFAULT_SOCKET_CONTROL, payload).await\n    }\n\n    /// Send a UDP packet to addr through proxy with `ControlData`\n    pub async fn send_with_ctrl(\n        &self,\n        addr: &Address,\n        control: &UdpSocketControlData,\n        payload: &[u8],\n    ) -> ProxySocketResult<usize> {\n        let mut send_buf = BytesMut::new();\n        self.encrypt_send_buffer(addr, control, &self.identity_keys, payload, &mut send_buf)?;\n\n        trace!(\n            \"UDP server client send to {}, control: {:?}, payload length {} bytes, packet length {} bytes\",\n            addr,\n            control,\n            payload.len(),\n            send_buf.len()\n        );\n\n        let send_len = match self.send_timeout {\n            None => self.io.send(&send_buf).await?,\n            Some(d) => match time::timeout(d, self.io.send(&send_buf)).await {\n                Ok(Ok(l)) => l,\n                Ok(Err(err)) => return Err(err.into()),\n                Err(..) => return Err(io::Error::from(ErrorKind::TimedOut).into()),\n            },\n        };\n\n        if send_buf.len() != send_len {\n            warn!(\n                \"UDP server client send {} bytes, but actually sent {} bytes\",\n                send_buf.len(),\n                send_len\n            );\n        }\n\n        Ok(send_len)\n    }\n\n    /// poll family functions\n    ///\n    /// Send a UDP packet to addr through proxy\n    ///\n    /// NOTE: the `send_timeout` is ignored.\n    pub fn poll_send(&self, addr: &Address, payload: &[u8], cx: &mut Context<'_>) -> Poll<ProxySocketResult<usize>> {\n        self.poll_send_with_ctrl(addr, &DEFAULT_SOCKET_CONTROL, payload, cx)\n    }\n\n    /// poll family functions\n    ///\n    /// Send a UDP packet to addr through proxy with `ControlData`\n    ///\n    /// NOTE: the `send_timeout` is ignored.\n    pub fn poll_send_with_ctrl(\n        &self,\n        addr: &Address,\n        control: &UdpSocketControlData,\n        payload: &[u8],\n        cx: &mut Context<'_>,\n    ) -> Poll<ProxySocketResult<usize>> {\n        let mut send_buf = BytesMut::with_capacity(payload.len() + 256);\n\n        self.encrypt_send_buffer(addr, control, &self.identity_keys, payload, &mut send_buf)?;\n\n        trace!(\n            \"UDP server client send to {}, control: {:?}, payload length {} bytes, packet length {} bytes\",\n            addr,\n            control,\n            payload.len(),\n            send_buf.len()\n        );\n\n        let n_send_buf = send_buf.len();\n\n        match self.io.poll_send(cx, &send_buf).map_err(|x| x.into()) {\n            Poll::Ready(Ok(l)) => {\n                if l == n_send_buf {\n                    Poll::Ready(Ok(payload.len()))\n                } else {\n                    Poll::Ready(Err(io::Error::from(ErrorKind::WriteZero).into()))\n                }\n            }\n            x => x,\n        }\n    }\n\n    /// poll family functions\n    ///\n    /// Send a UDP packet to addr through proxy `target`\n    ///\n    /// NOTE: the `send_timeout` is ignored.\n    pub fn poll_send_to(\n        &self,\n        target: SocketAddr,\n        addr: &Address,\n        payload: &[u8],\n        cx: &mut Context<'_>,\n    ) -> Poll<ProxySocketResult<usize>> {\n        self.poll_send_to_with_ctrl(target, addr, &DEFAULT_SOCKET_CONTROL, payload, cx)\n    }\n\n    /// poll family functions\n    ///\n    /// Send a UDP packet to addr through proxy `target` with `ControlData`\n    ///\n    /// NOTE: the `send_timeout` is ignored.\n    pub fn poll_send_to_with_ctrl(\n        &self,\n        target: SocketAddr,\n        addr: &Address,\n        control: &UdpSocketControlData,\n        payload: &[u8],\n        cx: &mut Context<'_>,\n    ) -> Poll<ProxySocketResult<usize>> {\n        let mut send_buf = BytesMut::with_capacity(payload.len() + 256);\n\n        self.encrypt_send_buffer(addr, control, &self.identity_keys, payload, &mut send_buf)?;\n\n        info!(\n            \"UDP server client poll_send_to to {}, payload length {} bytes, packet length {} bytes\",\n            target,\n            payload.len(),\n            send_buf.len()\n        );\n\n        let n_send_buf = send_buf.len();\n        match self.io.poll_send_to(cx, &send_buf, target).map_err(|x| x.into()) {\n            Poll::Ready(Ok(l)) => {\n                if l == n_send_buf {\n                    Poll::Ready(Ok(payload.len()))\n                } else {\n                    Poll::Ready(Err(io::Error::from(ErrorKind::WriteZero).into()))\n                }\n            }\n            x => x,\n        }\n    }\n\n    /// poll family functions\n    ///\n    /// Check if socket is ready to `send`, or writable.\n    pub fn poll_send_ready(&self, cx: &mut Context<'_>) -> Poll<ProxySocketResult<()>> {\n        self.io.poll_send_ready(cx).map_err(|x| x.into())\n    }\n\n    /// Send a UDP packet to target through proxy `target`\n    pub async fn send_to(&self, target: SocketAddr, addr: &Address, payload: &[u8]) -> ProxySocketResult<usize> {\n        self.send_to_with_ctrl(target, addr, &DEFAULT_SOCKET_CONTROL, payload)\n            .await\n    }\n\n    /// Send a UDP packet to target through proxy `target`\n    pub async fn send_to_with_ctrl(\n        &self,\n        target: SocketAddr,\n        addr: &Address,\n        control: &UdpSocketControlData,\n        payload: &[u8],\n    ) -> ProxySocketResult<usize> {\n        let mut send_buf = BytesMut::new();\n        self.encrypt_send_buffer(addr, control, &self.identity_keys, payload, &mut send_buf)?;\n\n        trace!(\n            \"UDP server client send_to to, addr {}, control: {:?}, payload length {} bytes, packet length {} bytes\",\n            addr,\n            control,\n            payload.len(),\n            send_buf.len()\n        );\n\n        let send_len = match self.send_timeout {\n            None => self.io.send_to(&send_buf, target).await?,\n            Some(d) => match time::timeout(d, self.io.send_to(&send_buf, target)).await {\n                Ok(Ok(l)) => l,\n                Ok(Err(err)) => return Err(err.into()),\n                Err(..) => return Err(io::Error::from(ErrorKind::TimedOut).into()),\n            },\n        };\n\n        if send_buf.len() != send_len {\n            warn!(\n                \"UDP server client send_to {} bytes, but actually sent {} bytes\",\n                send_buf.len(),\n                send_len\n            );\n        }\n\n        Ok(send_len)\n    }\n}\n\nimpl<S> ProxySocket<S>\nwhere\n    S: DatagramReceive,\n{\n    fn decrypt_recv_buffer(\n        &self,\n        recv_buf: &mut [u8],\n        user_manager: Option<&ServerUserManager>,\n    ) -> ProtocolResult<(usize, Address, Option<UdpSocketControlData>)> {\n        match self.socket_type {\n            UdpSocketType::Client => decrypt_server_payload(&self.context, self.method, &self.key, recv_buf),\n            UdpSocketType::Server => {\n                decrypt_client_payload(&self.context, self.method, &self.key, recv_buf, user_manager)\n            }\n        }\n    }\n\n    /// Receive packet from Shadowsocks' UDP server\n    ///\n    /// This function will use `recv_buf` to store intermediate data, so it has to be big enough to store the whole shadowsocks' packet\n    ///\n    /// It is recommended to allocate a buffer to have at least 65536 bytes.\n    pub async fn recv(&self, recv_buf: &mut [u8]) -> ProxySocketResult<(usize, Address, usize)> {\n        self.recv_with_ctrl(recv_buf).await.map(|(n, a, rn, _)| (n, a, rn))\n    }\n\n    /// Receive packet from Shadowsocks' UDP server\n    ///\n    /// This function will use `recv_buf` to store intermediate data, so it has to be big enough to store the whole shadowsocks' packet\n    ///\n    /// It is recommended to allocate a buffer to have at least 65536 bytes.\n    pub async fn recv_with_ctrl(\n        &self,\n        recv_buf: &mut [u8],\n    ) -> ProxySocketResult<(usize, Address, usize, Option<UdpSocketControlData>)> {\n        let recv_n = match self.recv_timeout {\n            None => self.io.recv(recv_buf).await?,\n            Some(d) => match time::timeout(d, self.io.recv(recv_buf)).await {\n                Ok(Ok(l)) => l,\n                Ok(Err(err)) => return Err(err.into()),\n                Err(..) => return Err(io::Error::from(ErrorKind::TimedOut).into()),\n            },\n        };\n\n        let (n, addr, control) = match self.decrypt_recv_buffer(&mut recv_buf[..recv_n], self.user_manager.as_deref()) {\n            Ok(x) => x,\n            Err(err) => return Err(ProxySocketError::ProtocolError(err)),\n        };\n\n        trace!(\n            \"UDP server client receive from {}, control: {:?}, packet length {} bytes, payload length {} bytes\",\n            addr, control, recv_n, n\n        );\n\n        Ok((n, addr, recv_n, control))\n    }\n\n    /// Receive packet from Shadowsocks' UDP server\n    ///\n    /// This function will use `recv_buf` to store intermediate data, so it has to be big enough to store the whole shadowsocks' packet\n    ///\n    /// It is recommended to allocate a buffer to have at least 65536 bytes.\n    #[allow(clippy::type_complexity)]\n    pub async fn recv_from(&self, recv_buf: &mut [u8]) -> ProxySocketResult<(usize, SocketAddr, Address, usize)> {\n        self.recv_from_with_ctrl(recv_buf)\n            .await\n            .map(|(n, sa, a, rn, _)| (n, sa, a, rn))\n    }\n\n    /// Receive packet from Shadowsocks' UDP server\n    ///\n    /// This function will use `recv_buf` to store intermediate data, so it has to be big enough to store the whole shadowsocks' packet\n    ///\n    /// It is recommended to allocate a buffer to have at least 65536 bytes.\n    #[allow(clippy::type_complexity)]\n    pub async fn recv_from_with_ctrl(\n        &self,\n        recv_buf: &mut [u8],\n    ) -> ProxySocketResult<(usize, SocketAddr, Address, usize, Option<UdpSocketControlData>)> {\n        // Waiting for response from server SERVER -> CLIENT\n        let (recv_n, target_addr) = match self.recv_timeout {\n            None => self.io.recv_from(recv_buf).await?,\n            Some(d) => match time::timeout(d, self.io.recv_from(recv_buf)).await {\n                Ok(Ok(l)) => l,\n                Ok(Err(err)) => return Err(err.into()),\n                Err(..) => return Err(io::Error::from(ErrorKind::TimedOut).into()),\n            },\n        };\n\n        let (n, addr, control) = match self.decrypt_recv_buffer(&mut recv_buf[..recv_n], self.user_manager.as_deref()) {\n            Ok(x) => x,\n            Err(err) => return Err(ProxySocketError::ProtocolErrorWithPeer(target_addr, err)),\n        };\n\n        trace!(\n            \"UDP server client receive from {}, addr {}, control: {:?}, packet length {} bytes, payload length {} bytes\",\n            target_addr, addr, control, recv_n, n,\n        );\n\n        Ok((n, target_addr, addr, recv_n, control))\n    }\n\n    /// poll family functions.\n    /// the recv_timeout is ignored.\n    #[allow(clippy::type_complexity)]\n    pub fn poll_recv(\n        &self,\n        cx: &mut Context<'_>,\n        recv_buf: &mut ReadBuf,\n    ) -> Poll<ProxySocketResult<(usize, Address, usize)>> {\n        self.poll_recv_with_ctrl(cx, recv_buf)\n            .map(|r| r.map(|(n, a, rn, _)| (n, a, rn)))\n    }\n\n    /// poll family functions\n    #[allow(clippy::type_complexity)]\n    pub fn poll_recv_with_ctrl(\n        &self,\n        cx: &mut Context<'_>,\n        recv_buf: &mut ReadBuf,\n    ) -> Poll<ProxySocketResult<(usize, Address, usize, Option<UdpSocketControlData>)>> {\n        ready!(self.io.poll_recv(cx, recv_buf))?;\n\n        let n_recv = recv_buf.filled().len();\n\n        match self.decrypt_recv_buffer(recv_buf.filled_mut(), self.user_manager.as_deref()) {\n            Ok(x) => Poll::Ready(Ok((x.0, x.1, n_recv, x.2))),\n            Err(err) => Poll::Ready(Err(ProxySocketError::ProtocolError(err))),\n        }\n    }\n\n    /// poll family functions\n    #[allow(clippy::type_complexity)]\n    pub fn poll_recv_from(\n        &self,\n        cx: &mut Context<'_>,\n        recv_buf: &mut ReadBuf,\n    ) -> Poll<ProxySocketResult<(usize, SocketAddr, Address, usize)>> {\n        self.poll_recv_from_with_ctrl(cx, recv_buf)\n            .map(|r| r.map(|(n, sa, a, rn, _)| (n, sa, a, rn)))\n    }\n\n    /// poll family functions\n    #[allow(clippy::type_complexity)]\n    pub fn poll_recv_from_with_ctrl(\n        &self,\n        cx: &mut Context<'_>,\n        recv_buf: &mut ReadBuf,\n    ) -> Poll<ProxySocketResult<(usize, SocketAddr, Address, usize, Option<UdpSocketControlData>)>> {\n        let src = ready!(self.io.poll_recv_from(cx, recv_buf))?;\n\n        let n_recv = recv_buf.filled().len();\n        match self.decrypt_recv_buffer(recv_buf.filled_mut(), self.user_manager.as_deref()) {\n            Ok(x) => Poll::Ready(Ok((x.0, src, x.1, n_recv, x.2))),\n            Err(err) => Poll::Ready(Err(ProxySocketError::ProtocolError(err))),\n        }\n    }\n\n    /// poll family functions\n    pub fn poll_recv_ready(&self, cx: &mut Context<'_>) -> Poll<ProxySocketResult<()>> {\n        self.io.poll_recv_ready(cx).map_err(|x| x.into())\n    }\n}\n\nimpl<S> ProxySocket<S>\nwhere\n    S: DatagramSocket,\n{\n    /// Get local addr of socket\n    pub fn local_addr(&self) -> io::Result<SocketAddr> {\n        self.io.local_addr()\n    }\n}\n\n#[cfg(unix)]\nimpl<S> AsRawFd for ProxySocket<S>\nwhere\n    S: AsRawFd,\n{\n    /// Retrieve raw fd of the outbound socket\n    fn as_raw_fd(&self) -> RawFd {\n        self.io.as_raw_fd()\n    }\n}\n\n#[cfg(unix)]\nimpl<S> AsFd for ProxySocket<S>\nwhere\n    S: AsFd,\n{\n    fn as_fd(&self) -> BorrowedFd<'_> {\n        self.io.as_fd()\n    }\n}\n\n#[cfg(unix)]\nimpl<S> IntoRawFd for ProxySocket<S>\nwhere\n    S: IntoRawFd,\n{\n    fn into_raw_fd(self) -> RawFd {\n        self.io.into_raw_fd()\n    }\n}\n\n#[cfg(windows)]\nimpl<S> AsRawSocket for ProxySocket<S>\nwhere\n    S: AsRawSocket,\n{\n    fn as_raw_socket(&self) -> RawSocket {\n        self.io.as_raw_socket()\n    }\n}\n\n#[cfg(windows)]\nimpl<S> AsSocket for ProxySocket<S>\nwhere\n    S: AsSocket,\n{\n    fn as_socket(&self) -> BorrowedSocket<'_> {\n        self.io.as_socket()\n    }\n}\n\n#[cfg(windows)]\nimpl<S> IntoRawSocket for ProxySocket<S>\nwhere\n    S: IntoRawSocket,\n{\n    fn into_raw_socket(self) -> RawSocket {\n        self.io.into_raw_socket()\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/relay/udprelay/stream.rs",
    "content": "//! Shadowsocks UDP Stream Protocol\n//!\n//! Payload with stream cipher\n//! ```plain\n//! +-------+----------+\n//! |  IV   | Payload  |\n//! +-------+----------+\n//! | Fixed | Variable |\n//! +-------+----------+\n//! ```\n\nuse std::io::Cursor;\n\nuse byte_string::ByteStr;\nuse bytes::{BufMut, BytesMut};\nuse log::trace;\n\nuse crate::{\n    context::Context,\n    crypto::{CipherKind, v1::Cipher},\n    relay::socks5::{Address, Error as Socks5Error},\n};\n\n/// Stream protocol error\n#[derive(thiserror::Error, Debug)]\npub enum ProtocolError {\n    #[error(\"packet too short, at least {0} bytes, but only {1} bytes\")]\n    PacketTooShort(usize, usize),\n    #[error(\"invalid address in packet, {0}\")]\n    InvalidAddress(Socks5Error),\n}\n\n/// Stream protocol result\npub type ProtocolResult<T> = Result<T, ProtocolError>;\n\n/// Encrypt UDP stream protocol packet\npub fn encrypt_payload_stream(\n    context: &Context,\n    method: CipherKind,\n    key: &[u8],\n    addr: &Address,\n    payload: &[u8],\n    dst: &mut BytesMut,\n) {\n    let iv_len = method.iv_len();\n    let addr_len = addr.serialized_len();\n\n    // Packet = IV + ADDRESS + PAYLOAD\n    dst.reserve(iv_len + addr_len + payload.len());\n\n    // Generate IV\n    dst.resize(iv_len, 0);\n    let iv = &mut dst[..iv_len];\n\n    if iv_len > 0 {\n        context.generate_nonce(method, iv, false);\n        trace!(\"UDP packet generated stream iv {:?}\", ByteStr::new(iv));\n    }\n\n    let mut cipher = Cipher::new(method, key, iv);\n\n    addr.write_to_buf(dst);\n    dst.put_slice(payload);\n    let m = &mut dst[iv_len..];\n    cipher.encrypt_packet(m);\n}\n\n/// Decrypt UDP stream protocol packet\npub fn decrypt_payload_stream(\n    _context: &Context,\n    method: CipherKind,\n    key: &[u8],\n    payload: &mut [u8],\n) -> ProtocolResult<(usize, Address)> {\n    let plen = payload.len();\n    let iv_len = method.iv_len();\n\n    if plen < iv_len {\n        return Err(ProtocolError::PacketTooShort(iv_len, plen));\n    }\n\n    let (iv, data) = payload.split_at_mut(iv_len);\n    // context.check_nonce_replay(iv)?;\n\n    trace!(\"UDP packet got stream IV {:?}\", ByteStr::new(iv));\n    let mut cipher = Cipher::new(method, key, iv);\n\n    assert!(cipher.decrypt_packet(data));\n\n    let (dn, addr) = parse_packet(data)?;\n\n    let data_start_idx = iv_len + dn;\n    let data_length = payload.len() - data_start_idx;\n    payload.copy_within(data_start_idx.., 0);\n\n    Ok((data_length, addr))\n}\n\n#[inline]\nfn parse_packet(buf: &[u8]) -> ProtocolResult<(usize, Address)> {\n    let mut cur = Cursor::new(buf);\n    match Address::read_cursor(&mut cur) {\n        Ok(address) => {\n            let pos = cur.position() as usize;\n            Ok((pos, address))\n        }\n        Err(err) => Err(ProtocolError::InvalidAddress(err)),\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/security/mod.rs",
    "content": "pub mod replay;\n"
  },
  {
    "path": "crates/shadowsocks/src/security/replay/mod.rs",
    "content": "use std::fmt;\n\n#[cfg(feature = \"aead-cipher-2022\")]\nuse std::time::Duration;\n\nuse cfg_if::cfg_if;\n#[cfg(feature = \"aead-cipher-2022\")]\nuse lru_time_cache::LruCache;\n\n#[cfg(feature = \"aead-cipher-2022\")]\nuse crate::relay::tcprelay::proxy_stream::protocol::v2::SERVER_STREAM_TIMESTAMP_MAX_DIFF;\nuse crate::{config::ServerType, crypto::CipherKind};\n\n#[cfg(feature = \"security-replay-attack-detect\")]\nuse self::ppbloom::PingPongBloom;\n\n#[cfg(feature = \"security-replay-attack-detect\")]\nmod ppbloom;\n\n/// A Bloom Filter based protector against replay attack\npub struct ReplayProtector {\n    // Check for duplicated IV/Nonce, for prevent replay attack\n    // https://github.com/shadowsocks/shadowsocks-org/issues/44\n    #[cfg(feature = \"security-replay-attack-detect\")]\n    nonce_ppbloom: spin::Mutex<PingPongBloom>,\n\n    // AEAD 2022 specific filter.\n    // AEAD 2022 TCP protocol has a timestamp, which can already reject most of the replay requests,\n    // so we only need to remember nonce that are in the valid time range\n    #[cfg(feature = \"aead-cipher-2022\")]\n    nonce_set: spin::Mutex<LruCache<Vec<u8>, ()>>,\n}\n\nimpl fmt::Debug for ReplayProtector {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        f.debug_struct(\"ReplayProtector\").finish()\n    }\n}\n\nimpl ReplayProtector {\n    /// Create a new ReplayProtector\n    #[allow(unused_variables)]\n    pub fn new(config_type: ServerType) -> Self {\n        Self {\n            #[cfg(feature = \"security-replay-attack-detect\")]\n            nonce_ppbloom: spin::Mutex::new(PingPongBloom::new(config_type)),\n            #[cfg(feature = \"aead-cipher-2022\")]\n            nonce_set: spin::Mutex::new(LruCache::with_expiry_duration(Duration::from_secs(\n                SERVER_STREAM_TIMESTAMP_MAX_DIFF * 2,\n            ))),\n        }\n    }\n\n    /// Check if nonce exist or not\n    #[inline(always)]\n    pub fn check_nonce_and_set(&self, method: CipherKind, nonce: &[u8]) -> bool {\n        // Plain cipher doesn't have a nonce\n        // Always treated as non-duplicated\n        if nonce.is_empty() {\n            return false;\n        }\n\n        #[cfg(feature = \"aead-cipher-2022\")]\n        if method.is_aead_2022() {\n            let mut set = self.nonce_set.lock();\n            if set.get(nonce).is_some() {\n                return true;\n            }\n            set.insert(nonce.to_vec(), ());\n            return false;\n        }\n\n        let _ = method;\n\n        cfg_if! {\n            if #[cfg(feature = \"security-replay-attack-detect\")] {\n                let mut ppbloom = self.nonce_ppbloom.lock();\n                ppbloom.check_and_set(nonce)\n            } else {\n                false\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/src/security/replay/ppbloom.rs",
    "content": "use bloomfilter::Bloom;\nuse log::debug;\n\nuse crate::config::ServerType;\n\n// Entries for server's bloom filter\n//\n// Borrowed from shadowsocks-libev's default value\nconst BF_NUM_ENTRIES_FOR_SERVER: usize = 1_000_000;\n\n// Entries for client's bloom filter\n//\n// Borrowed from shadowsocks-libev's default value\nconst BF_NUM_ENTRIES_FOR_CLIENT: usize = 10_000;\n\n// Error rate for server's bloom filter\n//\n// Borrowed from shadowsocks-libev's default value\nconst BF_ERROR_RATE_FOR_SERVER: f64 = 1e-6;\n\n// Error rate for client's bloom filter\n//\n// Borrowed from shadowsocks-libev's default value\nconst BF_ERROR_RATE_FOR_CLIENT: f64 = 1e-15;\n\n// A bloom filter borrowed from shadowsocks-libev's `ppbloom`\n//\n// It contains 2 bloom filters and each one holds 1/2 entries.\n// Use them as a ring buffer.\n#[derive(Debug)]\npub struct PingPongBloom {\n    blooms: [Bloom<[u8]>; 2],\n    bloom_count: [usize; 2],\n    item_count: usize,\n    current: usize,\n}\n\nimpl PingPongBloom {\n    pub fn new(ty: ServerType) -> Self {\n        let (mut item_count, fp_p) = if ty.is_local() {\n            (BF_NUM_ENTRIES_FOR_CLIENT, BF_ERROR_RATE_FOR_CLIENT)\n        } else {\n            (BF_NUM_ENTRIES_FOR_SERVER, BF_ERROR_RATE_FOR_SERVER)\n        };\n\n        item_count /= 2;\n\n        Self {\n            blooms: [\n                Bloom::new_for_fp_rate(item_count, fp_p).expect(\"BloomFilter1\"),\n                Bloom::new_for_fp_rate(item_count, fp_p).expect(\"BloomFilter2\"),\n            ],\n            bloom_count: [0, 0],\n            item_count,\n            current: 0,\n        }\n    }\n\n    // Check if data in `buf` exist.\n    //\n    // Set into the current bloom filter if not exist.\n    //\n    // Return `true` if data exist in bloom filter.\n    pub fn check_and_set(&mut self, buf: &[u8]) -> bool {\n        for bloom in &self.blooms {\n            if bloom.check(buf) {\n                return true;\n            }\n        }\n\n        if self.bloom_count[self.current] >= self.item_count {\n            // Current bloom filter is full,\n            // Create a new one and use that one as current.\n\n            self.current = (self.current + 1) % 2;\n\n            self.bloom_count[self.current] = 0;\n            self.blooms[self.current].clear();\n\n            debug!(\n                \"bloom filter based replay protector full, each capacity: {}, total filters: {}\",\n                self.item_count,\n                self.blooms.len(),\n            );\n        }\n\n        // Cannot be optimized by `check_and_set`\n        // Because we have to check every filters in `blooms` before `set`\n        self.blooms[self.current].set(buf);\n        self.bloom_count[self.current] += 1;\n\n        false\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks/tests/tcp.rs",
    "content": "use std::{io, net::SocketAddr, sync::Arc};\n\nuse byte_string::ByteStr;\nuse futures::future;\nuse log::info;\nuse tokio::{\n    io::{AsyncBufReadExt, AsyncWriteExt, BufReader},\n    net::{TcpListener, TcpStream},\n    sync::Barrier,\n};\n\nuse shadowsocks::{\n    ProxyClientStream, ProxyListener,\n    config::{ServerConfig, ServerType},\n    context::Context,\n    crypto::CipherKind,\n    relay::{\n        socks5::Address,\n        tcprelay::{\n            proxy_stream::ProxyServerStream,\n            utils::{copy_from_encrypted, copy_to_encrypted},\n        },\n    },\n};\n\nasync fn handle_tcp_tunnel_server_client(\n    method: CipherKind,\n    mut stream: ProxyServerStream<TcpStream>,\n) -> io::Result<()> {\n    let addr = stream.handshake().await?;\n\n    let mut remote = {\n        let remote = match addr {\n            Address::SocketAddress(ref sa) => TcpStream::connect(sa).await?,\n            Address::DomainNameAddress(ref dname, port) => TcpStream::connect((dname.as_str(), port)).await?,\n        };\n\n        info!(\"connected to remote {}\", addr);\n        remote\n    };\n\n    let (mut sr, mut sw) = tokio::io::split(stream);\n    let (mut mr, mut mw) = remote.split();\n\n    let l2r = copy_from_encrypted(method, &mut sr, &mut mw);\n    let r2l = copy_to_encrypted(method, &mut mr, &mut sw);\n\n    tokio::pin!(l2r);\n    tokio::pin!(r2l);\n\n    let _ = future::select(l2r, r2l).await;\n\n    info!(\"TCP tunnel server finished\");\n\n    Ok(())\n}\n\nasync fn handle_tcp_tunnel_local_client(\n    context: Arc<Context>,\n    svr_cfg: Arc<ServerConfig>,\n    mut stream: TcpStream,\n) -> io::Result<()> {\n    let target_addr = Address::from((\"www.example.com\".to_owned(), 80));\n\n    let remote = ProxyClientStream::connect(context, &svr_cfg, target_addr).await?;\n\n    let (mut lr, mut lw) = stream.split();\n    let (mut sr, mut sw) = tokio::io::split(remote);\n\n    let l2s = copy_to_encrypted(svr_cfg.method(), &mut lr, &mut sw);\n    let s2l = copy_from_encrypted(svr_cfg.method(), &mut sr, &mut lw);\n\n    tokio::pin!(l2s);\n    tokio::pin!(s2l);\n\n    let _ = future::select(l2s, s2l).await;\n\n    info!(\"TCP tunnel client finished\");\n\n    Ok(())\n}\n\nasync fn tcp_tunnel_example(\n    server_addr: SocketAddr,\n    local_addr: SocketAddr,\n    password: &str,\n    method: CipherKind,\n) -> io::Result<()> {\n    let svr_cfg_server = ServerConfig::new(server_addr, password, method).unwrap();\n    let svr_cfg_local = svr_cfg_server.clone();\n\n    let ctx_server = Context::new_shared(ServerType::Server);\n    let ctx_local = Context::new_shared(ServerType::Local);\n\n    let barrier_server = Arc::new(Barrier::new(3));\n    let barrier_local = barrier_server.clone();\n    let barrier = barrier_local.clone();\n\n    tokio::spawn(async move {\n        let svr_cfg_server = Arc::new(svr_cfg_server);\n\n        let listener = ProxyListener::bind(ctx_server, &svr_cfg_server).await.unwrap();\n        info!(\"server listening on {}\", listener.local_addr().unwrap());\n\n        barrier_server.wait().await;\n\n        while let Ok((stream, peer_addr)) = listener.accept().await {\n            info!(\"server accepted stream {}\", peer_addr);\n            tokio::spawn(handle_tcp_tunnel_server_client(svr_cfg_server.method(), stream));\n        }\n    });\n\n    tokio::spawn(async move {\n        let svr_cfg_local = Arc::new(svr_cfg_local);\n\n        let listener = TcpListener::bind(local_addr).await.unwrap();\n        info!(\"local listening on {}\", listener.local_addr().unwrap());\n\n        barrier_local.wait().await;\n\n        while let Ok((stream, peer_addr)) = listener.accept().await {\n            info!(\"local accepted stream {}\", peer_addr);\n\n            let context = ctx_local.clone();\n            let svr_cfg = svr_cfg_local.clone();\n            tokio::spawn(handle_tcp_tunnel_local_client(context, svr_cfg, stream));\n        }\n    });\n\n    barrier.wait().await;\n\n    let mut client = TcpStream::connect(local_addr).await?;\n\n    const HTTP_REQUEST: &[u8] = b\"GET / HTTP/1.1\\r\\nHost: www.example.com\\r\\nAccept: */*\\r\\nConnection: close\\r\\n\\r\\n\";\n    client.write_all(HTTP_REQUEST).await?;\n\n    let mut reader = BufReader::new(client);\n\n    let mut buffer = Vec::new();\n    reader.read_until(b'\\n', &mut buffer).await?;\n\n    println!(\"{:?}\", ByteStr::new(&buffer));\n\n    const HTTP_RESPONSE_STATUS: &[u8] = b\"HTTP/1.1 200 OK\\r\\n\";\n    assert!(buffer.starts_with(HTTP_RESPONSE_STATUS));\n\n    Ok(())\n}\n\n#[cfg(feature = \"aead-cipher\")]\n#[tokio::test]\nasync fn tcp_tunnel_aead() {\n    let _ = env_logger::try_init();\n\n    let server_addr = \"127.0.0.1:31001\".parse::<SocketAddr>().unwrap();\n    let local_addr = \"127.0.0.1:31101\".parse::<SocketAddr>().unwrap();\n    tcp_tunnel_example(server_addr, local_addr, \"p$p\", CipherKind::AES_128_GCM)\n        .await\n        .unwrap();\n}\n\n#[cfg(feature = \"stream-cipher\")]\n#[tokio::test]\nasync fn tcp_tunnel_stream() {\n    let _ = env_logger::try_init();\n\n    let server_addr = \"127.0.0.1:32001\".parse::<SocketAddr>().unwrap();\n    let local_addr = \"127.0.0.1:32101\".parse::<SocketAddr>().unwrap();\n    tcp_tunnel_example(server_addr, local_addr, \"p$p\", CipherKind::AES_128_CFB128)\n        .await\n        .unwrap();\n}\n\n#[tokio::test]\nasync fn tcp_tunnel_none() {\n    let _ = env_logger::try_init();\n\n    let server_addr = \"127.0.0.1:33001\".parse::<SocketAddr>().unwrap();\n    let local_addr = \"127.0.0.1:33101\".parse::<SocketAddr>().unwrap();\n    tcp_tunnel_example(server_addr, local_addr, \"\", CipherKind::NONE)\n        .await\n        .unwrap();\n}\n\n#[cfg(feature = \"aead-cipher-2022\")]\n#[tokio::test]\nasync fn tcp_tunnel_aead_2022_aes() {\n    let _ = env_logger::try_init();\n\n    let server_addr = \"127.0.0.1:34001\".parse::<SocketAddr>().unwrap();\n    let local_addr = \"127.0.0.1:34101\".parse::<SocketAddr>().unwrap();\n    tcp_tunnel_example(\n        server_addr,\n        local_addr,\n        \"3L69X4PF2eSL/JSLkoWnXg==\",\n        CipherKind::AEAD2022_BLAKE3_AES_128_GCM,\n    )\n    .await\n    .unwrap();\n}\n\n#[cfg(feature = \"aead-cipher-2022\")]\n#[tokio::test]\nasync fn tcp_tunnel_aead_2022_chacha20() {\n    let _ = env_logger::try_init();\n\n    let server_addr = \"127.0.0.1:35001\".parse::<SocketAddr>().unwrap();\n    let local_addr = \"127.0.0.1:35101\".parse::<SocketAddr>().unwrap();\n    tcp_tunnel_example(\n        server_addr,\n        local_addr,\n        \"VUw3mGWIpil2z2DKiyauE2Sp9KyE2ab8dulciawe74o\",\n        CipherKind::AEAD2022_BLAKE3_CHACHA20_POLY1305,\n    )\n    .await\n    .unwrap();\n}\n"
  },
  {
    "path": "crates/shadowsocks/tests/tcp_tfo.rs",
    "content": "#![cfg(any(\n    windows,\n    target_os = \"linux\",\n    target_os = \"android\",\n    target_os = \"macos\",\n    target_os = \"ios\",\n    target_os = \"tvos\",\n    target_os = \"watchos\",\n    target_os = \"freebsd\"\n))]\n\nuse byte_string::ByteStr;\nuse futures::future;\nuse log::debug;\nuse shadowsocks::{\n    ProxyClientStream, ProxyListener, ServerConfig,\n    config::ServerType,\n    context::Context,\n    crypto::CipherKind,\n    net::{AcceptOpts, ConnectOpts},\n    relay::{\n        socks5::Address,\n        tcprelay::utils::{copy_from_encrypted, copy_to_encrypted},\n    },\n};\nuse tokio::{\n    io::{AsyncBufReadExt, AsyncWriteExt, BufReader},\n    net::TcpStream,\n};\n\n#[tokio::test]\nasync fn tcp_tunnel_tfo() {\n    let _ = env_logger::try_init();\n\n    let svr_cfg = ServerConfig::new((\"127.0.0.1\", 41000), \"\", CipherKind::NONE).unwrap();\n    let svr_cfg_client = svr_cfg.clone();\n\n    tokio::spawn(async move {\n        let context = Context::new_shared(ServerType::Server);\n\n        let mut accept_opts = AcceptOpts::default();\n        accept_opts.tcp.fastopen = true;\n\n        let listener = ProxyListener::bind_with_opts(context, &svr_cfg, accept_opts)\n            .await\n            .unwrap();\n\n        while let Ok((mut stream, peer_addr)) = listener.accept().await {\n            debug!(\"accepted {}\", peer_addr);\n\n            tokio::spawn(async move {\n                let addr = stream.handshake().await.unwrap();\n                let remote = match addr {\n                    Address::SocketAddress(a) => TcpStream::connect(a).await.unwrap(),\n                    Address::DomainNameAddress(name, port) => TcpStream::connect((name.as_str(), port)).await.unwrap(),\n                };\n\n                let (mut lr, mut lw) = tokio::io::split(stream);\n                let (mut rr, mut rw) = remote.into_split();\n\n                let l2r = copy_from_encrypted(CipherKind::NONE, &mut lr, &mut rw);\n                let r2l = copy_to_encrypted(CipherKind::NONE, &mut rr, &mut lw);\n\n                tokio::pin!(l2r);\n                tokio::pin!(r2l);\n\n                let _ = future::select(l2r, r2l).await;\n            });\n        }\n    });\n\n    tokio::task::yield_now().await;\n\n    let context = Context::new_shared(ServerType::Local);\n\n    let mut connect_opts = ConnectOpts::default();\n    connect_opts.tcp.fastopen = true;\n\n    let mut client = ProxyClientStream::connect_with_opts(\n        context,\n        &svr_cfg_client,\n        (\"www.example.com\".to_owned(), 80),\n        &connect_opts,\n    )\n    .await\n    .unwrap();\n\n    client\n        .write_all(b\"GET / HTTP/1.1\\r\\nHost: www.example.com\\r\\nAccept: */*\\r\\nConnection: close\\r\\n\\r\\n\")\n        .await\n        .unwrap();\n\n    let mut reader = BufReader::new(client);\n\n    let mut buffer = Vec::new();\n    reader.read_until(b'\\n', &mut buffer).await.unwrap();\n\n    println!(\"{:?}\", ByteStr::new(&buffer));\n\n    const HTTP_RESPONSE_STATUS: &[u8] = b\"HTTP/1.1 200 OK\\r\\n\";\n    assert!(buffer.starts_with(HTTP_RESPONSE_STATUS));\n}\n"
  },
  {
    "path": "crates/shadowsocks/tests/udp.rs",
    "content": "use std::{io, net::SocketAddr, sync::Arc};\n\nuse byte_string::ByteStr;\nuse log::info;\nuse tokio::{net::UdpSocket, sync::Barrier};\n\nuse shadowsocks::{\n    config::{ServerConfig, ServerType},\n    context::{Context, SharedContext},\n    crypto::CipherKind,\n    net::UdpSocket as ShadowUdpSocket,\n    relay::{socks5::Address, udprelay::ProxySocket},\n};\n\nasync fn handle_udp_server_client(\n    peer_addr: SocketAddr,\n    remote_addr: Address,\n    payload: &[u8],\n    socket: &ProxySocket<ShadowUdpSocket>,\n) -> io::Result<()> {\n    let remote_socket = UdpSocket::bind(\"0.0.0.0:0\").await?;\n\n    match remote_addr {\n        Address::SocketAddress(sa) => remote_socket.connect(sa).await?,\n        Address::DomainNameAddress(ref domain, port) => remote_socket.connect((domain.as_str(), port)).await?,\n    }\n\n    remote_socket.send(payload).await?;\n\n    let mut buf = [0u8; 65536];\n    let n = remote_socket.recv(&mut buf).await?;\n\n    socket.send_to(peer_addr, &remote_addr, &buf[..n]).await?;\n\n    Ok(())\n}\n\nasync fn handle_udp_local_client(\n    context: SharedContext,\n    svr_cfg: &ServerConfig,\n    peer_addr: SocketAddr,\n    remote_addr: Address,\n    payload: &[u8],\n    socket: &UdpSocket,\n) -> io::Result<()> {\n    let server_socket = ProxySocket::connect(context, svr_cfg).await?;\n    server_socket.send(&remote_addr, payload).await?;\n\n    let mut recv_buf = [0u8; 65536];\n    let (n, ..) = server_socket.recv(&mut recv_buf).await?;\n    socket.send_to(&recv_buf[..n], peer_addr).await?;\n\n    Ok(())\n}\n\nasync fn udp_tunnel_echo(\n    server_addr: SocketAddr,\n    local_addr: SocketAddr,\n    target_addr: SocketAddr,\n    password: &str,\n    method: CipherKind,\n) -> io::Result<()> {\n    let svr_cfg_server = ServerConfig::new(server_addr, password, method).unwrap();\n    let svr_cfg_local = svr_cfg_server.clone();\n\n    let ctx_server = Context::new_shared(ServerType::Server);\n    let ctx_local = Context::new_shared(ServerType::Local);\n\n    let barrier_server = Arc::new(Barrier::new(4));\n    let barrier_local = barrier_server.clone();\n    let barrier_target = barrier_server.clone();\n    let barrier = barrier_server.clone();\n\n    tokio::spawn(async move {\n        let socket = UdpSocket::bind(target_addr).await.unwrap();\n        barrier_target.wait().await;\n\n        let mut buffer = vec![0u8; 65536];\n        loop {\n            let (n, peer_addr) = socket.recv_from(&mut buffer).await.unwrap();\n            info!(\"echo packet: {:?}\", ByteStr::new(&buffer[..n]));\n            let _ = socket.send_to(&buffer[..n], peer_addr).await;\n        }\n    });\n\n    tokio::spawn(async move {\n        let svr_cfg_server = Arc::new(svr_cfg_server);\n        let context = ctx_server;\n\n        let socket = ProxySocket::bind(context.clone(), &svr_cfg_server).await.unwrap();\n        barrier_server.wait().await;\n\n        let mut recv_buf = vec![0u8; 65536];\n        loop {\n            let (n, peer_addr, remote_addr, ..) = socket.recv_from(&mut recv_buf).await.unwrap();\n            let _ = handle_udp_server_client(peer_addr, remote_addr, &recv_buf[..n], &socket).await;\n        }\n    });\n\n    tokio::spawn(async move {\n        let svr_cfg_local = Arc::new(svr_cfg_local);\n\n        let socket = UdpSocket::bind(local_addr).await.unwrap();\n        barrier_local.wait().await;\n\n        let context = ctx_local;\n\n        let mut buffer = vec![0u8; 65536];\n        loop {\n            let (n, peer_addr) = socket.recv_from(&mut buffer).await.unwrap();\n            let _ = handle_udp_local_client(\n                context.clone(),\n                &svr_cfg_local,\n                peer_addr,\n                target_addr.into(),\n                &buffer[..n],\n                &socket,\n            )\n            .await;\n        }\n    });\n\n    barrier.wait().await;\n\n    let socket = UdpSocket::bind(\"0.0.0.0:0\").await?;\n    socket.connect(local_addr).await?;\n\n    const SEND_PAYLOAD: &[u8] = b\"HELLO WORLD. \\x0012345\";\n    socket.send(SEND_PAYLOAD).await?;\n\n    let mut buffer = [0u8; 65536];\n    let n = socket.recv(&mut buffer).await?;\n\n    assert_eq!(&buffer[..n], SEND_PAYLOAD);\n\n    Ok(())\n}\n\n#[cfg(feature = \"aead-cipher\")]\n#[tokio::test]\nasync fn udp_tunnel_aead() {\n    let _ = env_logger::try_init();\n\n    let server_addr = \"127.0.0.1:21001\".parse::<SocketAddr>().unwrap();\n    let local_addr = \"127.0.0.1:21101\".parse::<SocketAddr>().unwrap();\n    let target_addr = \"127.0.0.1:21201\".parse::<SocketAddr>().unwrap();\n\n    udp_tunnel_echo(server_addr, local_addr, target_addr, \"pas$$\", CipherKind::AES_128_GCM)\n        .await\n        .unwrap();\n}\n\n#[cfg(feature = \"stream-cipher\")]\n#[tokio::test]\nasync fn udp_tunnel_stream() {\n    let _ = env_logger::try_init();\n\n    let server_addr = \"127.0.0.1:22001\".parse::<SocketAddr>().unwrap();\n    let local_addr = \"127.0.0.1:22101\".parse::<SocketAddr>().unwrap();\n    let target_addr = \"127.0.0.1:22201\".parse::<SocketAddr>().unwrap();\n\n    udp_tunnel_echo(\n        server_addr,\n        local_addr,\n        target_addr,\n        \"pas$$\",\n        CipherKind::AES_128_CFB128,\n    )\n    .await\n    .unwrap();\n}\n\n#[tokio::test]\nasync fn udp_tunnel_none() {\n    let _ = env_logger::try_init();\n\n    let server_addr = \"127.0.0.1:23001\".parse::<SocketAddr>().unwrap();\n    let local_addr = \"127.0.0.1:23101\".parse::<SocketAddr>().unwrap();\n    let target_addr = \"127.0.0.1:23201\".parse::<SocketAddr>().unwrap();\n\n    udp_tunnel_echo(server_addr, local_addr, target_addr, \"pas$$\", CipherKind::NONE)\n        .await\n        .unwrap();\n}\n\n#[cfg(feature = \"aead-cipher-2022\")]\n#[tokio::test]\nasync fn udp_tunnel_aead_2022_aes() {\n    let _ = env_logger::try_init();\n\n    let server_addr = \"127.0.0.1:24001\".parse::<SocketAddr>().unwrap();\n    let local_addr = \"127.0.0.1:24101\".parse::<SocketAddr>().unwrap();\n    let target_addr = \"127.0.0.1:24201\".parse::<SocketAddr>().unwrap();\n\n    udp_tunnel_echo(\n        server_addr,\n        local_addr,\n        target_addr,\n        \"D1HJFfvRIxpklHLeKvjCDQ==\",\n        CipherKind::AEAD2022_BLAKE3_AES_128_GCM,\n    )\n    .await\n    .unwrap();\n}\n\n#[cfg(feature = \"aead-cipher-2022\")]\n#[tokio::test]\nasync fn udp_tunnel_aead_2022_chacha20() {\n    let _ = env_logger::try_init();\n\n    let server_addr = \"127.0.0.1:25001\".parse::<SocketAddr>().unwrap();\n    let local_addr = \"127.0.0.1:25101\".parse::<SocketAddr>().unwrap();\n    let target_addr = \"127.0.0.1:25201\".parse::<SocketAddr>().unwrap();\n\n    udp_tunnel_echo(\n        server_addr,\n        local_addr,\n        target_addr,\n        \"4wYfDniq4N6kMqFajRO03PPZLfPkl469eNYY9Wz0E78=\",\n        CipherKind::AEAD2022_BLAKE3_CHACHA20_POLY1305,\n    )\n    .await\n    .unwrap();\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/Cargo.toml",
    "content": "[package]\nname = \"shadowsocks-service\"\nversion = \"1.24.0\"\nauthors = [\"Shadowsocks Contributors\"]\ndescription = \"shadowsocks is a fast tunnel proxy that helps you bypass firewalls.\"\nrepository = \"https://github.com/shadowsocks/shadowsocks-rust\"\nreadme = \"README.md\"\ndocumentation = \"https://docs.rs/shadowsocks-service\"\nkeywords = [\"shadowsocks\", \"proxy\", \"socks\", \"socks5\", \"firewall\"]\nlicense = \"MIT\"\nedition = \"2024\"\nrust-version = \"1.88\"\n\n[badges]\nmaintenance = { status = \"passively-maintained\" }\n\n[features]\ndefault = [\"hickory-dns\", \"aead-cipher\"]\n\nfull = [\n    \"local\",\n    \"server\",\n    \"manager\",\n    \"hickory-dns\",\n    \"local-http\",\n    \"local-redir\",\n    \"local-tunnel\",\n    \"local-socks4\",\n    \"aead-cipher\",\n]\n\n# Enable local server\nlocal = [\"httparse\"]\n# Enable remote server\nserver = []\n# Enable manager server\nmanager = [\"server\"]\n\n# Enables Hickory-DNS for replacing tokio's builtin DNS resolver\nhickory-dns = [\"hickory-resolver\", \"shadowsocks/trust-dns\"]\n# Hickory-DNS was renamed from Trust-DNS, keep compatibility.\ntrust-dns = [\"hickory-dns\"]\ndns-over-tls = [\n    \"hickory-dns\",\n    \"hickory-resolver/tls-ring\",\n    \"hickory-resolver/webpki-roots\",\n]\ndns-over-https = [\n    \"hickory-dns\",\n    \"hickory-resolver/https-ring\",\n    \"hickory-resolver/webpki-roots\",\n]\ndns-over-h3 = [\"hickory-dns\", \"hickory-resolver/h3-ring\"]\n\n# Enable DNS-relay\nlocal-dns = [\"local\", \"hickory-dns\"]\n# Backward compatibility, DO NOT USE\nlocal-dns-relay = [\"local-dns\"]\n# Enable client flow statistic report\n# Currently is only used in Android\nlocal-flow-stat = [\"local\"]\n# Enable HTTP protocol for sslocal\nlocal-http = [\"local\", \"hyper\", \"http\", \"http-body-util\", \"base64\"]\nlocal-http-native-tls = [\"local-http\", \"tokio-native-tls\", \"native-tls\"]\nlocal-http-native-tls-vendored = [\n    \"local-http-native-tls\",\n    \"tokio-native-tls/vendored\",\n    \"native-tls/vendored\",\n]\nlocal-http-rustls = [\n    \"local-http\",\n    \"tokio-rustls\",\n    \"webpki-roots\",\n    \"rustls-native-certs\",\n]\n# Enable REDIR protocol for sslocal\n# (transparent proxy)\nlocal-redir = [\"local\"]\n# Enable tunnel protocol for sslocal\nlocal-tunnel = [\"local\"]\n# Enable socks4 protocol for sslocal\nlocal-socks4 = [\"local\"]\n# Enable Tun interface protocol for sslocal\nlocal-tun = [\"local\", \"etherparse\", \"tun\", \"smoltcp\"]\n# Enable Fake DNS\nlocal-fake-dns = [\"local\", \"trust-dns\", \"rocksdb\", \"bson\"]\n# sslocal support online URL (SIP008 Online Configuration Delivery)\n# https://shadowsocks.org/doc/sip008.html\nlocal-online-config = [\n    \"local\",\n    \"local-http\",\n    \"mime\",\n    \"http\",\n    \"flate2\",\n    \"brotli\",\n    \"zstd\",\n]\n\n# Enable Stream Cipher Protocol\n# WARN: Stream Cipher Protocol is proved to be insecure\n# https://github.com/shadowsocks/shadowsocks-rust/issues/373\n# Users should always avoid using these ciphers in practice\nstream-cipher = [\"shadowsocks/stream-cipher\"]\n\n# Enable AEAD ciphers\naead-cipher = [\"shadowsocks/aead-cipher\"]\n\n# Enable extra AEAD ciphers\n# WARN: These non-standard AEAD ciphers are not officially supported by shadowsocks community\naead-cipher-extra = [\"aead-cipher\", \"shadowsocks/aead-cipher-extra\"]\n\n# Enable AEAD 2022\naead-cipher-2022 = [\"shadowsocks/aead-cipher-2022\"]\n# Enable AEAD 2022 with extra ciphers\naead-cipher-2022-extra = [\n    \"aead-cipher-2022\",\n    \"shadowsocks/aead-cipher-2022-extra\",\n]\n\n# Enable detection against replay attack\nsecurity-replay-attack-detect = [\"shadowsocks/security-replay-attack-detect\"]\n\n[dependencies]\nlog = \"0.4\"\n\ncfg-if = \"1\"\npin-project = \"1.1\"\nthiserror = \"2.0\"\narc-swap = \"1.7\"\n\nspin = { version = \"0.10\" }\nlru_time_cache = \"0.11\"\nbytes = \"1.7\"\nbyte_string = \"1.0\"\nbyteorder = \"1.5\"\nrand = \"0.10\"\nrocksdb = { version = \"0.24\", optional = true }\n\nfutures = \"0.3\"\ntokio = { version = \"1.38\", features = [\n    \"io-util\",\n    \"macros\",\n    \"net\",\n    \"parking_lot\",\n    \"rt\",\n    \"sync\",\n    \"time\",\n] }\ntokio-native-tls = { version = \"0.3\", optional = true }\nnative-tls = { version = \"0.2.8\", optional = true, features = [\"alpn\"] }\nwebpki-roots = { version = \"1.0\", optional = true }\ntokio-rustls = { version = \"0.26\", optional = true, default-features = false, features = [\n    \"logging\",\n    \"tls12\",\n    \"ring\",\n] }\nrustls-native-certs = { version = \"0.8\", optional = true }\ntrait-variant = \"0.1\"\n\nsocket2 = { version = \"0.6\", features = [\"all\"] }\nlibc = \"~0.2.141\"\n\nhyper = { version = \"1.4\", optional = true, features = [\"full\"] }\nhttp-body-util = { version = \"0.1\", optional = true }\nhttp = { version = \"1.1\", optional = true }\nhttparse = { version = \"1.9\", optional = true }\n\nhickory-resolver = { version = \"0.25\", optional = true, features = [\"serde\"] }\n\nidna = \"1.0\"\nipnet = \"2.10\"\niprange = \"0.6\"\nregex = { version = \"1.4\", default-features = false, features = [\n    \"std\",\n    \"perf\",\n] }\n\nmime = { version = \"0.3\", optional = true }\nflate2 = { version = \"1.0\", optional = true }\nbrotli = { version = \"8.0\", optional = true }\nzstd = { version = \"0.13\", optional = true }\nbase64 = { version = \"0.22\", optional = true }\n\netherparse = { version = \"0.19\", optional = true }\nsmoltcp = { version = \"0.12\", optional = true, default-features = false, features = [\n    \"std\",\n    \"log\",\n    \"medium-ip\",\n    \"proto-ipv4\",\n    \"proto-ipv4-fragmentation\",\n    \"proto-ipv6\",\n    \"socket-icmp\",\n    \"socket-udp\",\n    \"socket-tcp\",\n    \"socket-tcp-cubic\",\n] }\n\nserde = { version = \"1.0\", features = [\"derive\"] }\njson5 = \"1.3\"\nserde_json = \"1.0\"\nbson = { version = \"3.0.0\", features = [\"serde\"], optional = true }\n\nshadowsocks = { version = \"1.24.0\", path = \"../shadowsocks\", default-features = false }\n\n# Just for the ioctl call macro\n[target.'cfg(any(target_os = \"macos\", target_os = \"ios\", target_os = \"freebsd\", target_os = \"openbsd\"))'.dependencies]\nnix = { version = \"0.31\", features = [\"ioctl\"] }\n\n[target.'cfg(windows)'.dependencies]\nwindows-sys = { version = \"0.61\", features = [\"Win32_Networking_WinSock\"] }\n\n[target.'cfg(any(target_os = \"ios\", target_os = \"macos\", target_os = \"linux\", target_os = \"android\", target_os = \"windows\", target_os = \"freebsd\"))'.dependencies]\ntun = { version = \"0.8\", optional = true, features = [\"async\"] }\n\n[dev-dependencies]\nbyteorder = \"1.5\"\nenv_logger = \"0.11\"\n\n[package.metadata.docs.rs]\nfeatures = [\n    \"full\",\n    \"local-http-rustls\",\n    \"local-dns\",\n    \"dns-over-tls\",\n    \"dns-over-https\",\n]\n\n[lints.clippy]\nuninlined_format_args = \"allow\"\n"
  },
  {
    "path": "crates/shadowsocks-service/README.md",
    "content": "# shadowsocks-service\n\n[![License](https://img.shields.io/github/license/zonyitoo/shadowsocks-rust.svg)](https://github.com/zonyitoo/shadowsocks-rust)\n[![crates.io](https://img.shields.io/crates/v/shadowsocks-service.svg)](https://crates.io/crates/shadowsocks-service)\n[![docs.rs](https://img.shields.io/docsrs/shadowsocks-service)](https://docs.rs/shadowsocks-service)\n\nThis is a port of [shadowsocks](https://github.com/shadowsocks/shadowsocks).\n\nshadowsocks is a fast tunnel proxy that helps you bypass firewalls.\n\n## Features\n\n* Local Server\n\n  * SOCKS 5\n  * SOCKS 4/4a (`local-socks4`)\n  * HTTP (`local-http`)\n  * Tunnel (`local-tunnel`)\n  * Redir, aka Transparent Proxy (`local-redir`)\n  * DNS (`local-dns`)\n  * Tun (`local-tun`)\n  * FakeDNS (`local-fake-dns`)\n  * SIP008 Online Config (`local-online-config`)\n\n* Server\n\n* Manager\n\n  * API References: [Manage Multiple Users](https://github.com/shadowsocks/shadowsocks/wiki/Manage-Multiple-Users)\n"
  },
  {
    "path": "crates/shadowsocks-service/src/acl/mod.rs",
    "content": "//! Access Control List (ACL) for shadowsocks\n//!\n//! This is for advance controlling server behaviors in both local and proxy servers.\n\nuse std::{\n    borrow::Cow,\n    collections::HashSet,\n    fmt,\n    fs::File,\n    io::{self, BufRead, BufReader, Error},\n    net::{IpAddr, SocketAddr},\n    path::{Path, PathBuf},\n    str,\n    sync::LazyLock,\n};\n\nuse ipnet::{IpNet, Ipv4Net, Ipv6Net};\nuse iprange::IpRange;\nuse log::{trace, warn};\nuse regex::bytes::{Regex, RegexBuilder, RegexSet, RegexSetBuilder};\n\nuse shadowsocks::{context::Context, relay::socks5::Address};\n\nuse self::sub_domains_tree::SubDomainsTree;\n\nmod sub_domains_tree;\n\n/// Strategy mode that ACL is running\n#[derive(Debug, Copy, Clone, Eq, PartialEq)]\npub enum Mode {\n    /// BlackList mode, rejects or bypasses all requests by default\n    BlackList,\n    /// WhiteList mode, accepts or proxies all requests by default\n    WhiteList,\n}\n\n#[derive(Clone)]\nstruct Rules {\n    ipv4: IpRange<Ipv4Net>,\n    ipv6: IpRange<Ipv6Net>,\n    rule_regex: RegexSet,\n    rule_set: HashSet<String>,\n    rule_tree: SubDomainsTree,\n}\n\nimpl fmt::Debug for Rules {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(\n            f,\n            \"Rules {{ ipv4: {:?}, ipv6: {:?}, rule_regex: [\",\n            self.ipv4, self.ipv6\n        )?;\n\n        let max_len = 2;\n        let has_more = self.rule_regex.len() > max_len;\n\n        for (idx, r) in self.rule_regex.patterns().iter().take(max_len).enumerate() {\n            if idx > 0 {\n                f.write_str(\", \")?;\n            }\n            f.write_str(r)?;\n        }\n\n        if has_more {\n            f.write_str(\", ...\")?;\n        }\n\n        write!(f, \"], rule_set: [\")?;\n\n        let has_more = self.rule_set.len() > max_len;\n        for (idx, r) in self.rule_set.iter().take(max_len).enumerate() {\n            if idx > 0 {\n                f.write_str(\", \")?;\n            }\n            f.write_str(r)?;\n        }\n\n        if has_more {\n            f.write_str(\", ...\")?;\n        }\n\n        write!(f, \"], rule_tree: {:?} }}\", self.rule_tree)\n    }\n}\n\nimpl Rules {\n    /// Create a new rule\n    fn new(\n        mut ipv4: IpRange<Ipv4Net>,\n        mut ipv6: IpRange<Ipv6Net>,\n        rule_regex: RegexSet,\n        rule_set: HashSet<String>,\n        rule_tree: SubDomainsTree,\n    ) -> Self {\n        // Optimization, merging networks\n        ipv4.simplify();\n        ipv6.simplify();\n\n        Self {\n            ipv4,\n            ipv6,\n            rule_regex,\n            rule_set,\n            rule_tree,\n        }\n    }\n\n    /// Check if the specified address matches these rules\n    #[allow(dead_code)]\n    fn check_address_matched(&self, addr: &Address) -> bool {\n        match *addr {\n            Address::SocketAddress(ref saddr) => self.check_ip_matched(&saddr.ip()),\n            Address::DomainNameAddress(ref domain, ..) => self.check_host_matched(domain),\n        }\n    }\n\n    /// Check if the specified address matches any rules\n    fn check_ip_matched(&self, addr: &IpAddr) -> bool {\n        match addr {\n            IpAddr::V4(v4) => {\n                if self.ipv4.contains(v4) {\n                    return true;\n                }\n\n                let mapped_ipv6 = v4.to_ipv6_mapped();\n                self.ipv6.contains(&mapped_ipv6)\n            }\n            IpAddr::V6(v6) => {\n                if self.ipv6.contains(v6) {\n                    return true;\n                }\n\n                if let Some(mapped_ipv4) = v6.to_ipv4_mapped() {\n                    return self.ipv4.contains(&mapped_ipv4);\n                }\n\n                false\n            }\n        }\n    }\n\n    /// Check if the specified ASCII host matches any rules\n    fn check_host_matched(&self, host: &str) -> bool {\n        let host = host.trim_end_matches('.'); // FQDN, removes the last `.`\n        self.rule_set.contains(host) || self.rule_tree.contains(host) || self.rule_regex.is_match(host.as_bytes())\n    }\n\n    /// Check if there are no rules for IP addresses\n    fn is_ip_empty(&self) -> bool {\n        self.ipv4.is_empty() && self.ipv6.is_empty()\n    }\n\n    /// Check if there are no rules for domain names\n    fn is_host_empty(&self) -> bool {\n        self.rule_set.is_empty() && self.rule_tree.is_empty() && self.rule_regex.is_empty()\n    }\n}\n\nstruct ParsingRules {\n    name: &'static str,\n    ipv4: IpRange<Ipv4Net>,\n    ipv6: IpRange<Ipv6Net>,\n    rules_regex: Vec<String>,\n    rules_set: HashSet<String>,\n    rules_tree: SubDomainsTree,\n}\n\nimpl ParsingRules {\n    fn new(name: &'static str) -> Self {\n        Self {\n            name,\n            ipv4: IpRange::new(),\n            ipv6: IpRange::new(),\n            rules_regex: Vec::new(),\n            rules_set: HashSet::new(),\n            rules_tree: SubDomainsTree::new(),\n        }\n    }\n\n    fn add_ipv4_rule(&mut self, rule: impl Into<Ipv4Net>) {\n        let rule = rule.into();\n        trace!(\"IPV4-RULE {}\", rule);\n        self.ipv4.add(rule);\n    }\n\n    fn add_ipv6_rule(&mut self, rule: impl Into<Ipv6Net>) {\n        let rule = rule.into();\n        trace!(\"IPV6-RULE {}\", rule);\n        self.ipv6.add(rule);\n    }\n\n    fn add_regex_rule(&mut self, mut rule: String) {\n        static TREE_SET_RULE_EQUIV: LazyLock<Regex> = LazyLock::new(|| {\n            RegexBuilder::new(\n                r#\"^(?:(?:\\((?:\\?:)?\\^\\|\\\\\\.\\)|(?:\\^\\.(?:\\+|\\*))?\\\\\\.)((?:[\\w-]+(?:\\\\\\.)?)+)|\\^((?:[\\w-]+(?:\\\\\\.)?)+))\\$?$\"#,\n            )\n            .unicode(false)\n            .build()\n            .unwrap()\n        });\n\n        if let Some(caps) = TREE_SET_RULE_EQUIV.captures(rule.as_bytes()) {\n            if let Some(tree_rule) = caps.get(1) {\n                if let Ok(tree_rule) = str::from_utf8(tree_rule.as_bytes()) {\n                    let tree_rule = tree_rule.replace(\"\\\\.\", \".\");\n                    if self.add_tree_rule_inner(&tree_rule).is_ok() {\n                        trace!(\"REGEX-RULE {} => TREE-RULE {}\", rule, tree_rule);\n                        return;\n                    }\n                }\n            } else if let Some(set_rule) = caps.get(2)\n                && let Ok(set_rule) = str::from_utf8(set_rule.as_bytes())\n            {\n                let set_rule = set_rule.replace(\"\\\\.\", \".\");\n                if self.add_set_rule_inner(&set_rule).is_ok() {\n                    trace!(\"REGEX-RULE {} => SET-RULE {}\", rule, set_rule);\n                    return;\n                }\n            }\n        }\n\n        trace!(\"REGEX-RULE {}\", rule);\n\n        rule.make_ascii_lowercase();\n\n        // Handle it as a normal REGEX\n        // FIXME: If this line is not a valid regex, how can we know without actually compile it?\n        self.rules_regex.push(rule);\n    }\n\n    #[inline]\n    fn add_set_rule(&mut self, rule: &str) -> io::Result<()> {\n        trace!(\"SET-RULE {}\", rule);\n        self.add_set_rule_inner(rule)\n    }\n\n    fn add_set_rule_inner(&mut self, rule: &str) -> io::Result<()> {\n        self.rules_set.insert(self.check_is_ascii(rule)?.to_ascii_lowercase());\n        Ok(())\n    }\n\n    #[inline]\n    fn add_tree_rule(&mut self, rule: &str) -> io::Result<()> {\n        trace!(\"TREE-RULE {}\", rule);\n        self.add_tree_rule_inner(rule)\n    }\n\n    fn add_tree_rule_inner(&mut self, rule: &str) -> io::Result<()> {\n        // SubDomainsTree do lowercase conversion inside insert\n        self.rules_tree.insert(self.check_is_ascii(rule)?);\n        Ok(())\n    }\n\n    fn check_is_ascii<'a>(&self, str: &'a str) -> io::Result<&'a str> {\n        if str.is_ascii() {\n            // Remove the last `.` of FQDN\n            Ok(str.trim_end_matches('.'))\n        } else {\n            Err(Error::other(format!(\n                \"{} parsing error: Unicode not allowed here `{}`\",\n                self.name, str\n            )))\n        }\n    }\n\n    fn compile_regex(name: &'static str, regex_rules: Vec<String>) -> io::Result<RegexSet> {\n        const REGEX_SIZE_LIMIT: usize = usize::MAX;\n        RegexSetBuilder::new(regex_rules)\n            .size_limit(REGEX_SIZE_LIMIT)\n            .unicode(false)\n            .build()\n            .map_err(|err| Error::other(format!(\"{name} regex error: {err}\")))\n    }\n\n    fn into_rules(self) -> io::Result<Rules> {\n        Ok(Rules::new(\n            self.ipv4,\n            self.ipv6,\n            Self::compile_regex(self.name, self.rules_regex)?,\n            self.rules_set,\n            self.rules_tree,\n        ))\n    }\n}\n\n/// ACL rules\n///\n/// ## Sections\n///\n/// ACL File is formatted in sections, each section has a name with surrounded by brackets `[` and `]`\n/// followed by Rules line by line.\n///\n/// ```plain\n/// [SECTION-1]\n/// RULE-1\n/// RULE-2\n/// RULE-3\n///\n/// [SECTION-2]\n/// RULE-1\n/// RULE-2\n/// RULE-3\n/// ```\n///\n/// Available sections are\n///\n/// - For local servers (`sslocal`, `ssredir`, ...)\n///     * `[bypass_all]` - ACL runs in `WhiteList` mode.\n///     * `[proxy_all]` - ACL runs in `BlackList` mode.\n///     * `[bypass_list]` - Rules for connecting directly\n///     * `[proxy_list]` - Rules for connecting through proxies\n/// - For remote servers (`ssserver`)\n///     * `[reject_all]` - ACL runs in `WhiteList` mode.\n///     * `[accept_all]` - ACL runs in `BlackList` mode.\n///     * `[black_list]` - Rules for rejecting\n///     * `[white_list]` - Rules for allowing\n///     * `[outbound_block_all]` - ACL runs in `WhiteList` mode for outbound addresses.\n///     * `[outbound_allow_all]` - ACL runs in `BlackList` mode for outbound addresses.\n///     * `[outbound_block_list]` - Rules for blocking outbound addresses.\n///     * `[outbound_allow_list]` - Rules for allowing outbound addresses.\n///\n/// ## Mode\n///\n/// Mode is the default ACL strategy for those addresses that are not in configuration file.\n///\n/// - `WhiteList` - Bypasses / Rejects all addresses except those in `[proxy_list]` or `[white_list]`\n/// - `BlackList` - Proxies / Accepts all addresses except those in `[bypass_list]` or `[black_list]`\n///\n/// ## Rules\n///\n/// Rules can be either\n///\n/// - CIDR form network addresses, like `10.9.0.32/16`\n/// - IP addresses, like `127.0.0.1` or `::1`\n/// - Regular Expression for matching hosts, like `(^|\\.)gmail\\.com$`\n/// - Domain with preceding `|` for exact matching, like `|google.com`\n/// - Domain with preceding `||` for matching with subdomains, like `||google.com`\n#[derive(Debug, Clone)]\npub struct AccessControl {\n    outbound_block: Rules,\n    outbound_allow: Rules,\n    black_list: Rules,\n    white_list: Rules,\n    mode: Mode,\n    outbound_mode: Mode,\n    file_path: PathBuf,\n}\n\nimpl AccessControl {\n    /// Load ACL rules from a file\n    pub fn load_from_file<P: AsRef<Path>>(p: P) -> io::Result<Self> {\n        trace!(\"ACL loading from {:?}\", p.as_ref());\n\n        let file_path_ref = p.as_ref();\n        let file_path = file_path_ref.to_path_buf();\n\n        let fp = File::open(file_path_ref)?;\n        let r = BufReader::new(fp);\n\n        let mut mode = Mode::BlackList;\n        let mut outbound_mode = Mode::BlackList;\n\n        let mut outbound_block = ParsingRules::new(\"[outbound_block_list]\");\n        let mut outbound_allow = ParsingRules::new(\"[outbound_allow_list]\");\n        let mut bypass = ParsingRules::new(\"[black_list] or [bypass_list]\");\n        let mut proxy = ParsingRules::new(\"[white_list] or [proxy_list]\");\n        let mut curr = &mut bypass;\n\n        trace!(\"ACL parsing start from mode {:?} and black_list / bypass_list\", mode);\n\n        for line in r.lines() {\n            let line = line?;\n            if line.is_empty() {\n                continue;\n            }\n\n            // Comments\n            if line.starts_with('#') {\n                continue;\n            }\n\n            let line = line.trim();\n\n            if !line.is_ascii() {\n                warn!(\"ACL rule {} containing non-ASCII characters, skipped\", line);\n                continue;\n            }\n\n            if let Some(rule) = line.strip_prefix(\"||\") {\n                curr.add_tree_rule(rule)?;\n                continue;\n            }\n\n            if let Some(rule) = line.strip_prefix('|') {\n                curr.add_set_rule(rule)?;\n                continue;\n            }\n\n            match line {\n                \"[reject_all]\" | \"[bypass_all]\" => {\n                    mode = Mode::WhiteList;\n                    trace!(\"switch to mode {:?}\", mode);\n                }\n                \"[accept_all]\" | \"[proxy_all]\" => {\n                    mode = Mode::BlackList;\n                    trace!(\"switch to mode {:?}\", mode);\n                }\n                \"[outbound_block_all]\" => {\n                    outbound_mode = Mode::WhiteList;\n                    trace!(\"switch to outbound_mode {:?}\", outbound_mode);\n                }\n                \"[outbound_allow_all]\" => {\n                    outbound_mode = Mode::BlackList;\n                    trace!(\"switch to outbound_mode {:?}\", outbound_mode);\n                }\n                \"[outbound_block_list]\" => {\n                    curr = &mut outbound_block;\n                    trace!(\"loading outbound_block_list\");\n                }\n                \"[outbound_allow_list]\" => {\n                    curr = &mut outbound_allow;\n                    trace!(\"loading outbound_allow_list\");\n                }\n                \"[black_list]\" | \"[bypass_list]\" => {\n                    curr = &mut bypass;\n                    trace!(\"loading black_list / bypass_list\");\n                }\n                \"[white_list]\" | \"[proxy_list]\" => {\n                    curr = &mut proxy;\n                    trace!(\"loading white_list / proxy_list\");\n                }\n                _ => {\n                    match line.parse::<IpNet>() {\n                        Ok(IpNet::V4(v4)) => {\n                            curr.add_ipv4_rule(v4);\n                        }\n                        Ok(IpNet::V6(v6)) => {\n                            curr.add_ipv6_rule(v6);\n                        }\n                        Err(..) => {\n                            // Maybe it is a pure IpAddr\n                            match line.parse::<IpAddr>() {\n                                Ok(IpAddr::V4(v4)) => {\n                                    curr.add_ipv4_rule(v4);\n                                }\n                                Ok(IpAddr::V6(v6)) => {\n                                    curr.add_ipv6_rule(v6);\n                                }\n                                Err(..) => {\n                                    curr.add_regex_rule(line.to_owned());\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        Ok(Self {\n            outbound_block: outbound_block.into_rules()?,\n            outbound_allow: outbound_allow.into_rules()?,\n            black_list: bypass.into_rules()?,\n            white_list: proxy.into_rules()?,\n            mode,\n            outbound_mode,\n            file_path,\n        })\n    }\n\n    /// Get ACL file path\n    pub fn file_path(&self) -> &Path {\n        &self.file_path\n    }\n\n    /// Check if domain name is in proxy_list.\n    /// If so, it should be resolved from remote (for Android's DNS relay)\n    ///\n    /// Return\n    /// - `Some(true)` if `host` is in `white_list` (should be proxied)\n    /// - `Some(false)` if `host` is in `black_list` (should be bypassed)\n    /// - `None` if `host` doesn't match any rules\n    pub fn check_host_in_proxy_list(&self, host: &str) -> Option<bool> {\n        let host = Self::convert_to_ascii(host);\n        self.check_ascii_host_in_proxy_list(&host)\n    }\n\n    /// Check if ASCII domain name is in proxy_list.\n    /// If so, it should be resolved from remote (for Android's DNS relay)\n    ///\n    /// Return\n    /// - `Some(true)` if `host` is in `white_list` (should be proxied)\n    /// - `Some(false)` if `host` is in `black_list` (should be bypassed)\n    /// - `None` if `host` doesn't match any rules\n    pub fn check_ascii_host_in_proxy_list(&self, host: &str) -> Option<bool> {\n        // Addresses in proxy_list will be proxied\n        if self.white_list.check_host_matched(host) {\n            return Some(true);\n        }\n        // Addresses in bypass_list will be bypassed\n        if self.black_list.check_host_matched(host) {\n            return Some(false);\n        }\n        None\n    }\n\n    /// If there are no IP rules\n    #[inline]\n    pub fn is_ip_empty(&self) -> bool {\n        self.black_list.is_ip_empty() && self.white_list.is_ip_empty()\n    }\n\n    /// If there are no domain name rules\n    #[inline]\n    pub fn is_host_empty(&self) -> bool {\n        self.black_list.is_host_empty() && self.white_list.is_host_empty()\n    }\n\n    /// Check if `IpAddr` should be proxied\n    pub fn check_ip_in_proxy_list(&self, ip: &IpAddr) -> bool {\n        if self.black_list.check_ip_matched(ip) {\n            // If IP is in black_list, it should be bypassed\n            return false;\n        }\n        if self.white_list.check_ip_matched(ip) {\n            // If IP is in white_list, it should be proxied\n            return true;\n        }\n        self.is_default_in_proxy_list()\n    }\n\n    /// Default mode\n    ///\n    /// Default behavior for hosts that are not configured\n    /// - `true` - Proxied\n    /// - `false` - Bypassed\n    #[inline]\n    pub fn is_default_in_proxy_list(&self) -> bool {\n        match self.mode {\n            Mode::BlackList => true,\n            Mode::WhiteList => false,\n        }\n    }\n\n    /// Returns the ASCII representation a domain name,\n    /// if conversion fails returns original string\n    fn convert_to_ascii(host: &str) -> Cow<'_, str> {\n        idna::domain_to_ascii(host)\n            .map(From::from)\n            .unwrap_or_else(|_| host.into())\n    }\n\n    /// Check if target address should be bypassed (for client)\n    ///\n    /// This function may perform a DNS resolution\n    pub async fn check_target_bypassed(&self, context: &Context, addr: &Address) -> bool {\n        match *addr {\n            Address::SocketAddress(ref addr) => !self.check_ip_in_proxy_list(&addr.ip()),\n            // Resolve hostname and check the list\n            Address::DomainNameAddress(ref host, port) => {\n                if let Some(value) = self.check_host_in_proxy_list(host) {\n                    return !value;\n                }\n\n                // If mode is BlackList, host is proxied by default. If it has any resolved IPs in black_list, then it should be bypassed.\n                // If mode is WhiteList, host is bypassed by default. If it has any resolved IPs in white_list, then it should be proxied.\n                let (check_list, bypass_if_matched) = match self.mode {\n                    Mode::BlackList => (&self.black_list, true),\n                    Mode::WhiteList => (&self.white_list, false),\n                };\n\n                if check_list.is_ip_empty() {\n                    return !self.is_default_in_proxy_list();\n                }\n\n                if let Ok(vaddr) = context.dns_resolve(host, port).await {\n                    for addr in vaddr {\n                        let ip = addr.ip();\n                        if check_list.check_ip_matched(&ip) {\n                            return bypass_if_matched;\n                        }\n                    }\n                }\n\n                !self.is_default_in_proxy_list()\n            }\n        }\n    }\n\n    /// Check if client address should be blocked (for server)\n    pub fn check_client_blocked(&self, addr: &SocketAddr) -> bool {\n        match self.mode {\n            Mode::BlackList => {\n                // Only clients in black_list will be blocked\n                self.black_list.check_ip_matched(&addr.ip())\n            }\n            Mode::WhiteList => {\n                // Only clients not in white_list will be blocked\n                !self.white_list.check_ip_matched(&addr.ip())\n            }\n        }\n    }\n\n    /// Check if outbound address is blocked (for server)\n    ///\n    /// NOTE: `Address::DomainName` is only validated by regex rules,\n    ///       resolved addresses are checked in the `lookup_outbound_then!` macro\n    pub async fn check_outbound_blocked(&self, context: &Context, outbound: &Address) -> bool {\n        match outbound {\n            Address::SocketAddress(saddr) => self.check_outbound_ip_blocked(&saddr.ip()),\n            Address::DomainNameAddress(host, port) => {\n                let ascii_host = Self::convert_to_ascii(host);\n                if self.outbound_block.check_host_matched(&ascii_host) {\n                    return true; // Blocked by config\n                }\n                if self.outbound_allow.check_host_matched(&ascii_host) {\n                    return false; // Allowed by config\n                }\n\n                // If no domain name rules matched,\n                // we need to resolve the hostname to IP addresses\n\n                // If mode is BlackList, host is allowed by default. If any of its resolved IPs is in outbound_block, then it is blocked.\n                // If mode is WhiteList, host is blocked by default. If any of its resolved IPs is in outbound_allow, then it is allowed.\n                let (check_rule, block_if_matched) = match self.outbound_mode {\n                    Mode::BlackList => (&self.outbound_block, true),\n                    Mode::WhiteList => (&self.outbound_allow, false),\n                };\n\n                if check_rule.is_ip_empty() {\n                    // If there are no IP rules, use the default mode\n                    return self.is_outbound_default_blocked();\n                }\n\n                if let Ok(vaddr) = context.dns_resolve(host, *port).await {\n                    for addr in vaddr {\n                        let ip = addr.ip();\n                        if check_rule.check_ip_matched(&ip) {\n                            return block_if_matched;\n                        }\n                    }\n                }\n\n                self.is_outbound_default_blocked()\n            }\n        }\n    }\n\n    fn check_outbound_ip_blocked(&self, ip: &IpAddr) -> bool {\n        if self.outbound_block.check_ip_matched(ip) {\n            // If IP is in outbound_block, it should be blocked\n            return true;\n        }\n        if self.outbound_allow.check_ip_matched(ip) {\n            // If IP is in outbound_allow, it should be allowed\n            return false;\n        }\n        // If IP is not in any list, check the default mode\n        self.is_outbound_default_blocked()\n    }\n\n    #[inline]\n    fn is_outbound_default_blocked(&self) -> bool {\n        match self.outbound_mode {\n            Mode::BlackList => false,\n            Mode::WhiteList => true,\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/acl/sub_domains_tree.rs",
    "content": "use std::{\n    collections::HashMap,\n    fmt::{self, Debug},\n};\n\n#[derive(Debug, Clone)]\nstruct DomainPart {\n    included: bool,\n    children: HashMap<String, DomainPart>,\n}\n\nimpl DomainPart {\n    fn new() -> Self {\n        Self {\n            included: false,\n            children: HashMap::new(),\n        }\n    }\n}\n\n#[derive(Clone)]\npub struct SubDomainsTree(HashMap<String, DomainPart>);\n\nimpl Debug for SubDomainsTree {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(f, \"SubDomainsTree {{ .. }}\")\n    }\n}\n\nimpl SubDomainsTree {\n    pub fn new() -> Self {\n        Self(HashMap::new())\n    }\n\n    pub fn insert(&mut self, value: &str) {\n        let mut current_map = &mut self.0;\n        let mut last_included = None;\n        for part in value.rsplit('.') {\n            let entry = current_map\n                .entry(part.to_ascii_lowercase())\n                .or_insert_with(DomainPart::new);\n            // We don't need to include `a.b.c` if we already have `b.c`\n            if entry.included {\n                return;\n            }\n            current_map = &mut entry.children;\n            last_included = Some(&mut entry.included);\n        }\n        if let Some(last_included) = last_included {\n            *last_included = true;\n            // Remove all subdomains to free memory. `contains` will stop here anyway.\n            current_map.clear();\n        }\n    }\n\n    pub fn contains(&self, value: &str) -> bool {\n        let mut current_map = &self.0;\n        for part in value.rsplit('.') {\n            if let Some(el) = current_map.get(part) {\n                if el.included {\n                    return true;\n                }\n                current_map = &el.children;\n            } else {\n                break;\n            }\n        }\n        false\n    }\n\n    pub fn is_empty(&self) -> bool {\n        self.0.is_empty()\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/config.rs",
    "content": "//! This is a mod for storing and parsing configuration\n//!\n//! According to shadowsocks' official documentation, the standard configuration\n//! file should be in JSON format:\n//!\n//! ```ignore\n//! {\n//!     \"server\": \"127.0.0.1\",\n//!     \"server_port\": 1080,\n//!     \"local_port\": 8388,\n//!     \"password\": \"the-password\",\n//!     \"timeout\": 300,\n//!     \"method\": \"aes-256-cfb\",\n//!     \"local_address\": \"127.0.0.1\"\n//! }\n//! ```\n//!\n//! But this configuration is not for using multiple shadowsocks server, so we\n//! introduce an extended configuration file format:\n//!\n//! ```ignore\n//! {\n//!     \"servers\": [\n//!         {\n//!             \"server\": \"127.0.0.1\",\n//!             \"server_port\": 1080,\n//!             \"password\": \"hellofuck\",\n//!             \"method\": \"bf-cfb\"\n//!         },\n//!         {\n//!             \"server\": \"127.0.0.1\",\n//!             \"server_port\": 1081,\n//!             \"password\": \"hellofuck\",\n//!             \"method\": \"aes-128-cfb\"\n//!         }\n//!     ],\n//!     \"local_port\": 8388,\n//!     \"local_address\": \"127.0.0.1\"\n//! }\n//! ```\n//!\n//! These defined server will be used with a load balancing algorithm.\n\nuse std::{\n    borrow::Cow,\n    convert::{From, Infallible},\n    default::Default,\n    env,\n    fmt::{self, Debug, Display, Formatter},\n    fs::OpenOptions,\n    io::Read,\n    net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6},\n    option::Option,\n    path::{Path, PathBuf},\n    str::FromStr,\n    string::ToString,\n    time::Duration,\n};\n\nuse cfg_if::cfg_if;\n#[cfg(feature = \"hickory-dns\")]\nuse hickory_resolver::config::{NameServerConfig, ResolverConfig};\n#[cfg(feature = \"local-tun\")]\nuse ipnet::IpNet;\n#[cfg(feature = \"local-fake-dns\")]\nuse ipnet::{Ipv4Net, Ipv6Net};\nuse log::warn;\nuse serde::{Deserialize, Serialize};\n#[cfg(any(feature = \"local-tunnel\", feature = \"local-dns\"))]\nuse shadowsocks::relay::socks5::Address;\nuse shadowsocks::{\n    config::{\n        ManagerAddr, Mode, ReplayAttackPolicy, ServerAddr, ServerConfig, ServerSource, ServerUser, ServerUserManager,\n        ServerWeight,\n    },\n    crypto::CipherKind,\n    plugin::PluginConfig,\n};\n\nuse crate::acl::AccessControl;\n#[cfg(feature = \"local-dns\")]\nuse crate::local::dns::NameServerAddr;\n#[cfg(feature = \"local-http\")]\nuse crate::local::http::config::HttpAuthConfig;\n#[cfg(feature = \"local\")]\nuse crate::local::socks::config::Socks5AuthConfig;\n\n#[derive(Serialize, Deserialize, Debug)]\n#[serde(untagged)]\nenum SSDnsConfig {\n    Simple(String),\n    #[cfg(feature = \"hickory-dns\")]\n    HickoryDns(ResolverConfig),\n}\n\n#[derive(Serialize, Deserialize, Debug, Default)]\nstruct SSSecurityConfig {\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    replay_attack: Option<SSSecurityReplayAttackConfig>,\n}\n\n#[derive(Serialize, Deserialize, Debug, Default)]\nstruct SSSecurityReplayAttackConfig {\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    policy: Option<String>,\n}\n\n#[derive(Serialize, Deserialize, Debug, Default)]\nstruct SSBalancerConfig {\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    max_server_rtt: Option<u64>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    check_interval: Option<u64>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    check_best_interval: Option<u64>,\n}\n\n#[derive(Serialize, Deserialize, Debug, Default)]\nstruct SSConfig {\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    server: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    server_port: Option<u16>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    local_address: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    local_port: Option<u16>,\n\n    /// macOS launch activate socket for local_port\n    #[cfg(target_os = \"macos\")]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    launchd_udp_socket_name: Option<String>,\n    #[cfg(target_os = \"macos\")]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    launchd_tcp_socket_name: Option<String>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    protocol: Option<String>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    manager_address: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    manager_port: Option<u16>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    password: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    method: Option<String>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    plugin: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    plugin_opts: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    plugin_args: Option<Vec<String>>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    plugin_mode: Option<String>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    timeout: Option<u64>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    udp_timeout: Option<u64>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    udp_max_associations: Option<usize>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    udp_mtu: Option<usize>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\", alias = \"shadowsocks\")]\n    servers: Option<Vec<SSServerExtConfig>>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    locals: Option<Vec<SSLocalExtConfig>>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    dns: Option<SSDnsConfig>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    dns_cache_size: Option<usize>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    mode: Option<String>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    no_delay: Option<bool>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    keep_alive: Option<u64>,\n\n    #[cfg(all(unix, not(target_os = \"android\")))]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    nofile: Option<u64>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    ipv6_first: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    ipv6_only: Option<bool>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    fast_open: Option<bool>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    mptcp: Option<bool>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n    outbound_fwmark: Option<u32>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    #[cfg(target_os = \"freebsd\")]\n    outbound_user_cookie: Option<u32>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    outbound_bind_addr: Option<String>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    outbound_bind_interface: Option<String>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    outbound_udp_allow_fragmentation: Option<bool>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    security: Option<SSSecurityConfig>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    balancer: Option<SSBalancerConfig>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    acl: Option<String>,\n\n    #[cfg(feature = \"local-online-config\")]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    version: Option<u32>,\n\n    #[cfg(feature = \"local-online-config\")]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    online_config: Option<SSOnlineConfig>,\n}\n\n#[derive(Serialize, Deserialize, Debug, Default)]\nstruct SSLocalExtConfig {\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    local_address: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    local_port: Option<u16>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    disabled: Option<bool>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    mode: Option<String>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    local_udp_address: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    local_udp_port: Option<u16>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    protocol: Option<String>,\n\n    /// macOS launch activate socket\n    #[cfg(target_os = \"macos\")]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    launchd_udp_socket_name: Option<String>,\n    #[cfg(target_os = \"macos\")]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    launchd_tcp_socket_name: Option<String>,\n\n    /// TCP Transparent Proxy type\n    #[cfg(feature = \"local-redir\")]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    tcp_redir: Option<String>,\n    /// UDP Transparent Proxy type\n    #[cfg(feature = \"local-redir\")]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    udp_redir: Option<String>,\n\n    /// Local DNS's address\n    ///\n    /// Sending DNS query directly to this address\n    #[cfg(feature = \"local-dns\")]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    local_dns_address: Option<String>,\n    #[cfg(feature = \"local-dns\")]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    local_dns_port: Option<u16>,\n    /// Remote DNS's address\n    ///\n    /// Sending DNS query through proxy to this address\n    #[cfg(feature = \"local-dns\")]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    remote_dns_address: Option<String>,\n    #[cfg(feature = \"local-dns\")]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    remote_dns_port: Option<u16>,\n    #[cfg(feature = \"local-dns\")]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    client_cache_size: Option<usize>,\n\n    /// Tunnel\n    #[cfg(feature = \"local-tunnel\")]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    forward_address: Option<String>,\n    #[cfg(feature = \"local-tunnel\")]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    forward_port: Option<u16>,\n\n    /// Tun\n    #[cfg(feature = \"local-tun\")]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    tun_interface_name: Option<String>,\n    #[cfg(feature = \"local-tun\")]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    tun_interface_address: Option<String>,\n    #[cfg(feature = \"local-tun\")]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    tun_interface_destination: Option<String>,\n    #[cfg(all(feature = \"local-tun\", unix))]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    tun_device_fd_from_path: Option<String>,\n\n    /// SOCKS5\n    #[cfg(feature = \"local\")]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    socks5_auth_config_path: Option<String>,\n\n    /// HTTP\n    #[cfg(feature = \"local-http\")]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    http_auth_config_path: Option<String>,\n\n    /// Fake DNS\n    #[cfg(feature = \"local-fake-dns\")]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub fake_dns_record_expire_duration: Option<u64>,\n    #[cfg(feature = \"local-fake-dns\")]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub fake_dns_ipv4_network: Option<String>,\n    #[cfg(feature = \"local-fake-dns\")]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub fake_dns_ipv6_network: Option<String>,\n    #[cfg(feature = \"local-fake-dns\")]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub fake_dns_database_path: Option<String>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    acl: Option<String>,\n}\n\n#[derive(Serialize, Deserialize, Debug)]\nstruct SSServerUserConfig {\n    name: String,\n    password: String,\n}\n\n#[derive(Serialize, Deserialize, Debug)]\nstruct SSServerExtConfig {\n    // SIP008 https://github.com/shadowsocks/shadowsocks-org/issues/89\n    //\n    // `address` and `port` are non-standard field name only for shadowsocks-rust\n    #[serde(alias = \"address\")]\n    server: String,\n    #[serde(alias = \"port\")]\n    server_port: u16,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    password: Option<String>,\n    method: String,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    users: Option<Vec<SSServerUserConfig>>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    disabled: Option<bool>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    plugin: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    plugin_opts: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    plugin_args: Option<Vec<String>>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    plugin_mode: Option<String>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    timeout: Option<u64>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\", alias = \"name\")]\n    remarks: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    id: Option<String>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    mode: Option<String>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    tcp_weight: Option<f32>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    udp_weight: Option<f32>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    acl: Option<String>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n    outbound_fwmark: Option<u32>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    #[cfg(target_os = \"freebsd\")]\n    outbound_user_cookie: Option<u32>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    outbound_bind_addr: Option<IpAddr>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    outbound_bind_interface: Option<String>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    outbound_udp_allow_fragmentation: Option<bool>,\n}\n\n#[cfg(feature = \"local-online-config\")]\n#[derive(Serialize, Deserialize, Debug, Default)]\nstruct SSOnlineConfig {\n    config_url: String,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    update_interval: Option<u64>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    allowed_plugins: Option<Vec<String>>,\n}\n\n/// Server config type\n#[derive(Clone, Copy, Debug, Eq, PartialEq)]\npub enum ConfigType {\n    /// Config for local\n    Local,\n\n    /// Config for server\n    Server,\n\n    /// Config for Manager server\n    Manager,\n\n    /// Config for online config (SIP008)\n    /// https://shadowsocks.org/doc/sip008.html\n    #[cfg(feature = \"local-online-config\")]\n    OnlineConfig,\n}\n\nimpl ConfigType {\n    /// Check if it is local server type\n    pub fn is_local(self) -> bool {\n        self == Self::Local\n    }\n\n    /// Check if it is remote server type\n    pub fn is_server(self) -> bool {\n        self == Self::Server\n    }\n\n    /// Check if it is manager server type\n    pub fn is_manager(self) -> bool {\n        self == Self::Manager\n    }\n\n    /// Check if it is online config type (SIP008)\n    #[cfg(feature = \"local-online-config\")]\n    pub fn is_online_config(self) -> bool {\n        self == Self::OnlineConfig\n    }\n}\n\ncfg_if! {\n    if #[cfg(feature = \"local-redir\")] {\n        /// Transparent Proxy type\n        #[derive(Clone, Copy, Debug, Eq, PartialEq)]\n        pub enum RedirType {\n            /// For not supported platforms\n            NotSupported,\n\n            /// For Linux-like systems' Netfilter `REDIRECT`. Only for TCP connections.\n            ///\n            /// This is supported from Linux 2.4 Kernel. Document: <https://www.netfilter.org/documentation/index.html#documentation-howto>\n            ///\n            /// NOTE: Filter rule `REDIRECT` can only be applied to TCP connections.\n            #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n            Redirect,\n\n            /// For Linux-like systems' Netfilter TPROXY rule.\n            ///\n            /// NOTE: Filter rule `TPROXY` can be applied to TCP and UDP connections.\n            #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n            TProxy,\n\n            /// Packet Filter (pf)\n            ///\n            /// Supported by OpenBSD 3.0+, FreeBSD 5.3+, NetBSD 3.0+, Solaris 11.3+, macOS 10.7+, iOS, QNX\n            ///\n            /// Document: <https://www.freebsd.org/doc/handbook/firewalls-pf.html>\n            #[cfg(any(\n                target_os = \"freebsd\",\n                target_os = \"openbsd\",\n                target_os = \"macos\",\n                target_os = \"ios\"\n            ))]\n            PacketFilter,\n\n            /// IPFW\n            ///\n            /// Supported by FreeBSD, macOS 10.6- (Have been removed completely on macOS 10.10)\n            ///\n            /// Document: https://www.freebsd.org/doc/handbook/firewalls-ipfw.html\n            #[cfg(any(target_os = \"freebsd\", target_os = \"macos\", target_os = \"ios\"))]\n            IpFirewall,\n        }\n\n        impl RedirType {\n            cfg_if! {\n                if #[cfg(any(target_os = \"linux\", target_os = \"android\"))] {\n                    /// Default TCP transparent proxy solution on this platform\n                    pub const fn tcp_default() -> Self {\n                        Self::Redirect\n                    }\n\n                    /// Available TCP transparent proxy types\n                    #[doc(hidden)]\n                    pub fn tcp_available_types() -> &'static [&'static str] {\n                        const AVAILABLE_TYPES: &[&str] = &[RedirType::Redirect.name(), RedirType::TProxy.name()];\n                        AVAILABLE_TYPES\n                    }\n\n                    /// Default UDP transparent proxy solution on this platform\n                    pub const fn udp_default() -> Self {\n                        Self::TProxy\n                    }\n\n                    /// Available UDP transparent proxy types\n                    #[doc(hidden)]\n                    pub fn udp_available_types() -> &'static [&'static str] {\n                        const AVAILABLE_TYPES: &[&str] = &[RedirType::TProxy.name()];\n                        AVAILABLE_TYPES\n                    }\n                } else if #[cfg(any(target_os = \"freebsd\"))] {\n                    /// Default TCP transparent proxy solution on this platform\n                    pub fn tcp_default() -> RedirType {\n                        RedirType::PacketFilter\n                    }\n\n                    /// Available TCP transparent proxy types\n                    #[doc(hidden)]\n                    pub fn tcp_available_types() -> &'static [&'static str] {\n                        const AVAILABLE_TYPES: &[&str] = &[RedirType::PacketFilter.name(), RedirType::IpFirewall.name()];\n                        AVAILABLE_TYPES\n                    }\n\n                    /// Default UDP transparent proxy solution on this platform\n                    pub fn udp_default() -> RedirType {\n                        RedirType::PacketFilter\n                    }\n\n                    /// Available UDP transparent proxy types\n                    #[doc(hidden)]\n                    pub const fn udp_available_types() -> &'static [&'static str] {\n                        const AVAILABLE_TYPES: &[&str] = &[RedirType::PacketFilter.name(), RedirType::IpFirewall.name()];\n                        AVAILABLE_TYPES\n                    }\n                } else if #[cfg(target_os = \"openbsd\")] {\n                    /// Default TCP transparent proxy solution on this platform\n                    pub fn tcp_default() -> RedirType {\n                        RedirType::PacketFilter\n                    }\n\n                    /// Available TCP transparent proxy types\n                    #[doc(hidden)]\n                    pub fn tcp_available_types() -> &'static [&'static str] {\n                        const AVAILABLE_TYPES: &[&str] = &[RedirType::PacketFilter.name()];\n                        AVAILABLE_TYPES\n                    }\n\n                    /// Default UDP transparent proxy solution on this platform\n                    pub fn udp_default() -> RedirType {\n                        RedirType::PacketFilter\n                    }\n\n                    /// Available UDP transparent proxy types\n                    #[doc(hidden)]\n                    pub const fn udp_available_types() -> &'static [&'static str] {\n                        const AVAILABLE_TYPES: &[&str] = &[RedirType::PacketFilter.name()];\n                        AVAILABLE_TYPES\n                    }\n                } else if #[cfg(any(target_os = \"macos\", target_os = \"ios\"))] {\n                    /// Default TCP transparent proxy solution on this platform\n                    pub fn tcp_default() -> RedirType {\n                        RedirType::PacketFilter\n                    }\n\n                    /// Available TCP transparent proxy types\n                    #[doc(hidden)]\n                    pub const fn tcp_available_types() -> &'static [&'static str] {\n                        const AVAILABLE_TYPES: &[&str] = &[RedirType::PacketFilter.name(), RedirType::IpFirewall.name()];\n                        AVAILABLE_TYPES\n                    }\n\n                    /// Default UDP transparent proxy solution on this platform\n                    pub fn udp_default() -> RedirType {\n                        RedirType::PacketFilter\n                    }\n\n                    /// Available UDP transparent proxy types\n                    #[doc(hidden)]\n                    pub const fn udp_available_types() -> &'static [&'static str] {\n                        const AVAILABLE_TYPES: &[&str] = &[RedirType::PacketFilter.name()];\n                        AVAILABLE_TYPES\n                    }\n                } else {\n                    /// Default TCP transparent proxy solution on this platform\n                    pub fn tcp_default() -> RedirType {\n                        RedirType::NotSupported\n                    }\n\n                    /// Available TCP transparent proxy types\n                    #[doc(hidden)]\n                    pub const fn tcp_available_types() -> &'static [&'static str] {\n                        const AVAILABLE_TYPES: &[&str] = &[];\n                        AVAILABLE_TYPES\n                    }\n\n                    /// Default UDP transparent proxy solution on this platform\n                    pub fn udp_default() -> RedirType {\n                        RedirType::NotSupported\n                    }\n\n                    /// Available UDP transparent proxy types\n                    #[doc(hidden)]\n                    pub const fn udp_available_types() -> &'static [&'static str] {\n                        const AVAILABLE_TYPES: &[&str] = &[];\n                        AVAILABLE_TYPES\n                    }\n                }\n            }\n\n            /// Check if transparent proxy is supported on this platform\n            pub fn is_supported(self) -> bool {\n                self != Self::NotSupported\n            }\n\n            /// Name of redirect type (transparent proxy type)\n            pub const fn name(self) -> &'static str {\n                match self {\n                    // Dummy, shouldn't be used in any useful situations\n                    Self::NotSupported => \"not_supported\",\n\n                    #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n                    Self::Redirect => \"redirect\",\n\n                    #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n                    Self::TProxy => \"tproxy\",\n\n                    #[cfg(any(\n                        target_os = \"freebsd\",\n                        target_os = \"openbsd\",\n                        target_os = \"macos\",\n                        target_os = \"ios\"\n                    ))]\n                    RedirType::PacketFilter => \"pf\",\n\n                    #[cfg(any(target_os = \"freebsd\", target_os = \"macos\", target_os = \"ios\"))]\n                    RedirType::IpFirewall => \"ipfw\",\n                }\n            }\n        }\n\n        impl Display for RedirType {\n            fn fmt(&self, f: &mut Formatter) -> fmt::Result {\n                f.write_str(self.name())\n            }\n        }\n\n        /// Error type for `RedirType`'s `FromStr::Err`\n        #[derive(Debug)]\n        pub struct InvalidRedirType;\n\n        impl Display for InvalidRedirType {\n            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n                f.write_str(\"invalid RedirType\")\n            }\n        }\n\n        impl FromStr for RedirType {\n            type Err = InvalidRedirType;\n\n            fn from_str(s: &str) -> Result<Self, InvalidRedirType> {\n                match s {\n                    #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n                    \"redirect\" => Ok(Self::Redirect),\n\n                    #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n                    \"tproxy\" => Ok(Self::TProxy),\n\n                    #[cfg(any(\n                        target_os = \"freebsd\",\n                        target_os = \"openbsd\",\n                        target_os = \"macos\",\n                        target_os = \"ios\",\n                    ))]\n                    \"pf\" => Ok(RedirType::PacketFilter),\n\n                    #[cfg(any(\n                        target_os = \"freebsd\",\n                        target_os = \"macos\",\n                        target_os = \"ios\",\n                    ))]\n                    \"ipfw\" => Ok(RedirType::IpFirewall),\n\n                    _ => Err(InvalidRedirType),\n                }\n            }\n        }\n    }\n}\n\n/// Host for servers to bind\n///\n/// Servers will bind to a port of this host\n#[derive(Clone, Debug)]\npub enum ManagerServerHost {\n    /// Domain name\n    Domain(String),\n    /// IP address\n    Ip(IpAddr),\n}\n\nimpl Default for ManagerServerHost {\n    fn default() -> Self {\n        Self::Ip(Ipv4Addr::UNSPECIFIED.into())\n    }\n}\n\nimpl FromStr for ManagerServerHost {\n    type Err = Infallible;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        match s.parse::<IpAddr>() {\n            Ok(s) => Ok(Self::Ip(s)),\n            Err(..) => Ok(Self::Domain(s.to_owned())),\n        }\n    }\n}\n\n/// Mode of Manager's server\n#[derive(Debug, Clone, Copy, Eq, PartialEq, Default)]\npub enum ManagerServerMode {\n    /// Run shadowsocks server in the same process of manager\n    #[default]\n    Builtin,\n\n    /// Run shadowsocks server in standalone (process) mode\n    #[cfg(unix)]\n    Standalone,\n}\n\n/// Parsing ManagerServerMode error\n#[derive(Debug, Clone, Copy)]\npub struct ManagerServerModeError;\n\nimpl Display for ManagerServerModeError {\n    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {\n        f.write_str(\"invalid ManagerServerMode\")\n    }\n}\n\nimpl FromStr for ManagerServerMode {\n    type Err = ManagerServerModeError;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        match s {\n            \"builtin\" => Ok(Self::Builtin),\n            #[cfg(unix)]\n            \"standalone\" => Ok(Self::Standalone),\n            _ => Err(ManagerServerModeError),\n        }\n    }\n}\n\nimpl Display for ManagerServerMode {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        match *self {\n            Self::Builtin => f.write_str(\"builtin\"),\n            #[cfg(unix)]\n            Self::Standalone => f.write_str(\"standalone\"),\n        }\n    }\n}\n\n/// Configuration for Manager\n#[derive(Clone, Debug)]\npub struct ManagerConfig {\n    /// Address of `ss-manager`. Send servers' statistic data to the manager server\n    pub addr: ManagerAddr,\n    /// Manager's default method\n    pub method: Option<CipherKind>,\n    /// Manager's default plugin\n    pub plugin: Option<PluginConfig>,\n    /// Timeout for TCP connections, setting to manager's created servers\n    pub timeout: Option<Duration>,\n    /// IP/Host for servers to bind (inbound)\n    ///\n    /// Note: Outbound address is defined in Config.local_addr\n    pub server_host: ManagerServerHost,\n    /// Server's mode\n    pub mode: Mode,\n    /// Server's running mode\n    pub server_mode: ManagerServerMode,\n    /// Server's command if running in Standalone mode\n    #[cfg(unix)]\n    pub server_program: String,\n    /// Server's working directory if running in Standalone mode\n    #[cfg(unix)]\n    pub server_working_directory: PathBuf,\n}\n\nimpl ManagerConfig {\n    /// Create a ManagerConfig with default options\n    pub fn new(addr: ManagerAddr) -> Self {\n        Self {\n            addr,\n            method: None,\n            plugin: None,\n            timeout: None,\n            server_host: ManagerServerHost::default(),\n            mode: Mode::TcpOnly,\n            server_mode: ManagerServerMode::Builtin,\n            #[cfg(unix)]\n            server_program: \"ssserver\".to_owned(),\n            #[cfg(unix)]\n            server_working_directory: match std::env::current_dir() {\n                Ok(d) => d,\n                Err(..) => \"/tmp/shadowsocks-manager\".into(),\n            },\n        }\n    }\n}\n\n/// Protocol of local server\n#[derive(Debug, Default, Clone, Copy, Eq, PartialEq)]\npub enum ProtocolType {\n    #[default]\n    Socks,\n    #[cfg(feature = \"local-http\")]\n    Http,\n    #[cfg(feature = \"local-tunnel\")]\n    Tunnel,\n    #[cfg(feature = \"local-redir\")]\n    Redir,\n    #[cfg(feature = \"local-dns\")]\n    Dns,\n    #[cfg(feature = \"local-tun\")]\n    Tun,\n    #[cfg(feature = \"local-fake-dns\")]\n    FakeDns,\n}\n\nimpl ProtocolType {\n    /// As string representation\n    pub fn as_str(&self) -> &'static str {\n        match *self {\n            Self::Socks => \"socks\",\n            #[cfg(feature = \"local-http\")]\n            Self::Http => \"http\",\n            #[cfg(feature = \"local-tunnel\")]\n            Self::Tunnel => \"tunnel\",\n            #[cfg(feature = \"local-redir\")]\n            Self::Redir => \"redir\",\n            #[cfg(feature = \"local-dns\")]\n            Self::Dns => \"dns\",\n            #[cfg(feature = \"local-tun\")]\n            Self::Tun => \"tun\",\n            #[cfg(feature = \"local-fake-dns\")]\n            Self::FakeDns => \"fake-dns\",\n        }\n    }\n\n    /// Get all available protocols\n    pub fn available_protocols() -> &'static [&'static str] {\n        &[\n            \"socks\",\n            #[cfg(feature = \"local-http\")]\n            \"http\",\n            #[cfg(feature = \"local-tunnel\")]\n            \"tunnel\",\n            #[cfg(feature = \"local-redir\")]\n            \"redir\",\n            #[cfg(feature = \"local-dns\")]\n            \"dns\",\n            #[cfg(feature = \"local-tun\")]\n            \"tun\",\n            #[cfg(feature = \"local-fake-dns\")]\n            \"fake-dns\",\n        ]\n    }\n}\n\n/// Error while parsing `ProtocolType` from string\n#[derive(Debug)]\npub struct ProtocolTypeError;\n\nimpl Display for ProtocolTypeError {\n    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {\n        f.write_str(\"invalid ProtocolType\")\n    }\n}\n\nimpl FromStr for ProtocolType {\n    type Err = ProtocolTypeError;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        match s {\n            \"socks\" => Ok(Self::Socks),\n            #[cfg(feature = \"local-http\")]\n            \"http\" => Ok(Self::Http),\n            #[cfg(feature = \"local-tunnel\")]\n            \"tunnel\" => Ok(Self::Tunnel),\n            #[cfg(feature = \"local-redir\")]\n            \"redir\" => Ok(Self::Redir),\n            #[cfg(feature = \"local-dns\")]\n            \"dns\" => Ok(Self::Dns),\n            #[cfg(feature = \"local-tun\")]\n            \"tun\" => Ok(Self::Tun),\n            #[cfg(feature = \"local-fake-dns\")]\n            \"fake-dns\" => Ok(Self::FakeDns),\n            _ => Err(ProtocolTypeError),\n        }\n    }\n}\n\n/// Local server configuration\n#[derive(Clone, Debug)]\npub struct LocalConfig {\n    /// Listen address for local servers\n    pub addr: Option<ServerAddr>,\n\n    /// Local Protocol\n    pub protocol: ProtocolType,\n\n    /// Mode\n    /// Uses global `mode` if not specified\n    pub mode: Mode,\n\n    /// UDP server bind address. Uses `addr` if not specified\n    ///\n    /// Resolving Android's issue: [shadowsocks/shadowsocks-android#2571](https://github.com/shadowsocks/shadowsocks-android/issues/2571)\n    pub udp_addr: Option<ServerAddr>,\n\n    /// UDP Associate address. Uses `udp_addr` if not specified\n    pub udp_associate_addr: Option<ServerAddr>,\n\n    /// Destination address for tunnel\n    #[cfg(feature = \"local-tunnel\")]\n    pub forward_addr: Option<Address>,\n\n    /// TCP Transparent Proxy type\n    #[cfg(feature = \"local-redir\")]\n    pub tcp_redir: RedirType,\n    /// UDP Transparent Proxy type\n    #[cfg(feature = \"local-redir\")]\n    pub udp_redir: RedirType,\n\n    /// Local DNS's address\n    ///\n    /// Sending DNS query directly to this address\n    #[cfg(feature = \"local-dns\")]\n    pub local_dns_addr: Option<NameServerAddr>,\n    /// Remote DNS's address\n    ///\n    /// Sending DNS query through proxy to this address\n    #[cfg(feature = \"local-dns\")]\n    pub remote_dns_addr: Option<Address>,\n    // client cache size\n    // if a lot of `create connection` observed in log,\n    // increase the size\n    #[cfg(feature = \"local-dns\")]\n    pub client_cache_size: Option<usize>,\n\n    /// Tun interface's name\n    ///\n    /// Linux: eth0, eth1, ...\n    /// macOS: utun0, utun1, ...\n    #[cfg(feature = \"local-tun\")]\n    pub tun_interface_name: Option<String>,\n    /// Tun interface's address and netmask\n    #[cfg(feature = \"local-tun\")]\n    pub tun_interface_address: Option<IpNet>,\n    /// Tun interface's destination address and netmask\n    #[cfg(feature = \"local-tun\")]\n    pub tun_interface_destination: Option<IpNet>,\n    /// Tun interface's file descriptor\n    #[cfg(all(feature = \"local-tun\", unix))]\n    pub tun_device_fd: Option<std::os::unix::io::RawFd>,\n    /// Tun interface's file descriptor read from this Unix Domain Socket\n    #[cfg(all(feature = \"local-tun\", unix))]\n    pub tun_device_fd_from_path: Option<PathBuf>,\n\n    /// macOS launchd socket for TCP listener\n    ///\n    /// <https://developer.apple.com/documentation/xpc/1505523-launch_activate_socket>\n    /// <https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html>\n    ///\n    /// ```plist\n    /// <key>Sockets</key>\n    /// <dict>\n    ///     <key>{launchd_tcp_socket_name}</key>\n    ///     <dict>\n    ///         <key>SockType</key>\n    ///         <string>stream</string>\n    ///         ... other keys ...\n    ///     </dict>\n    /// </dict>\n    /// ```\n    #[cfg(target_os = \"macos\")]\n    pub launchd_tcp_socket_name: Option<String>,\n    /// macOS launchd socket for UDP listener\n    ///\n    /// <https://developer.apple.com/documentation/xpc/1505523-launch_activate_socket>\n    /// <https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html>\n    ///\n    /// ```plist\n    /// <key>Sockets</key>\n    /// <dict>\n    ///     <key>{launchd_udp_socket_name}</key>\n    ///     <dict>\n    ///         <key>SockType</key>\n    ///         <string>dgram</string>\n    ///         ... other keys ...\n    ///     </dict>\n    /// </dict>\n    /// ```\n    #[cfg(target_os = \"macos\")]\n    pub launchd_udp_socket_name: Option<String>,\n\n    /// Set `IPV6_V6ONLY` for listener socket\n    pub ipv6_only: bool,\n\n    /// SOCKS5 Authentication configuration\n    #[cfg(feature = \"local\")]\n    pub socks5_auth: Socks5AuthConfig,\n\n    /// HTTP Authentication configuration\n    #[cfg(feature = \"local-http\")]\n    pub http_auth: HttpAuthConfig,\n\n    /// Fake DNS record expire seconds\n    #[cfg(feature = \"local-fake-dns\")]\n    pub fake_dns_record_expire_duration: Option<Duration>,\n    /// Fake DNS IPv4 allocation space\n    #[cfg(feature = \"local-fake-dns\")]\n    pub fake_dns_ipv4_network: Option<Ipv4Net>,\n    /// Fake DNS IPv6 allocation space\n    #[cfg(feature = \"local-fake-dns\")]\n    pub fake_dns_ipv6_network: Option<Ipv6Net>,\n    /// Fake DNS storage database path\n    #[cfg(feature = \"local-fake-dns\")]\n    pub fake_dns_database_path: Option<PathBuf>,\n}\n\nimpl LocalConfig {\n    /// Create a new `LocalConfig`\n    pub fn new(protocol: ProtocolType) -> Self {\n        // DNS server runs in `TcpAndUdp` mode by default to maintain backwards compatibility\n        // see https://github.com/shadowsocks/shadowsocks-rust/issues/1281\n        let mode = match protocol {\n            #[cfg(feature = \"local-dns\")]\n            ProtocolType::Dns => Mode::TcpAndUdp,\n            _ => Mode::TcpOnly,\n        };\n\n        Self {\n            addr: None,\n\n            protocol,\n\n            mode,\n            udp_addr: None,\n            udp_associate_addr: None,\n\n            #[cfg(feature = \"local-tunnel\")]\n            forward_addr: None,\n\n            #[cfg(feature = \"local-redir\")]\n            tcp_redir: RedirType::tcp_default(),\n            #[cfg(feature = \"local-redir\")]\n            udp_redir: RedirType::udp_default(),\n\n            #[cfg(feature = \"local-dns\")]\n            local_dns_addr: None,\n            #[cfg(feature = \"local-dns\")]\n            remote_dns_addr: None,\n            #[cfg(feature = \"local-dns\")]\n            client_cache_size: None,\n\n            #[cfg(feature = \"local-tun\")]\n            tun_interface_name: None,\n            #[cfg(feature = \"local-tun\")]\n            tun_interface_address: None,\n            #[cfg(feature = \"local-tun\")]\n            tun_interface_destination: None,\n            #[cfg(all(feature = \"local-tun\", unix))]\n            tun_device_fd: None,\n            #[cfg(all(feature = \"local-tun\", unix))]\n            tun_device_fd_from_path: None,\n\n            #[cfg(target_os = \"macos\")]\n            launchd_tcp_socket_name: None,\n            #[cfg(target_os = \"macos\")]\n            launchd_udp_socket_name: None,\n\n            ipv6_only: false,\n\n            #[cfg(feature = \"local\")]\n            socks5_auth: Socks5AuthConfig::default(),\n\n            #[cfg(feature = \"local-http\")]\n            http_auth: HttpAuthConfig::default(),\n\n            #[cfg(feature = \"local-fake-dns\")]\n            fake_dns_record_expire_duration: None,\n            #[cfg(feature = \"local-fake-dns\")]\n            fake_dns_ipv4_network: None,\n            #[cfg(feature = \"local-fake-dns\")]\n            fake_dns_ipv6_network: None,\n            #[cfg(feature = \"local-fake-dns\")]\n            fake_dns_database_path: None,\n        }\n    }\n\n    /// Create a new `LocalConfig` with listen address\n    pub fn new_with_addr(addr: ServerAddr, protocol: ProtocolType) -> Self {\n        let mut config = Self::new(protocol);\n        config.addr = Some(addr);\n        config\n    }\n\n    fn check_integrity(&self) -> Result<(), Error> {\n        match self.protocol {\n            #[cfg(feature = \"local-tun\")]\n            ProtocolType::Tun => {}\n\n            _ => {\n                if self.addr.is_none() {\n                    let err = Error::new(ErrorKind::MissingField, \"missing `addr` in configuration\", None);\n                    return Err(err);\n                }\n            }\n        }\n\n        match self.protocol {\n            #[cfg(feature = \"local-dns\")]\n            ProtocolType::Dns => {\n                if self.local_dns_addr.is_none() || self.remote_dns_addr.is_none() {\n                    let err = Error::new(\n                        ErrorKind::MissingField,\n                        \"missing `local_dns_addr` or `remote_dns_addr` in configuration\",\n                        None,\n                    );\n                    return Err(err);\n                }\n            }\n            #[cfg(feature = \"local-tunnel\")]\n            ProtocolType::Tunnel => {\n                if self.forward_addr.is_none() {\n                    let err = Error::new(ErrorKind::MissingField, \"missing `forward_addr` in configuration\", None);\n                    return Err(err);\n                }\n            }\n\n            #[cfg(feature = \"local-http\")]\n            ProtocolType::Http => {\n                if !self.mode.enable_tcp() {\n                    let err = Error::new(ErrorKind::Invalid, \"TCP mode have to be enabled for http\", None);\n                    return Err(err);\n                }\n            }\n\n            _ => {}\n        }\n\n        Ok(())\n    }\n\n    // Check if it is a basic format of local\n    pub fn is_basic(&self) -> bool {\n        if self.protocol != ProtocolType::Socks || self.udp_addr.is_some() {\n            return false;\n        }\n\n        #[cfg(feature = \"local-tunnel\")]\n        if self.forward_addr.is_some() {\n            return false;\n        }\n\n        #[cfg(feature = \"local-redir\")]\n        if self.tcp_redir != RedirType::tcp_default() || self.udp_redir != RedirType::udp_default() {\n            return false;\n        }\n\n        #[cfg(feature = \"local-dns\")]\n        if self.local_dns_addr.is_some() || self.remote_dns_addr.is_some() {\n            return false;\n        }\n\n        true\n    }\n}\n\n#[derive(Clone, Debug, Default)]\npub enum DnsConfig {\n    #[default]\n    System,\n    #[cfg(feature = \"hickory-dns\")]\n    HickoryDns(ResolverConfig),\n    #[cfg(feature = \"local-dns\")]\n    LocalDns(NameServerAddr),\n}\n\n/// Security Config\n#[derive(Clone, Debug, Default)]\npub struct SecurityConfig {\n    pub replay_attack: SecurityReplayAttackConfig,\n}\n\n#[derive(Clone, Debug, Default)]\npub struct SecurityReplayAttackConfig {\n    pub policy: ReplayAttackPolicy,\n}\n\n/// Balancer Config\n#[derive(Clone, Debug, Default)]\npub struct BalancerConfig {\n    /// MAX rtt of servers, which is the timeout duration of each check requests\n    pub max_server_rtt: Option<Duration>,\n    /// Interval between each checking\n    pub check_interval: Option<Duration>,\n    /// Interval for checking the best server\n    pub check_best_interval: Option<Duration>,\n}\n\n/// Address for local to report flow statistic data\n#[cfg(feature = \"local-flow-stat\")]\n#[derive(Debug, Clone)]\npub enum LocalFlowStatAddress {\n    /// UNIX Domain Socket address\n    #[cfg(unix)]\n    UnixStreamPath(PathBuf),\n    /// TCP Stream Address\n    TcpStreamAddr(SocketAddr),\n}\n\n/// Server instance config\n#[derive(Debug, Clone)]\npub struct ServerInstanceConfig {\n    /// Server's config\n    pub config: ServerConfig,\n    /// Server's private ACL, set to `None` will use the global `AccessControl`\n    pub acl: Option<AccessControl>,\n    /// Server's outbound fwmark / address / interface to support split tunnel\n    #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n    pub outbound_fwmark: Option<u32>,\n    #[cfg(target_os = \"freebsd\")]\n    pub outbound_user_cookie: Option<u32>,\n    pub outbound_bind_addr: Option<IpAddr>,\n    pub outbound_bind_interface: Option<String>,\n    pub outbound_udp_allow_fragmentation: Option<bool>,\n}\n\nimpl ServerInstanceConfig {\n    /// Create with `ServerConfig`\n    pub fn with_server_config(config: ServerConfig) -> Self {\n        Self {\n            config,\n            acl: None,\n            #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n            outbound_fwmark: None,\n            #[cfg(target_os = \"freebsd\")]\n            outbound_user_cookie: None,\n            outbound_bind_addr: None,\n            outbound_bind_interface: None,\n            outbound_udp_allow_fragmentation: None,\n        }\n    }\n}\n\n/// Local instance config\n#[derive(Debug, Clone)]\npub struct LocalInstanceConfig {\n    /// Local server's config\n    pub config: LocalConfig,\n    /// Server's private ACL, set to `None` will use the global `AccessControl`\n    pub acl: Option<AccessControl>,\n}\n\nimpl LocalInstanceConfig {\n    /// Create with `LocalConfig`\n    pub fn with_local_config(config: LocalConfig) -> Self {\n        Self { config, acl: None }\n    }\n}\n\n/// OnlineConfiguration (SIP008)\n/// https://shadowsocks.org/doc/sip008.html\n#[cfg(feature = \"local-online-config\")]\n#[derive(Debug, Clone)]\npub struct OnlineConfig {\n    /// SIP008 URL\n    pub config_url: String,\n    /// Update interval, 3600s by default\n    pub update_interval: Option<Duration>,\n    /// Allowed plugins\n    pub allowed_plugins: Option<Vec<String>>,\n}\n\n/// Configuration\n#[derive(Clone, Debug)]\npub struct Config {\n    /// Remote ShadowSocks server configurations\n    pub server: Vec<ServerInstanceConfig>,\n    /// Local server configuration\n    pub local: Vec<LocalInstanceConfig>,\n\n    /// DNS configuration, uses system-wide DNS configuration by default\n    ///\n    /// Value could be a `IpAddr`, uses UDP DNS protocol with port `53`. For example: `8.8.8.8`\n    ///\n    /// Also Value could be some pre-defined DNS server names:\n    ///\n    /// - `google`\n    /// - `cloudflare`, `cloudflare_tls`, `cloudflare_https`\n    /// - `quad9`, `quad9_tls`\n    pub dns: DnsConfig,\n    pub dns_cache_size: Option<usize>,\n    /// Uses IPv6 addresses first\n    ///\n    /// Set to `true` if you want to query IPv6 addresses before IPv4\n    pub ipv6_first: bool,\n    /// Set `IPV6_V6ONLY` for listener sockets\n    pub ipv6_only: bool,\n\n    /// Set `TCP_NODELAY` socket option\n    pub no_delay: bool,\n    /// Set `TCP_FASTOPEN` socket option\n    pub fast_open: bool,\n    /// Set TCP Keep-Alive duration, will set both `TCP_KEEPIDLE` and `TCP_KEEPINTVL`\n    ///\n    /// <https://github.com/shadowsocks/shadowsocks-rust/issues/546>\n    ///\n    /// If this is not set, sockets will be set with a default timeout\n    pub keep_alive: Option<Duration>,\n    /// Multipath-TCP\n    pub mptcp: bool,\n\n    /// `RLIMIT_NOFILE` option for *nix systems\n    #[cfg(all(unix, not(target_os = \"android\")))]\n    pub nofile: Option<u64>,\n\n    /// Set `SO_MARK` socket option for outbound sockets\n    #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n    pub outbound_fwmark: Option<u32>,\n    /// Set `SO_USER_COOKIE` socket option for outbound sockets\n    #[cfg(target_os = \"freebsd\")]\n    pub outbound_user_cookie: Option<u32>,\n    /// Set `SO_BINDTODEVICE` (Linux), `IP_BOUND_IF` (BSD), `IP_UNICAST_IF` (Windows) socket option for outbound sockets\n    pub outbound_bind_interface: Option<String>,\n    /// Outbound sockets will `bind` to this address\n    pub outbound_bind_addr: Option<IpAddr>,\n    /// Outbound UDP sockets allow IP fragmentation\n    pub outbound_udp_allow_fragmentation: bool,\n    /// Path to protect callback unix address, only for Android\n    #[cfg(target_os = \"android\")]\n    pub outbound_vpn_protect_path: Option<PathBuf>,\n\n    /// Set `SO_SNDBUF` for inbound sockets\n    pub inbound_send_buffer_size: Option<u32>,\n    /// Set `SO_RCVBUF` for inbound sockets\n    pub inbound_recv_buffer_size: Option<u32>,\n    /// Set `SO_SNDBUF` for outbound sockets\n    pub outbound_send_buffer_size: Option<u32>,\n    /// Set `SO_RCVBUF` for outbound sockets\n    pub outbound_recv_buffer_size: Option<u32>,\n\n    /// Manager's configuration\n    pub manager: Option<ManagerConfig>,\n\n    /// Config is for Client or Server\n    pub config_type: ConfigType,\n\n    /// Timeout for UDP Associations, default is 5 minutes\n    pub udp_timeout: Option<Duration>,\n    /// Maximum number of UDP Associations, default is unconfigured\n    pub udp_max_associations: Option<usize>,\n    /// Maximum Transmission Unit (MTU) size for UDP packets\n    /// 65535 by default. Suggestion: 1500\n    /// NOTE: mtu includes IP header, UDP header, UDP payload\n    pub udp_mtu: Option<usize>,\n\n    /// ACL configuration (Global)\n    ///\n    /// Could be overwritten by servers/locals' private `acl`\n    pub acl: Option<AccessControl>,\n\n    /// Flow statistic report Unix socket path (only for Android)\n    #[cfg(feature = \"local-flow-stat\")]\n    pub local_stat_addr: Option<LocalFlowStatAddress>,\n\n    /// Replay attack policy\n    pub security: SecurityConfig,\n\n    /// Balancer config of local server\n    pub balancer: BalancerConfig,\n\n    /// Configuration file path, the actual path of the configuration.\n    /// This is normally for auto-reloading if implementation supports.\n    pub config_path: Option<PathBuf>,\n\n    /// OnlineConfiguration (SIP008)\n    /// https://shadowsocks.org/doc/sip008.html\n    #[cfg(feature = \"local-online-config\")]\n    pub online_config: Option<OnlineConfig>,\n}\n\n/// Configuration parsing error kind\n#[derive(Copy, Clone, Debug)]\npub enum ErrorKind {\n    /// Missing required fields in JSON configuration\n    MissingField,\n    /// Missing some keys that must be provided together\n    Malformed,\n    /// Invalid value of some configuration keys\n    Invalid,\n    /// Invalid JSON\n    JsonParsingError,\n    /// `std::io::Error`\n    IoError,\n}\n\n/// Configuration parsing error\npub struct Error {\n    pub kind: ErrorKind,\n    pub desc: &'static str,\n    pub detail: Option<String>,\n}\n\nimpl Error {\n    pub fn new(kind: ErrorKind, desc: &'static str, detail: Option<String>) -> Self {\n        Self { kind, desc, detail }\n    }\n}\n\nimpl std::error::Error for Error {\n    fn description(&self) -> &str {\n        self.desc\n    }\n}\n\nmacro_rules! impl_from {\n    ($error:ty, $kind:expr, $desc:expr) => {\n        impl From<$error> for Error {\n            fn from(err: $error) -> Self {\n                Error::new($kind, $desc, Some(format!(\"{:?}\", err)))\n            }\n        }\n    };\n}\n\nimpl_from!(::std::io::Error, ErrorKind::IoError, \"error while reading file\");\nimpl_from!(json5::Error, ErrorKind::JsonParsingError, \"json parse error\");\nimpl_from!(serde_json::Error, ErrorKind::JsonParsingError, \"json parse error\");\n\nimpl Debug for Error {\n    fn fmt(&self, f: &mut Formatter) -> fmt::Result {\n        match self.detail {\n            None => write!(f, \"{}\", self.desc),\n            Some(ref det) => write!(f, \"{} {}\", self.desc, det),\n        }\n    }\n}\n\nimpl Display for Error {\n    fn fmt(&self, f: &mut Formatter) -> fmt::Result {\n        match self.detail {\n            None => f.write_str(self.desc),\n            Some(ref d) => write!(f, \"{}, {}\", self.desc, d),\n        }\n    }\n}\n\nimpl Config {\n    /// Creates an empty configuration\n    pub fn new(config_type: ConfigType) -> Self {\n        Self {\n            server: Vec::new(),\n            local: Vec::new(),\n\n            dns: DnsConfig::default(),\n            dns_cache_size: None,\n            ipv6_first: false,\n            ipv6_only: false,\n\n            no_delay: false,\n            fast_open: false,\n            keep_alive: None,\n            mptcp: false,\n\n            #[cfg(all(unix, not(target_os = \"android\")))]\n            nofile: None,\n\n            #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n            outbound_fwmark: None,\n            #[cfg(target_os = \"freebsd\")]\n            outbound_user_cookie: None,\n            outbound_bind_interface: None,\n            outbound_bind_addr: None,\n            outbound_udp_allow_fragmentation: false,\n            #[cfg(target_os = \"android\")]\n            outbound_vpn_protect_path: None,\n\n            inbound_send_buffer_size: None,\n            inbound_recv_buffer_size: None,\n            outbound_send_buffer_size: None,\n            outbound_recv_buffer_size: None,\n\n            manager: None,\n\n            config_type,\n\n            udp_timeout: None,\n            udp_max_associations: None,\n            udp_mtu: None,\n\n            acl: None,\n\n            #[cfg(feature = \"local-flow-stat\")]\n            local_stat_addr: None,\n\n            security: SecurityConfig::default(),\n\n            balancer: BalancerConfig::default(),\n\n            config_path: None,\n\n            #[cfg(feature = \"local-online-config\")]\n            online_config: None,\n        }\n    }\n\n    fn load_from_ssconfig(config: SSConfig, config_type: ConfigType) -> Result<Self, Error> {\n        let mut nconfig = Self::new(config_type);\n\n        // Client\n        //\n        // local_address is allowed to be NULL, which means to bind to ::1 or 127.0.0.1\n        //\n        // https://shadowsocks.org/en/config/quick-guide.html\n        #[inline]\n        fn get_local_address(local_address: Option<String>, local_port: u16, ipv6_first: bool) -> ServerAddr {\n            match local_address {\n                Some(addr) => {\n                    match addr.parse::<IpAddr>() {\n                        Ok(ip) => ServerAddr::from(SocketAddr::new(ip, local_port)),\n                        Err(..) => {\n                            // treated as domain\n                            ServerAddr::from((addr, local_port))\n                        }\n                    }\n                }\n                None => {\n                    // Implementation note: This is not implemented like libev which will choose IPv6 or IPv6 LoopBack address\n                    // by checking all its remote servers if all of them supports IPv6.\n                    let ip = if ipv6_first {\n                        Ipv6Addr::LOCALHOST.into()\n                    } else {\n                        Ipv4Addr::LOCALHOST.into()\n                    };\n\n                    ServerAddr::from(SocketAddr::new(ip, local_port))\n                }\n            }\n        }\n\n        // Mode\n        let mut global_mode = Mode::TcpOnly;\n        if let Some(m) = config.mode {\n            match m.parse::<Mode>() {\n                Ok(xm) => global_mode = xm,\n                Err(..) => {\n                    let e = Error::new(\n                        ErrorKind::Malformed,\n                        \"malformed `mode`, must be one of `tcp_only`, `udp_only` and `tcp_and_udp`\",\n                        None,\n                    );\n                    return Err(e);\n                }\n            }\n        }\n\n        match config_type {\n            ConfigType::Local => {\n                // Standard config\n                if config.local_address.is_some() && config.local_port.unwrap_or(0) == 0 {\n                    let err = Error::new(ErrorKind::MissingField, \"missing `local_port`\", None);\n                    return Err(err);\n                }\n\n                if let Some(local_port) = config.local_port {\n                    // local_port won't be 0, it was checked above\n                    assert_ne!(local_port, 0);\n\n                    let local_addr =\n                        get_local_address(config.local_address, local_port, config.ipv6_first.unwrap_or(false));\n\n                    // shadowsocks uses SOCKS5 by default\n                    let mut local_config = LocalConfig::new(ProtocolType::Socks);\n                    local_config.addr = Some(local_addr);\n                    local_config.mode = global_mode;\n                    local_config.protocol = match config.protocol {\n                        None => ProtocolType::Socks,\n                        Some(p) => match p.parse::<ProtocolType>() {\n                            Ok(p) => p,\n                            Err(..) => {\n                                let err = Error::new(\n                                    ErrorKind::Malformed,\n                                    \"`protocol` invalid\",\n                                    Some(format!(\"unrecognized protocol {p}\")),\n                                );\n                                return Err(err);\n                            }\n                        },\n                    };\n                    #[cfg(target_os = \"macos\")]\n                    {\n                        local_config\n                            .launchd_tcp_socket_name\n                            .clone_from(&config.launchd_tcp_socket_name);\n                        local_config\n                            .launchd_udp_socket_name\n                            .clone_from(&config.launchd_udp_socket_name);\n                    }\n\n                    let local_instance = LocalInstanceConfig {\n                        config: local_config,\n                        acl: None,\n                    };\n\n                    nconfig.local.push(local_instance);\n                }\n\n                // Ext locals\n                // `locals` are only effective in local server\n                if let Some(locals) = config.locals {\n                    for local in locals {\n                        if local.disabled.unwrap_or(false) {\n                            continue;\n                        }\n\n                        let protocol = match local.protocol {\n                            None => ProtocolType::Socks,\n                            Some(p) => match p.parse::<ProtocolType>() {\n                                Ok(p) => p,\n                                Err(..) => {\n                                    let err = Error::new(\n                                        ErrorKind::Malformed,\n                                        \"`protocol` invalid\",\n                                        Some(format!(\"unrecognized protocol {p}\")),\n                                    );\n                                    return Err(err);\n                                }\n                            },\n                        };\n\n                        let mut local_config = LocalConfig::new(protocol);\n\n                        if let Some(local_port) = local.local_port {\n                            if local_port == 0 {\n                                let err = Error::new(ErrorKind::Malformed, \"`local_port` cannot be 0\", None);\n                                return Err(err);\n                            }\n\n                            let local_addr =\n                                get_local_address(local.local_address, local_port, config.ipv6_first.unwrap_or(false));\n                            local_config.addr = Some(local_addr);\n                        } else if local.local_address.is_some() {\n                            let err = Error::new(ErrorKind::Malformed, \"missing `local_port`\", None);\n                            return Err(err);\n                        }\n\n                        if let Some(local_udp_port) = local.local_udp_port {\n                            if local_udp_port == 0 {\n                                let err = Error::new(ErrorKind::Malformed, \"`local_udp_port` cannot be 0\", None);\n                                return Err(err);\n                            }\n\n                            let local_udp_addr = get_local_address(\n                                local.local_udp_address,\n                                local_udp_port,\n                                config.ipv6_first.unwrap_or(false),\n                            );\n\n                            local_config.udp_addr = Some(local_udp_addr);\n                        }\n\n                        #[cfg(target_os = \"macos\")]\n                        {\n                            local_config.launchd_tcp_socket_name = local.launchd_tcp_socket_name;\n                            local_config.launchd_udp_socket_name = local.launchd_udp_socket_name;\n                        }\n\n                        match local.mode {\n                            Some(mode) => match mode.parse::<Mode>() {\n                                Ok(mode) => local_config.mode = mode,\n                                Err(..) => {\n                                    let err = Error::new(ErrorKind::Malformed, \"invalid `mode`\", None);\n                                    return Err(err);\n                                }\n                            },\n                            None => {\n                                // DNS server runs in `TcpAndUdp` mode by default to maintain backwards compatibility\n                                // see https://github.com/shadowsocks/shadowsocks-rust/issues/1281\n                                let mode = match protocol {\n                                    #[cfg(feature = \"local-dns\")]\n                                    ProtocolType::Dns => Mode::TcpAndUdp,\n                                    _ => global_mode,\n                                };\n\n                                local_config.mode = mode;\n                            }\n                        }\n\n                        #[cfg(feature = \"local-tunnel\")]\n                        if let Some(forward_address) = local.forward_address {\n                            let forward_port = match local.forward_port {\n                                None | Some(0) => {\n                                    let err =\n                                        Error::new(ErrorKind::Malformed, \"`forward_port` cannot be missing or 0\", None);\n                                    return Err(err);\n                                }\n                                Some(p) => p,\n                            };\n\n                            local_config.forward_addr = Some(match forward_address.parse::<IpAddr>() {\n                                Ok(ip) => Address::from(SocketAddr::new(ip, forward_port)),\n                                Err(..) => Address::from((forward_address, forward_port)),\n                            });\n                        }\n\n                        #[cfg(feature = \"local-redir\")]\n                        if let Some(tcp_redir) = local.tcp_redir {\n                            match tcp_redir.parse::<RedirType>() {\n                                Ok(r) => local_config.tcp_redir = r,\n                                Err(..) => {\n                                    let err = Error::new(ErrorKind::Malformed, \"`tcp_redir` invalid\", None);\n                                    return Err(err);\n                                }\n                            }\n                        }\n\n                        #[cfg(feature = \"local-redir\")]\n                        if let Some(udp_redir) = local.udp_redir {\n                            match udp_redir.parse::<RedirType>() {\n                                Ok(r) => local_config.udp_redir = r,\n                                Err(..) => {\n                                    let err = Error::new(ErrorKind::Malformed, \"`udp_redir` invalid\", None);\n                                    return Err(err);\n                                }\n                            }\n                        }\n\n                        #[cfg(feature = \"local-dns\")]\n                        if let Some(local_dns_address) = local.local_dns_address {\n                            match local_dns_address.parse::<IpAddr>() {\n                                Ok(ip) => {\n                                    local_config.local_dns_addr = Some(NameServerAddr::SocketAddr(SocketAddr::new(\n                                        ip,\n                                        local.local_dns_port.unwrap_or(53),\n                                    )));\n                                }\n                                #[cfg(unix)]\n                                Err(..) => {\n                                    local_config.local_dns_addr =\n                                        Some(NameServerAddr::UnixSocketAddr(PathBuf::from(local_dns_address)));\n                                }\n                                #[cfg(not(unix))]\n                                Err(..) => {\n                                    let err = Error::new(ErrorKind::Malformed, \"`local_dns_address` invalid\", None);\n                                    return Err(err);\n                                }\n                            }\n                        }\n\n                        #[cfg(feature = \"local-dns\")]\n                        if let Some(client_cache_size) = local.client_cache_size {\n                            local_config.client_cache_size = Some(client_cache_size);\n                        }\n\n                        #[cfg(feature = \"local-dns\")]\n                        if let Some(remote_dns_address) = local.remote_dns_address {\n                            let remote_dns_port = local.remote_dns_port.unwrap_or(53);\n                            local_config.remote_dns_addr = Some(match remote_dns_address.parse::<IpAddr>() {\n                                Ok(ip) => Address::from(SocketAddr::new(ip, remote_dns_port)),\n                                Err(..) => Address::from((remote_dns_address, remote_dns_port)),\n                            });\n                        }\n\n                        #[cfg(feature = \"local-tun\")]\n                        if let Some(tun_interface_address) = local.tun_interface_address {\n                            match tun_interface_address.parse::<IpNet>() {\n                                Ok(addr) => local_config.tun_interface_address = Some(addr),\n                                Err(..) => {\n                                    let err = Error::new(ErrorKind::Malformed, \"`tun_interface_address` invalid\", None);\n                                    return Err(err);\n                                }\n                            }\n                        }\n\n                        #[cfg(feature = \"local-tun\")]\n                        if let Some(tun_interface_destination) = local.tun_interface_destination {\n                            match tun_interface_destination.parse::<IpNet>() {\n                                Ok(addr) => local_config.tun_interface_destination = Some(addr),\n                                Err(..) => {\n                                    let err =\n                                        Error::new(ErrorKind::Malformed, \"`tun_interface_destination` invalid\", None);\n                                    return Err(err);\n                                }\n                            }\n                        }\n\n                        #[cfg(feature = \"local-tun\")]\n                        if let Some(tun_interface_name) = local.tun_interface_name {\n                            local_config.tun_interface_name = Some(tun_interface_name);\n                        }\n\n                        #[cfg(all(feature = \"local-tun\", unix))]\n                        if let Some(tun_device_fd_from_path) = local.tun_device_fd_from_path {\n                            local_config.tun_device_fd_from_path = Some(From::from(tun_device_fd_from_path));\n                        }\n\n                        #[cfg(feature = \"local\")]\n                        if let Some(socks5_auth_config_path) = local.socks5_auth_config_path {\n                            local_config.socks5_auth = Socks5AuthConfig::load_from_file(&socks5_auth_config_path)?;\n                        }\n\n                        #[cfg(feature = \"local-http\")]\n                        if let Some(http_auth_config_path) = local.http_auth_config_path {\n                            local_config.http_auth = HttpAuthConfig::load_from_file(&http_auth_config_path)?;\n                        }\n\n                        #[cfg(feature = \"local-fake-dns\")]\n                        {\n                            if let Some(d) = local.fake_dns_record_expire_duration {\n                                local_config.fake_dns_record_expire_duration = Some(Duration::from_secs(d));\n                            }\n                            if let Some(n) = local.fake_dns_ipv4_network {\n                                match n.parse::<Ipv4Net>() {\n                                    Ok(n) => local_config.fake_dns_ipv4_network = Some(n),\n                                    Err(..) => {\n                                        let err =\n                                            Error::new(ErrorKind::Malformed, \"invalid `fake_dns_ipv4_network`\", None);\n                                        return Err(err);\n                                    }\n                                }\n                            }\n                            if let Some(n) = local.fake_dns_ipv6_network {\n                                match n.parse::<Ipv6Net>() {\n                                    Ok(n) => local_config.fake_dns_ipv6_network = Some(n),\n                                    Err(..) => {\n                                        let err =\n                                            Error::new(ErrorKind::Malformed, \"invalid `fake_dns_ipv6_network`\", None);\n                                        return Err(err);\n                                    }\n                                }\n                            }\n                            if let Some(p) = local.fake_dns_database_path {\n                                local_config.fake_dns_database_path = Some(p.into());\n                            }\n                        }\n\n                        let mut local_instance = LocalInstanceConfig {\n                            config: local_config,\n                            acl: None,\n                        };\n\n                        if let Some(acl_path) = local.acl {\n                            let acl = match AccessControl::load_from_file(&acl_path) {\n                                Ok(acl) => acl,\n                                Err(err) => {\n                                    let err = Error::new(\n                                        ErrorKind::Invalid,\n                                        \"acl loading failed\",\n                                        Some(format!(\"file {acl_path}, error: {err}\")),\n                                    );\n                                    return Err(err);\n                                }\n                            };\n                            local_instance.acl = Some(acl);\n                        }\n\n                        nconfig.local.push(local_instance);\n                    }\n                }\n            }\n            ConfigType::Server | ConfigType::Manager => {\n                // NOTE: IGNORED.\n                // servers only uses `local_address` for binding outbound interfaces\n                //\n                // This behavior causes lots of confusion. use outbound_bind_addr instead\n            }\n            #[cfg(feature = \"local-online-config\")]\n            ConfigType::OnlineConfig => {\n                // SIP008. https://shadowsocks.org/doc/sip008.html\n                // \"version\" should be set to \"1\"\n                match config.version {\n                    Some(1) => {}\n                    Some(v) => {\n                        let err = Error::new(\n                            ErrorKind::Invalid,\n                            \"invalid online config version\",\n                            Some(format!(\"version: {v}\")),\n                        );\n                        return Err(err);\n                    }\n                    None => {\n                        warn!(\n                            \"OnlineConfig \\\"version\\\" is missing in the configuration, assuming it is a compatible version for this project\"\n                        );\n                    }\n                }\n            }\n        }\n\n        let server_source = match config_type {\n            ConfigType::Local | ConfigType::Server | ConfigType::Manager => ServerSource::Configuration,\n            #[cfg(feature = \"local-online-config\")]\n            ConfigType::OnlineConfig => ServerSource::OnlineConfig,\n        };\n\n        // Standard config\n        // Server\n        match (config.server, config.server_port, config.password, &config.method) {\n            (Some(address), Some(port), pwd_opt, Some(m)) => {\n                let addr = match address.parse::<Ipv4Addr>() {\n                    Ok(v4) => ServerAddr::SocketAddr(SocketAddr::V4(SocketAddrV4::new(v4, port))),\n                    Err(..) => match address.parse::<Ipv6Addr>() {\n                        Ok(v6) => ServerAddr::SocketAddr(SocketAddr::V6(SocketAddrV6::new(v6, port, 0, 0))),\n                        Err(..) => ServerAddr::DomainName(address, port),\n                    },\n                };\n\n                let method = match m.parse::<CipherKind>() {\n                    Ok(m) => m,\n                    Err(..) => {\n                        let err = Error::new(\n                            ErrorKind::Invalid,\n                            \"unsupported method\",\n                            Some(format!(\"`{m}` is not a supported method\")),\n                        );\n                        return Err(err);\n                    }\n                };\n\n                // Only \"password\" support getting from environment variable.\n                let password = match pwd_opt {\n                    Some(ref pwd) => read_variable_field_value(pwd),\n                    None => {\n                        if method.is_none() {\n                            String::new().into()\n                        } else {\n                            let err = Error::new(\n                                ErrorKind::MissingField,\n                                \"`password` is required\",\n                                Some(format!(\"`password` is required for method {method}\")),\n                            );\n                            return Err(err);\n                        }\n                    }\n                };\n\n                let mut nsvr = match ServerConfig::new(addr, password, method) {\n                    Ok(svr) => svr,\n                    Err(serr) => {\n                        let err = Error::new(\n                            ErrorKind::Malformed,\n                            \"server config create failed\",\n                            Some(format!(\"{}\", serr)),\n                        );\n                        return Err(err);\n                    }\n                };\n                nsvr.set_source(server_source);\n                nsvr.set_mode(global_mode);\n\n                if let Some(ref p) = config.plugin {\n                    // SIP008 allows \"plugin\" to be an empty string\n                    // Empty string implies \"no plugin\"\n                    if !p.is_empty() {\n                        let plugin = PluginConfig {\n                            plugin: p.clone(),\n                            plugin_opts: config.plugin_opts.clone(),\n                            plugin_args: config.plugin_args.clone().unwrap_or_default(),\n                            plugin_mode: match config.plugin_mode {\n                                None => Mode::TcpOnly,\n                                Some(ref mode) => match mode.parse::<Mode>() {\n                                    Ok(m) => m,\n                                    Err(..) => {\n                                        let e = Error::new(\n                                            ErrorKind::Malformed,\n                                            \"malformed `plugin_mode`, must be one of `tcp_only`, `udp_only` and `tcp_and_udp`\",\n                                            None,\n                                        );\n                                        return Err(e);\n                                    }\n                                },\n                            },\n                        };\n                        nsvr.set_plugin(plugin);\n                    }\n                }\n\n                if let Some(timeout) = config.timeout.map(Duration::from_secs) {\n                    nsvr.set_timeout(timeout);\n                }\n\n                nconfig.server.push(ServerInstanceConfig::with_server_config(nsvr));\n            }\n            (None, None, None, Some(_)) if config_type.is_manager() => {\n                // Set the default method for manager\n            }\n            (None, None, None, None) => (),\n            _ => {\n                let err = Error::new(\n                    ErrorKind::Malformed,\n                    \"`server`, `server_port`, `method`, `password` must be provided together\",\n                    None,\n                );\n                return Err(err);\n            }\n        }\n\n        // Ext servers\n        if let Some(servers) = config.servers {\n            for svr in servers {\n                // Skip if server is disabled\n                if svr.disabled.unwrap_or(false) {\n                    continue;\n                }\n\n                let address = svr.server;\n                let port = svr.server_port;\n\n                let addr = match address.parse::<Ipv4Addr>() {\n                    Ok(v4) => ServerAddr::SocketAddr(SocketAddr::V4(SocketAddrV4::new(v4, port))),\n                    Err(..) => match address.parse::<Ipv6Addr>() {\n                        Ok(v6) => ServerAddr::SocketAddr(SocketAddr::V6(SocketAddrV6::new(v6, port, 0, 0))),\n                        Err(..) => ServerAddr::DomainName(address, port),\n                    },\n                };\n\n                let method = match svr.method.parse::<CipherKind>() {\n                    Ok(m) => m,\n                    Err(..) => {\n                        let err = Error::new(\n                            ErrorKind::Invalid,\n                            \"unsupported method\",\n                            Some(format!(\"`{}` is not a supported method\", svr.method)),\n                        );\n                        return Err(err);\n                    }\n                };\n\n                // Only \"password\" support getting from environment variable.\n                let password = match svr.password {\n                    Some(ref pwd) => read_variable_field_value(pwd),\n                    None => {\n                        if method.is_none() {\n                            String::new().into()\n                        } else {\n                            let err = Error::new(\n                                ErrorKind::MissingField,\n                                \"`password` is required\",\n                                Some(format!(\"`password` is required for method {method}\")),\n                            );\n                            return Err(err);\n                        }\n                    }\n                };\n\n                let mut nsvr = match ServerConfig::new(addr, password, method) {\n                    Ok(svr) => svr,\n                    Err(serr) => {\n                        let err = Error::new(\n                            ErrorKind::Malformed,\n                            \"server config create failed\",\n                            Some(format!(\"{}\", serr)),\n                        );\n                        return Err(err);\n                    }\n                };\n                nsvr.set_source(server_source);\n\n                // Extensible Identity Header, Users\n                if let Some(users) = svr.users {\n                    let mut user_manager = ServerUserManager::new();\n\n                    for user in users {\n                        let user = match ServerUser::with_encoded_key(user.name, &user.password) {\n                            Ok(u) => u,\n                            Err(..) => {\n                                let err = Error::new(\n                                    ErrorKind::Malformed,\n                                    \"`users[].password` should be base64 encoded\",\n                                    None,\n                                );\n                                return Err(err);\n                            }\n                        };\n\n                        user_manager.add_user(user);\n                    }\n\n                    nsvr.set_user_manager(user_manager);\n                }\n\n                match svr.mode {\n                    Some(mode) => match mode.parse::<Mode>() {\n                        Ok(mode) => nsvr.set_mode(mode),\n                        Err(..) => {\n                            let err = Error::new(ErrorKind::Invalid, \"invalid `mode`\", None);\n                            return Err(err);\n                        }\n                    },\n                    None => {\n                        // Server will derive mode from the global scope\n                        if matches!(config_type, ConfigType::Server | ConfigType::Manager) {\n                            nsvr.set_mode(global_mode);\n                        }\n                    }\n                }\n\n                if let Some(p) = svr.plugin {\n                    // SIP008 allows \"plugin\" to be an empty string\n                    // Empty string implies \"no plugin\"\n                    if !p.is_empty() {\n                        let plugin = PluginConfig {\n                            plugin: p,\n                            plugin_opts: svr.plugin_opts,\n                            plugin_args: svr.plugin_args.unwrap_or_default(),\n                            plugin_mode: match svr.plugin_mode {\n                                None => Mode::TcpOnly,\n                                Some(ref mode) => match mode.parse::<Mode>() {\n                                    Ok(m) => m,\n                                    Err(..) => {\n                                        let e = Error::new(\n                                            ErrorKind::Malformed,\n                                            \"malformed `plugin_mode`, must be one of `tcp_only`, `udp_only` and `tcp_and_udp`\",\n                                            None,\n                                        );\n                                        return Err(e);\n                                    }\n                                },\n                            },\n                        };\n                        nsvr.set_plugin(plugin);\n                    }\n                }\n\n                if let Some(timeout) = config.timeout.map(Duration::from_secs) {\n                    nsvr.set_timeout(timeout);\n                }\n\n                if let Some(remarks) = svr.remarks {\n                    nsvr.set_remarks(remarks);\n                }\n\n                if let Some(id) = svr.id {\n                    nsvr.set_id(id);\n                }\n\n                if svr.tcp_weight.is_some() || svr.udp_weight.is_some() {\n                    let tcp_weight = svr.tcp_weight.unwrap_or(1.0);\n                    if !(0.0..=1.0).contains(&tcp_weight) {\n                        let err = Error::new(ErrorKind::Invalid, \"invalid `tcp_weight`, must be in [0, 1]\", None);\n                        return Err(err);\n                    }\n                    let udp_weight = svr.udp_weight.unwrap_or(1.0);\n                    if !(0.0..=1.0).contains(&udp_weight) {\n                        let err = Error::new(ErrorKind::Invalid, \"invalid `udp_weight`, must be in [0, 1]\", None);\n                        return Err(err);\n                    }\n                    let mut weight = ServerWeight::new();\n                    weight.set_tcp_weight(tcp_weight);\n                    weight.set_udp_weight(udp_weight);\n                    nsvr.set_weight(weight);\n                }\n\n                let mut server_instance = ServerInstanceConfig::with_server_config(nsvr);\n\n                if let Some(acl_path) = svr.acl {\n                    let acl = match AccessControl::load_from_file(&acl_path) {\n                        Ok(acl) => acl,\n                        Err(err) => {\n                            let err = Error::new(\n                                ErrorKind::Invalid,\n                                \"acl loading failed\",\n                                Some(format!(\"file {acl_path}, error: {err}\")),\n                            );\n                            return Err(err);\n                        }\n                    };\n                    server_instance.acl = Some(acl);\n                }\n\n                #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n                if let Some(outbound_fwmark) = svr.outbound_fwmark {\n                    server_instance.outbound_fwmark = Some(outbound_fwmark);\n                }\n\n                #[cfg(target_os = \"freebsd\")]\n                if let Some(outbound_user_cookie) = svr.outbound_user_cookie {\n                    server_instance.outbound_user_cookie = Some(outbound_user_cookie);\n                }\n\n                if let Some(outbound_bind_addr) = svr.outbound_bind_addr {\n                    server_instance.outbound_bind_addr = Some(outbound_bind_addr);\n                }\n\n                if let Some(ref outbound_bind_interface) = svr.outbound_bind_interface {\n                    server_instance.outbound_bind_interface = Some(outbound_bind_interface.clone());\n                }\n\n                if let Some(outbound_udp_allow_fragmentation) = svr.outbound_udp_allow_fragmentation {\n                    server_instance.outbound_udp_allow_fragmentation = Some(outbound_udp_allow_fragmentation);\n                }\n\n                nconfig.server.push(server_instance);\n            }\n        }\n\n        // Set timeout globally\n        if let Some(timeout) = config.timeout {\n            let timeout = Duration::from_secs(timeout);\n            // Set as a default timeout\n            for inst in &mut nconfig.server {\n                let svr = &mut inst.config;\n                if svr.timeout().is_none() {\n                    svr.set_timeout(timeout);\n                }\n            }\n        }\n\n        // Manager Address\n        if let Some(ma) = config.manager_address {\n            let manager = match config.manager_port {\n                Some(port) => {\n                    match ma.parse::<IpAddr>() {\n                        Ok(ip) => ManagerAddr::from(SocketAddr::new(ip, port)),\n                        Err(..) => {\n                            // treated as domain\n                            ManagerAddr::from((ma, port))\n                        }\n                    }\n                }\n                #[cfg(unix)]\n                None => ManagerAddr::from(PathBuf::from(ma)),\n                #[cfg(not(unix))]\n                None => {\n                    let e = Error::new(ErrorKind::MissingField, \"missing `manager_port`\", None);\n                    return Err(e);\n                }\n            };\n\n            let mut manager_config = ManagerConfig::new(manager);\n            manager_config.mode = global_mode;\n\n            if let Some(ref m) = config.method {\n                match m.parse::<CipherKind>() {\n                    Ok(method) => manager_config.method = Some(method),\n                    Err(..) => {\n                        let err = Error::new(\n                            ErrorKind::Invalid,\n                            \"unsupported method\",\n                            Some(format!(\"`{m}` is not a supported method\")),\n                        );\n                        return Err(err);\n                    }\n                }\n            }\n\n            if let Some(p) = config.plugin {\n                // SIP008 allows \"plugin\" to be an empty string\n                // Empty string implies \"no plugin\"\n                if !p.is_empty() {\n                    manager_config.plugin = Some(PluginConfig {\n                        plugin: p,\n                        plugin_opts: config.plugin_opts,\n                        plugin_args: config.plugin_args.unwrap_or_default(),\n                        plugin_mode: match config.plugin_mode {\n                            None => Mode::TcpOnly,\n                            Some(ref mode) => match mode.parse::<Mode>() {\n                                Ok(m) => m,\n                                Err(..) => {\n                                    let e = Error::new(\n                                        ErrorKind::Malformed,\n                                        \"malformed `plugin_mode`, must be one of `tcp_only`, `udp_only` and `tcp_and_udp`\",\n                                        None,\n                                    );\n                                    return Err(e);\n                                }\n                            },\n                        },\n                    });\n                }\n            }\n\n            nconfig.manager = Some(manager_config);\n        }\n\n        // DNS\n        {\n            match config.dns {\n                Some(SSDnsConfig::Simple(ds)) => nconfig.set_dns_formatted(&ds)?,\n                #[cfg(feature = \"hickory-dns\")]\n                Some(SSDnsConfig::HickoryDns(c)) => nconfig.dns = DnsConfig::HickoryDns(c),\n                None => nconfig.dns = DnsConfig::System,\n            }\n            nconfig.dns_cache_size = config.dns_cache_size;\n        }\n\n        // TCP nodelay\n        if let Some(b) = config.no_delay {\n            nconfig.no_delay = b;\n        }\n\n        // TCP fast open\n        if let Some(b) = config.fast_open {\n            nconfig.fast_open = b;\n        }\n\n        // TCP Keep-Alive\n        if let Some(d) = config.keep_alive {\n            nconfig.keep_alive = Some(Duration::from_secs(d));\n        }\n\n        // Multipath-TCP\n        if let Some(b) = config.mptcp {\n            nconfig.mptcp = b;\n        }\n\n        // UDP\n        nconfig.udp_timeout = config.udp_timeout.map(Duration::from_secs);\n\n        // Maximum associations to be kept simultaneously\n        nconfig.udp_max_associations = config.udp_max_associations;\n\n        // MTU for UDP\n        nconfig.udp_mtu = config.udp_mtu;\n\n        // RLIMIT_NOFILE\n        #[cfg(all(unix, not(target_os = \"android\")))]\n        {\n            nconfig.nofile = config.nofile;\n        }\n\n        // Uses IPv6 first\n        if let Some(f) = config.ipv6_first {\n            nconfig.ipv6_first = f;\n        }\n\n        // IPV6_V6ONLY\n        if let Some(o) = config.ipv6_only {\n            nconfig.ipv6_only = o;\n        }\n\n        // SO_MARK\n        #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n        if let Some(fwmark) = config.outbound_fwmark {\n            nconfig.outbound_fwmark = Some(fwmark);\n        }\n\n        // SO_USER_COOKIE\n        #[cfg(target_os = \"freebsd\")]\n        if let Some(user_cookie) = config.outbound_user_cookie {\n            nconfig.outbound_user_cookie = Some(user_cookie);\n        }\n\n        // Outbound bind() address\n        if let Some(bind_addr) = config.outbound_bind_addr {\n            match bind_addr.parse::<IpAddr>() {\n                Ok(b) => nconfig.outbound_bind_addr = Some(b),\n                Err(..) => {\n                    let err = Error::new(ErrorKind::Invalid, \"invalid outbound_bind_addr\", None);\n                    return Err(err);\n                }\n            }\n        }\n\n        // Bind device / interface\n        nconfig.outbound_bind_interface = config.outbound_bind_interface;\n\n        if let Some(b) = config.outbound_udp_allow_fragmentation {\n            nconfig.outbound_udp_allow_fragmentation = b;\n        }\n\n        // Security\n        if let Some(sec) = config.security\n            && let Some(replay_attack) = sec.replay_attack\n            && let Some(policy) = replay_attack.policy\n        {\n            match policy.parse::<ReplayAttackPolicy>() {\n                Ok(p) => nconfig.security.replay_attack.policy = p,\n                Err(..) => {\n                    let err = Error::new(ErrorKind::Invalid, \"invalid replay attack policy\", None);\n                    return Err(err);\n                }\n            }\n        }\n\n        if let Some(balancer) = config.balancer {\n            nconfig.balancer = BalancerConfig {\n                max_server_rtt: balancer.max_server_rtt.map(Duration::from_secs),\n                check_interval: balancer.check_interval.map(Duration::from_secs),\n                check_best_interval: balancer.check_best_interval.map(Duration::from_secs),\n            };\n        }\n\n        if let Some(acl_path) = config.acl {\n            let acl = match AccessControl::load_from_file(&acl_path) {\n                Ok(acl) => acl,\n                Err(err) => {\n                    let err = Error::new(\n                        ErrorKind::Invalid,\n                        \"acl loading failed\",\n                        Some(format!(\"file {acl_path}, error: {err}\")),\n                    );\n                    return Err(err);\n                }\n            };\n            nconfig.acl = Some(acl);\n        }\n\n        #[cfg(feature = \"local-online-config\")]\n        if let Some(online_config) = config.online_config {\n            nconfig.online_config = Some(OnlineConfig {\n                config_url: online_config.config_url,\n                update_interval: online_config.update_interval.map(Duration::from_secs),\n                allowed_plugins: online_config.allowed_plugins,\n            });\n        }\n\n        Ok(nconfig)\n    }\n\n    /// Set DNS configuration in string format\n    ///\n    /// 1. `[(unix|tcp|udp)://]host[:port][,host[:port]]...`\n    /// 2. Pre-defined. Like `google`, `cloudflare`\n    pub fn set_dns_formatted(&mut self, dns: &str) -> Result<(), Error> {\n        self.dns = match dns {\n            \"system\" => DnsConfig::System,\n\n            #[cfg(feature = \"hickory-dns\")]\n            \"google\" => DnsConfig::HickoryDns(ResolverConfig::google()),\n            #[cfg(all(feature = \"hickory-dns\", feature = \"dns-over-tls\"))]\n            \"google_tls\" => DnsConfig::HickoryDns(ResolverConfig::google_tls()),\n            #[cfg(all(feature = \"hickory-dns\", feature = \"dns-over-https\"))]\n            \"google_https\" => DnsConfig::HickoryDns(ResolverConfig::google_https()),\n            #[cfg(all(feature = \"hickory-dns\", feature = \"dns-over-h3\"))]\n            \"google_h3\" => DnsConfig::HickoryDns(ResolverConfig::google_h3()),\n\n            #[cfg(feature = \"hickory-dns\")]\n            \"cloudflare\" => DnsConfig::HickoryDns(ResolverConfig::cloudflare()),\n            #[cfg(all(feature = \"hickory-dns\", feature = \"dns-over-tls\"))]\n            \"cloudflare_tls\" => DnsConfig::HickoryDns(ResolverConfig::cloudflare_tls()),\n            #[cfg(all(feature = \"hickory-dns\", feature = \"dns-over-https\"))]\n            \"cloudflare_https\" => DnsConfig::HickoryDns(ResolverConfig::cloudflare_https()),\n\n            #[cfg(feature = \"hickory-dns\")]\n            \"quad9\" => DnsConfig::HickoryDns(ResolverConfig::quad9()),\n            #[cfg(all(feature = \"hickory-dns\", feature = \"dns-over-tls\"))]\n            \"quad9_tls\" => DnsConfig::HickoryDns(ResolverConfig::quad9_tls()),\n            #[cfg(all(feature = \"hickory-dns\", feature = \"dns-over-https\"))]\n            \"quad9_https\" => DnsConfig::HickoryDns(ResolverConfig::quad9_https()),\n\n            nameservers => self.parse_dns_nameservers(nameservers)?,\n        };\n\n        Ok(())\n    }\n\n    #[cfg(any(feature = \"hickory-dns\", feature = \"local-dns\"))]\n    fn parse_dns_nameservers(&mut self, nameservers: &str) -> Result<DnsConfig, Error> {\n        use hickory_resolver::proto::xfer::Protocol;\n\n        #[cfg(all(unix, feature = \"local-dns\"))]\n        if let Some(nameservers) = nameservers.strip_prefix(\"unix://\") {\n            // A special DNS server only for shadowsocks-android\n            // It serves like a TCP DNS server but using unix domain sockets\n\n            return Ok(DnsConfig::LocalDns(NameServerAddr::UnixSocketAddr(PathBuf::from(\n                nameservers,\n            ))));\n        }\n\n        enum DnsProtocol {\n            Tcp,\n            Udp,\n            Both,\n        }\n\n        impl DnsProtocol {\n            fn enable_tcp(&self) -> bool {\n                matches!(*self, Self::Tcp | Self::Both)\n            }\n\n            fn enable_udp(&self) -> bool {\n                matches!(*self, Self::Udp | Self::Both)\n            }\n        }\n\n        let mut protocol = DnsProtocol::Both;\n\n        let mut nameservers = nameservers;\n        if nameservers.starts_with(\"tcp://\") {\n            protocol = DnsProtocol::Tcp;\n            nameservers = &nameservers[6..];\n        } else if nameservers.starts_with(\"udp://\") {\n            protocol = DnsProtocol::Udp;\n            nameservers = &nameservers[6..];\n        }\n\n        // If enables Trust-DNS, then it supports multiple nameservers\n        //\n        // Set ips directly\n        // Similar to shadowsocks-libev's `ares_set_servers_ports_csv`\n        //\n        // ```\n        // host[:port][,host[:port]]...\n        // ```\n        //\n        // For example:\n        //     `192.168.1.100,192.168.1.101,3.4.5.6`\n        let mut c = ResolverConfig::new();\n        for part in nameservers.split(',') {\n            let socket_addr = if let Ok(socket_addr) = part.parse::<SocketAddr>() {\n                socket_addr\n            } else if let Ok(ipaddr) = part.parse::<IpAddr>() {\n                SocketAddr::new(ipaddr, 53)\n            } else {\n                let e = Error::new(\n                    ErrorKind::Invalid,\n                    \"invalid `dns` value, can only be [(tcp|udp)://]host[:port][,host[:port]]..., or unix:///path/to/dns, or predefined keys like \\\"google\\\", \\\"cloudflare\\\"\",\n                    None,\n                );\n                return Err(e);\n            };\n\n            if protocol.enable_udp() {\n                let ns_config = NameServerConfig::new(socket_addr, Protocol::Udp);\n                c.add_name_server(ns_config);\n            }\n            if protocol.enable_tcp() {\n                let ns_config = NameServerConfig::new(socket_addr, Protocol::Tcp);\n                c.add_name_server(ns_config);\n            }\n        }\n\n        Ok(if c.name_servers().is_empty() {\n            DnsConfig::System\n        } else {\n            DnsConfig::HickoryDns(c)\n        })\n    }\n\n    #[cfg(not(any(feature = \"hickory-dns\", feature = \"local-dns\")))]\n    fn parse_dns_nameservers(&mut self, _nameservers: &str) -> Result<DnsConfig, Error> {\n        Ok(DnsConfig::System)\n    }\n\n    /// Load Config from a `str`\n    pub fn load_from_str(s: &str, config_type: ConfigType) -> Result<Self, Error> {\n        let c = json5::from_str::<SSConfig>(s)?;\n        Self::load_from_ssconfig(c, config_type)\n    }\n\n    /// Load Config from a JSON `str`\n    pub fn load_from_json_str(s: &str, config_type: ConfigType) -> Result<Self, Error> {\n        let c = serde_json::from_str::<SSConfig>(s)?;\n        Self::load_from_ssconfig(c, config_type)\n    }\n\n    /// Load Config from a File\n    pub fn load_from_file<P: AsRef<Path>>(filename: P, config_type: ConfigType) -> Result<Self, Error> {\n        let filename = filename.as_ref();\n\n        let mut reader = OpenOptions::new().read(true).open(filename)?;\n        let mut content = String::new();\n        reader.read_to_string(&mut content)?;\n\n        let mut config = Self::load_from_str(&content[..], config_type)?;\n\n        // Record the path of the configuration for auto-reloading\n        config.config_path = Some(filename.to_owned());\n\n        Ok(config)\n    }\n\n    /// Check if there are any plugin are enabled with servers\n    pub fn has_server_plugins(&self) -> bool {\n        for inst in &self.server {\n            let server = &inst.config;\n\n            if server.plugin().is_some() {\n                return true;\n            }\n        }\n        false\n    }\n\n    /// Check if all required fields are already set\n    pub fn check_integrity(&self) -> Result<(), Error> {\n        if self.config_type.is_local() {\n            if self.local.is_empty() {\n                let err = Error::new(\n                    ErrorKind::MissingField,\n                    \"missing `locals` for client configuration\",\n                    None,\n                );\n                return Err(err);\n            }\n\n            for local_config in &self.local {\n                local_config.config.check_integrity()?;\n            }\n\n            // Balancer related checks\n            if let Some(rtt) = self.balancer.max_server_rtt\n                && rtt.as_secs() == 0\n            {\n                let err = Error::new(ErrorKind::Invalid, \"balancer.max_server_rtt must be > 0\", None);\n                return Err(err);\n            }\n\n            if let Some(intv) = self.balancer.check_interval\n                && intv.as_secs() == 0\n            {\n                let err = Error::new(ErrorKind::Invalid, \"balancer.check_interval must be > 0\", None);\n                return Err(err);\n            }\n        }\n\n        if self.config_type.is_server() && self.server.is_empty() {\n            let err = Error::new(\n                ErrorKind::MissingField,\n                \"missing any valid servers in configuration\",\n                None,\n            );\n            return Err(err);\n        }\n\n        #[cfg(feature = \"local-online-config\")]\n        if self.config_type.is_online_config() && self.server.is_empty() {\n            let err = Error::new(\n                ErrorKind::MissingField,\n                \"missing any valid servers in configuration\",\n                None,\n            );\n            return Err(err);\n        }\n\n        if self.config_type.is_manager() && self.manager.is_none() {\n            let err = Error::new(\n                ErrorKind::MissingField,\n                \"missing `manager_addr` and `manager_port` in configuration\",\n                None,\n            );\n            return Err(err);\n        }\n\n        for inst in &self.server {\n            let server = &inst.config;\n\n            // Plugin shouldn't be an empty string\n            if let Some(plugin) = server.plugin()\n                && plugin.plugin.trim().is_empty()\n            {\n                let err = Error::new(ErrorKind::Malformed, \"`plugin` shouldn't be an empty string\", None);\n                return Err(err);\n            }\n\n            // Server's domain name shouldn't be an empty string\n            match server.addr() {\n                ServerAddr::SocketAddr(sa) => {\n                    if sa.port() == 0 {\n                        let err = Error::new(ErrorKind::Malformed, \"`server_port` shouldn't be 0\", None);\n                        return Err(err);\n                    }\n\n                    if self.config_type.is_local() {\n                        // Only server could bind to INADDR_ANY\n                        let ip = sa.ip();\n                        if ip.is_unspecified() {\n                            let err = Error::new(\n                                ErrorKind::Malformed,\n                                \"`server` shouldn't be an unspecified address (INADDR_ANY)\",\n                                None,\n                            );\n                            return Err(err);\n                        }\n                    }\n\n                    #[cfg(feature = \"local-online-config\")]\n                    if self.config_type.is_online_config() {\n                        // Only server could bind to INADDR_ANY\n                        let ip = sa.ip();\n                        if ip.is_unspecified() {\n                            let err = Error::new(\n                                ErrorKind::Malformed,\n                                \"`server` shouldn't be an unspecified address (INADDR_ANY)\",\n                                None,\n                            );\n                            return Err(err);\n                        }\n                    }\n                }\n                ServerAddr::DomainName(dn, port) => {\n                    if dn.is_empty() || *port == 0 {\n                        let err = Error::new(\n                            ErrorKind::Malformed,\n                            \"`server` shouldn't be an empty string, `server_port` shouldn't be 0\",\n                            None,\n                        );\n                        return Err(err);\n                    }\n                }\n            }\n\n            // Users' key must match key length\n            if let Some(user_manager) = server.user_manager() {\n                #[cfg(feature = \"aead-cipher-2022\")]\n                if server.method().is_aead_2022() {\n                    use shadowsocks::config::method_support_eih;\n                    if user_manager.user_count() > 0 && !method_support_eih(server.method()) {\n                        let err = Error::new(\n                            ErrorKind::Invalid,\n                            \"server method doesn't support Extended Identity Header (EIH), remove `users`\",\n                            Some(format!(\"method {}\", server.method())),\n                        );\n                        return Err(err);\n                    }\n                }\n\n                let key_len = server.method().key_len();\n                for user in user_manager.users_iter() {\n                    if user.key().len() != key_len {\n                        let err = Error::new(\n                            ErrorKind::Malformed,\n                            \"`users[].password` length must be exactly the same as method's key length\",\n                            None,\n                        );\n                        return Err(err);\n                    }\n                }\n            }\n        }\n\n        Ok(())\n    }\n}\n\nimpl fmt::Display for Config {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        // Convert to json\n\n        let mut jconf = SSConfig::default();\n\n        // Locals\n        if !self.local.is_empty() {\n            if self.local.len() == 1 && self.local[0].config.is_basic() {\n                let local_instance = &self.local[0];\n                let local = &local_instance.config;\n                if let Some(ref a) = local.addr {\n                    jconf.local_address = Some(match a {\n                        ServerAddr::SocketAddr(sa) => sa.ip().to_string(),\n                        ServerAddr::DomainName(dm, ..) => dm.to_string(),\n                    });\n                    jconf.local_port = Some(match a {\n                        ServerAddr::SocketAddr(sa) => sa.port(),\n                        ServerAddr::DomainName(.., port) => *port,\n                    });\n                }\n\n                #[cfg(target_os = \"macos\")]\n                {\n                    jconf.launchd_tcp_socket_name.clone_from(&local.launchd_tcp_socket_name);\n                    jconf.launchd_udp_socket_name.clone_from(&local.launchd_udp_socket_name);\n                }\n\n                if local.protocol != ProtocolType::Socks {\n                    jconf.protocol = Some(local.protocol.as_str().to_owned());\n                }\n\n                // ACL\n                if let Some(ref acl) = local_instance.acl {\n                    jconf.acl = Some(acl.file_path().to_str().unwrap().to_owned());\n                }\n            } else {\n                let mut jlocals = Vec::with_capacity(self.local.len());\n                for local_instance in &self.local {\n                    let local = &local_instance.config;\n\n                    let jlocal = SSLocalExtConfig {\n                        local_address: local.addr.as_ref().map(|a| match a {\n                            ServerAddr::SocketAddr(sa) => sa.ip().to_string(),\n                            ServerAddr::DomainName(dm, ..) => dm.to_string(),\n                        }),\n                        local_port: local.addr.as_ref().map(|a| match a {\n                            ServerAddr::SocketAddr(sa) => sa.port(),\n                            ServerAddr::DomainName(.., port) => *port,\n                        }),\n                        disabled: None,\n                        local_udp_address: local.udp_addr.as_ref().map(|udp_addr| match udp_addr {\n                            ServerAddr::SocketAddr(sa) => sa.ip().to_string(),\n                            ServerAddr::DomainName(dm, ..) => dm.to_string(),\n                        }),\n                        local_udp_port: local.udp_addr.as_ref().map(|udp_addr| match udp_addr {\n                            ServerAddr::SocketAddr(sa) => sa.port(),\n                            ServerAddr::DomainName(.., port) => *port,\n                        }),\n                        mode: Some(local.mode.to_string()),\n                        protocol: match local.protocol {\n                            ProtocolType::Socks => None,\n                            #[allow(unreachable_patterns)]\n                            p => Some(p.as_str().to_owned()),\n                        },\n                        #[cfg(target_os = \"macos\")]\n                        launchd_tcp_socket_name: local.launchd_tcp_socket_name.clone(),\n                        #[cfg(target_os = \"macos\")]\n                        launchd_udp_socket_name: local.launchd_udp_socket_name.clone(),\n                        #[cfg(feature = \"local-redir\")]\n                        tcp_redir: if local.tcp_redir != RedirType::tcp_default() {\n                            Some(local.tcp_redir.to_string())\n                        } else {\n                            None\n                        },\n                        #[cfg(feature = \"local-redir\")]\n                        udp_redir: if local.udp_redir != RedirType::udp_default() {\n                            Some(local.udp_redir.to_string())\n                        } else {\n                            None\n                        },\n                        #[cfg(feature = \"local-tunnel\")]\n                        forward_address: match local.forward_addr {\n                            None => None,\n                            Some(ref forward_addr) => match forward_addr {\n                                Address::SocketAddress(sa) => Some(sa.ip().to_string()),\n                                Address::DomainNameAddress(dm, ..) => Some(dm.to_string()),\n                            },\n                        },\n                        #[cfg(feature = \"local-tunnel\")]\n                        forward_port: match local.forward_addr {\n                            None => None,\n                            Some(ref forward_addr) => match forward_addr {\n                                Address::SocketAddress(sa) => Some(sa.port()),\n                                Address::DomainNameAddress(.., port) => Some(*port),\n                            },\n                        },\n                        #[cfg(feature = \"local-dns\")]\n                        local_dns_address: match local.local_dns_addr {\n                            None => None,\n                            Some(ref local_dns_addr) => match local_dns_addr {\n                                NameServerAddr::SocketAddr(sa) => Some(sa.ip().to_string()),\n                                #[cfg(unix)]\n                                NameServerAddr::UnixSocketAddr(path) => {\n                                    Some(path.to_str().expect(\"path is not utf-8\").to_owned())\n                                }\n                            },\n                        },\n                        #[cfg(feature = \"local-dns\")]\n                        local_dns_port: match local.local_dns_addr {\n                            None => None,\n                            Some(ref local_dns_addr) => match local_dns_addr {\n                                NameServerAddr::SocketAddr(sa) => Some(sa.port()),\n                                #[cfg(unix)]\n                                NameServerAddr::UnixSocketAddr(..) => None,\n                            },\n                        },\n                        #[cfg(feature = \"local-dns\")]\n                        remote_dns_address: match local.remote_dns_addr {\n                            None => None,\n                            Some(ref remote_dns_addr) => match remote_dns_addr {\n                                Address::SocketAddress(sa) => Some(sa.ip().to_string()),\n                                Address::DomainNameAddress(dm, ..) => Some(dm.to_string()),\n                            },\n                        },\n                        #[cfg(feature = \"local-dns\")]\n                        remote_dns_port: match local.remote_dns_addr {\n                            None => None,\n                            Some(ref remote_dns_addr) => match remote_dns_addr {\n                                Address::SocketAddress(sa) => Some(sa.port()),\n                                Address::DomainNameAddress(.., port) => Some(*port),\n                            },\n                        },\n                        #[cfg(feature = \"local-dns\")]\n                        client_cache_size: local.client_cache_size,\n                        #[cfg(feature = \"local-tun\")]\n                        tun_interface_name: local.tun_interface_name.clone(),\n                        #[cfg(feature = \"local-tun\")]\n                        tun_interface_address: local.tun_interface_address.as_ref().map(ToString::to_string),\n                        #[cfg(feature = \"local-tun\")]\n                        tun_interface_destination: local.tun_interface_destination.as_ref().map(ToString::to_string),\n                        #[cfg(all(feature = \"local-tun\", unix))]\n                        tun_device_fd_from_path: local\n                            .tun_device_fd_from_path\n                            .as_ref()\n                            .map(|p| p.to_str().expect(\"tun_device_fd_from_path is not utf-8\").to_owned()),\n\n                        #[cfg(feature = \"local\")]\n                        socks5_auth_config_path: None,\n\n                        #[cfg(feature = \"local-http\")]\n                        http_auth_config_path: None,\n\n                        #[cfg(feature = \"local-fake-dns\")]\n                        fake_dns_record_expire_duration: local.fake_dns_record_expire_duration.map(|d| d.as_secs()),\n                        #[cfg(feature = \"local-fake-dns\")]\n                        fake_dns_ipv4_network: local.fake_dns_ipv4_network.map(|n| n.to_string()),\n                        #[cfg(feature = \"local-fake-dns\")]\n                        fake_dns_ipv6_network: local.fake_dns_ipv6_network.map(|n| n.to_string()),\n                        #[cfg(feature = \"local-fake-dns\")]\n                        fake_dns_database_path: local\n                            .fake_dns_database_path\n                            .as_ref()\n                            .and_then(|n| n.to_str().map(ToOwned::to_owned)),\n\n                        acl: local_instance\n                            .acl\n                            .as_ref()\n                            .and_then(|a| a.file_path().to_str().map(ToOwned::to_owned)),\n                    };\n                    jlocals.push(jlocal);\n                }\n                jconf.locals = Some(jlocals);\n            }\n        }\n\n        // Servers\n        match self.server.len() {\n            0 => {}\n            // For 1 server, uses standard configure format\n            1 if self.server[0].config.is_basic() => {\n                let inst = &self.server[0];\n                let svr = &inst.config;\n\n                jconf.server = Some(match *svr.addr() {\n                    ServerAddr::SocketAddr(ref sa) => sa.ip().to_string(),\n                    ServerAddr::DomainName(ref dm, ..) => dm.to_string(),\n                });\n                jconf.server_port = Some(match *svr.addr() {\n                    ServerAddr::SocketAddr(ref sa) => sa.port(),\n                    ServerAddr::DomainName(.., port) => port,\n                });\n                jconf.method = Some(svr.method().to_string());\n                jconf.password = if svr.method().is_none() {\n                    None\n                } else {\n                    Some(svr.password().to_string())\n                };\n                jconf.plugin = svr.plugin().map(|p| p.plugin.to_string());\n                jconf.plugin_opts = svr.plugin().and_then(|p| p.plugin_opts.clone());\n                jconf.plugin_args = svr.plugin().and_then(|p| {\n                    if p.plugin_args.is_empty() {\n                        None\n                    } else {\n                        Some(p.plugin_args.clone())\n                    }\n                });\n                jconf.plugin_mode = match svr.plugin() {\n                    None => None,\n                    Some(p) => match p.plugin_mode {\n                        Mode::TcpOnly => None,\n                        _ => Some(p.plugin_mode.to_string()),\n                    },\n                };\n                jconf.timeout = svr.timeout().map(|t| t.as_secs());\n                jconf.mode = Some(svr.mode().to_string());\n\n                if let Some(ref acl) = inst.acl {\n                    jconf.acl = Some(acl.file_path().to_str().unwrap().to_owned());\n                }\n            }\n            // For >1 servers, uses extended multiple server format\n            _ => {\n                let mut vsvr = Vec::new();\n\n                for inst in &self.server {\n                    let svr = &inst.config;\n\n                    vsvr.push(SSServerExtConfig {\n                        server: match *svr.addr() {\n                            ServerAddr::SocketAddr(ref sa) => sa.ip().to_string(),\n                            ServerAddr::DomainName(ref dm, ..) => dm.to_string(),\n                        },\n                        server_port: match *svr.addr() {\n                            ServerAddr::SocketAddr(ref sa) => sa.port(),\n                            ServerAddr::DomainName(.., port) => port,\n                        },\n                        password: if svr.method().is_none() {\n                            None\n                        } else {\n                            Some(svr.password().to_string())\n                        },\n                        method: svr.method().to_string(),\n                        users: svr.user_manager().map(|m| {\n                            let mut vu = Vec::new();\n                            for u in m.users_iter() {\n                                vu.push(SSServerUserConfig {\n                                    name: u.name().to_owned(),\n                                    password: u.encoded_key(),\n                                });\n                            }\n                            vu\n                        }),\n                        disabled: None,\n                        plugin: svr.plugin().map(|p| p.plugin.to_string()),\n                        plugin_opts: svr.plugin().and_then(|p| p.plugin_opts.clone()),\n                        plugin_args: svr.plugin().and_then(|p| {\n                            if p.plugin_args.is_empty() {\n                                None\n                            } else {\n                                Some(p.plugin_args.clone())\n                            }\n                        }),\n                        plugin_mode: match svr.plugin() {\n                            None => None,\n                            Some(p) => match p.plugin_mode {\n                                Mode::TcpOnly => None,\n                                _ => Some(p.plugin_mode.to_string()),\n                            },\n                        },\n                        timeout: svr.timeout().map(|t| t.as_secs()),\n                        remarks: svr.remarks().map(ToOwned::to_owned),\n                        id: svr.id().map(ToOwned::to_owned),\n                        mode: Some(svr.mode().to_string()),\n                        tcp_weight: if (svr.weight().tcp_weight() - 1.0).abs() > f32::EPSILON {\n                            Some(svr.weight().tcp_weight())\n                        } else {\n                            None\n                        },\n                        udp_weight: if (svr.weight().udp_weight() - 1.0).abs() > f32::EPSILON {\n                            Some(svr.weight().udp_weight())\n                        } else {\n                            None\n                        },\n                        acl: inst\n                            .acl\n                            .as_ref()\n                            .and_then(|a| a.file_path().to_str().map(ToOwned::to_owned)),\n                        #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n                        outbound_fwmark: inst.outbound_fwmark,\n                        #[cfg(target_os = \"freebsd\")]\n                        outbound_user_cookie: inst.outbound_user_cookie,\n                        outbound_bind_addr: inst.outbound_bind_addr,\n                        outbound_bind_interface: inst.outbound_bind_interface.clone(),\n                        outbound_udp_allow_fragmentation: inst.outbound_udp_allow_fragmentation,\n                    });\n                }\n\n                jconf.servers = Some(vsvr);\n            }\n        }\n\n        if let Some(ref m) = self.manager {\n            jconf.manager_address = Some(match m.addr {\n                ManagerAddr::SocketAddr(ref saddr) => saddr.ip().to_string(),\n                ManagerAddr::DomainName(ref dname, ..) => dname.clone(),\n                #[cfg(unix)]\n                ManagerAddr::UnixSocketAddr(ref path) => path.display().to_string(),\n            });\n\n            jconf.manager_port = match m.addr {\n                ManagerAddr::SocketAddr(ref saddr) => Some(saddr.port()),\n                ManagerAddr::DomainName(.., port) => Some(port),\n                #[cfg(unix)]\n                ManagerAddr::UnixSocketAddr(..) => None,\n            };\n\n            if jconf.mode.is_none() {\n                jconf.mode = Some(m.mode.to_string());\n            }\n\n            if jconf.method.is_none()\n                && let Some(ref m) = m.method\n            {\n                jconf.method = Some(m.to_string());\n            }\n\n            if jconf.plugin.is_none()\n                && let Some(ref p) = m.plugin\n            {\n                jconf.plugin = Some(p.plugin.clone());\n                if let Some(ref o) = p.plugin_opts {\n                    jconf.plugin_opts = Some(o.clone());\n                }\n                if !p.plugin_args.is_empty() {\n                    jconf.plugin_args = Some(p.plugin_args.clone());\n                }\n            }\n        }\n\n        if self.no_delay {\n            jconf.no_delay = Some(self.no_delay);\n        }\n\n        if self.fast_open {\n            jconf.fast_open = Some(self.fast_open);\n        }\n\n        if let Some(keepalive) = self.keep_alive {\n            jconf.keep_alive = Some(keepalive.as_secs());\n        }\n\n        if self.mptcp {\n            jconf.mptcp = Some(self.mptcp);\n        }\n\n        match self.dns {\n            DnsConfig::System => {}\n            #[cfg(feature = \"hickory-dns\")]\n            DnsConfig::HickoryDns(ref dns) => {\n                jconf.dns = Some(SSDnsConfig::HickoryDns(dns.clone()));\n            }\n            #[cfg(feature = \"local-dns\")]\n            DnsConfig::LocalDns(ref ns) => {\n                jconf.dns = Some(SSDnsConfig::Simple(ns.to_string()));\n            }\n        }\n\n        jconf.udp_timeout = self.udp_timeout.map(|t| t.as_secs());\n\n        jconf.udp_max_associations = self.udp_max_associations;\n\n        jconf.udp_mtu = self.udp_mtu;\n\n        #[cfg(all(unix, not(target_os = \"android\")))]\n        {\n            jconf.nofile = self.nofile;\n        }\n\n        if self.ipv6_first {\n            jconf.ipv6_first = Some(self.ipv6_first);\n        }\n\n        if self.ipv6_only {\n            jconf.ipv6_only = Some(self.ipv6_only);\n        }\n\n        #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n        {\n            jconf.outbound_fwmark = self.outbound_fwmark;\n        }\n\n        #[cfg(target_os = \"freebsd\")]\n        {\n            jconf.outbound_user_cookie = self.outbound_user_cookie;\n        }\n\n        jconf.outbound_bind_addr = self.outbound_bind_addr.map(|i| i.to_string());\n        jconf.outbound_bind_interface.clone_from(&self.outbound_bind_interface);\n        jconf.outbound_udp_allow_fragmentation = Some(self.outbound_udp_allow_fragmentation);\n\n        // Security\n        if self.security.replay_attack.policy != ReplayAttackPolicy::default() {\n            jconf.security = Some(SSSecurityConfig {\n                replay_attack: Some(SSSecurityReplayAttackConfig {\n                    policy: Some(self.security.replay_attack.policy.to_string()),\n                }),\n            });\n        }\n\n        // Balancer\n        if self.balancer.max_server_rtt.is_some() || self.balancer.check_interval.is_some() {\n            jconf.balancer = Some(SSBalancerConfig {\n                max_server_rtt: self.balancer.max_server_rtt.as_ref().map(Duration::as_secs),\n                check_interval: self.balancer.check_interval.as_ref().map(Duration::as_secs),\n                check_best_interval: self.balancer.check_best_interval.as_ref().map(Duration::as_secs),\n            });\n        }\n\n        // ACL\n        if let Some(ref acl) = self.acl {\n            jconf.acl = Some(acl.file_path().to_str().unwrap().to_owned());\n        }\n\n        // OnlineConfig\n        #[cfg(feature = \"local-online-config\")]\n        if let Some(ref online_config) = self.online_config {\n            jconf.online_config = Some(SSOnlineConfig {\n                config_url: online_config.config_url.clone(),\n                update_interval: online_config.update_interval.as_ref().map(Duration::as_secs),\n                allowed_plugins: online_config.allowed_plugins.clone(),\n            });\n        }\n\n        write!(f, \"{}\", json5::to_string(&jconf).unwrap())\n    }\n}\n\n/// Parse variable value if it is an environment variable\n///\n/// If value is in format `${VAR_NAME}` then it will try to read from `VAR_NAME` environment variable.\n/// It will return the original value if fails to read `${VAR_NAME}`.\npub fn read_variable_field_value(value: &str) -> Cow<'_, str> {\n    if let Some(left_over) = value.strip_prefix(\"${\")\n        && let Some(var_name) = left_over.strip_suffix('}')\n    {\n        match env::var(var_name) {\n            Ok(value) => return value.into(),\n            Err(err) => {\n                warn!(\n                    \"couldn't read password from environment variable {}, error: {}\",\n                    var_name, err\n                );\n            }\n        }\n    }\n\n    value.into()\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/dns/mod.rs",
    "content": "//! DNS resolvers\n\n#[cfg(feature = \"hickory-dns\")]\nuse hickory_resolver::config::ResolverOpts;\nuse log::trace;\nuse shadowsocks::{dns_resolver::DnsResolver, net::ConnectOpts};\n\nuse crate::config::DnsConfig;\n\n#[allow(unused_variables, dead_code)]\npub async fn build_dns_resolver(\n    dns: DnsConfig,\n    ipv6_first: bool,\n    dns_cache_size: Option<usize>,\n    connect_opts: &ConnectOpts,\n) -> Option<DnsResolver> {\n    match dns {\n        DnsConfig::System => {\n            #[cfg(feature = \"hickory-dns\")]\n            if crate::hint_support_default_system_resolver() {\n                use log::warn;\n                use std::env;\n\n                let force_system_builtin = match env::var(\"SS_SYSTEM_DNS_RESOLVER_FORCE_BUILTIN\") {\n                    Ok(mut v) => {\n                        v.make_ascii_lowercase();\n                        v == \"1\" || v == \"true\"\n                    }\n                    Err(..) => false,\n                };\n\n                if !force_system_builtin {\n                    let mut opts_opt = None;\n                    if let Some(dns_cache_size) = dns_cache_size {\n                        let mut opts = ResolverOpts::default();\n                        opts.cache_size = dns_cache_size;\n                        opts_opt = Some(opts);\n                    }\n\n                    return match DnsResolver::hickory_dns_system_resolver(opts_opt, connect_opts.clone()).await {\n                        Ok(r) => Some(r),\n                        Err(err) => {\n                            warn!(\n                                \"initialize hickory-dns DNS system resolver failed, fallback to default system resolver, error: {}\",\n                                err\n                            );\n                            None\n                        }\n                    };\n                }\n            }\n\n            trace!(\"initialized DNS system resolver builtin\");\n\n            None\n        }\n        #[cfg(feature = \"hickory-dns\")]\n        DnsConfig::HickoryDns(dns) => {\n            let mut opts_opt = None;\n            if let Some(dns_cache_size) = dns_cache_size {\n                let mut opts = ResolverOpts::default();\n                opts.cache_size = dns_cache_size;\n                opts_opt = Some(opts);\n            }\n\n            match DnsResolver::hickory_resolver(dns, opts_opt, connect_opts.clone()).await {\n                Ok(r) => Some(r),\n                Err(err) => {\n                    use log::warn;\n\n                    warn!(\n                        \"initialize hickory-dns DNS resolver failed, fallback to default system resolver, error: {}\",\n                        err\n                    );\n                    None\n                }\n            }\n        }\n        #[cfg(feature = \"local-dns\")]\n        DnsConfig::LocalDns(ns) => {\n            use crate::local::dns::dns_resolver::DnsResolver as LocalDnsResolver;\n            use shadowsocks::config::Mode;\n\n            trace!(\"initializing direct DNS resolver for {}\", ns);\n\n            let mut resolver = LocalDnsResolver::new(ns);\n            resolver.set_mode(Mode::TcpAndUdp);\n            resolver.set_ipv6_first(ipv6_first);\n            resolver.set_connect_opts(connect_opts.clone());\n\n            Some(DnsResolver::custom_resolver(resolver))\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/lib.rs",
    "content": "//! Shadowsocks Service\n//!\n//! <https://shadowsocks.org/>\n//!\n//! shadowsocks is a fast tunnel proxy that helps you bypass firewalls.\n//!\n//! ## Usage\n//!\n//! Build shadowsocks and you will get at least 2 binaries: `sslocal` and `ssserver`\n//!\n//! Write your servers in a configuration file. Format is defined in\n//! [shadowsocks' documentation](https://github.com/shadowsocks/shadowsocks/wiki)\n//!\n//! For example:\n//!\n//! ```json\n//! {\n//!    \"server\": \"my_server_ip\",\n//!    \"server_port\": 8388,\n//!    \"local_address\": \"127.0.0.1\",\n//!    \"local_port\": 1080,\n//!    \"password\": \"mypassword\",\n//!    \"timeout\": 300,\n//!    \"method\": \"aes-256-cfb\"\n//! }\n//! ```\n//!\n//! Save it in file `shadowsocks.json` and run local proxy server with\n//!\n//! ```bash\n//! cargo run --bin sslocal -- -c shadowsocks.json\n//! ```\n//!\n//! Now you can use SOCKS5 protocol to proxy your requests, for example:\n//!\n//! ```bash\n//! curl --socks5-hostname 127.0.0.1:1080 https://www.google.com\n//! ```\n//!\n//! On the server side, you can run the server with\n//!\n//! ```bash\n//! cargo run --bin ssserver -- -c shadowsocks.json\n//! ```\n//!\n//! Server should use the same configuration file as local, except the listen addresses for servers must be socket\n//! addresses.\n//!\n//! Of course, you can also use `cargo install` to install binaries.\n\nuse std::time::Duration;\n\n#[cfg(feature = \"local\")]\npub use self::local::run as run_local;\n\n#[cfg(feature = \"manager\")]\npub use self::manager::run as run_manager;\n#[cfg(feature = \"server\")]\npub use self::server::run as run_server;\npub use shadowsocks;\n\npub mod acl;\npub mod config;\nmod dns;\n#[cfg(feature = \"local\")]\npub mod local;\n#[cfg(feature = \"manager\")]\npub mod manager;\npub mod net;\n#[cfg(feature = \"server\")]\npub mod server;\nmod sys;\nmod utils;\n\n/// Default UDP association's expire duration\n#[allow(dead_code)]\nconst DEFAULT_UDP_EXPIRY_DURATION: Duration = Duration::from_secs(5 * 60);\n\n#[cfg(feature = \"hickory-dns\")]\nfn hint_support_default_system_resolver() -> bool {\n    // Nearly all *nix system have /etc/resolv.conf, except Android.\n    // macOS have to use system provided resolver.\n    cfg!(all(\n        unix,\n        not(target_os = \"android\"),\n        // not(target_os = \"macos\"),\n        // not(target_os = \"ios\")\n    ))\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/context.rs",
    "content": "//! Shadowsocks Local Server Context\n\nuse std::sync::Arc;\n#[cfg(feature = \"local-dns\")]\nuse std::{net::IpAddr, time::Duration};\n\n#[cfg(feature = \"local-dns\")]\nuse lru_time_cache::LruCache;\nuse shadowsocks::{\n    config::ServerType,\n    context::{Context, SharedContext},\n    dns_resolver::DnsResolver,\n    net::{AcceptOpts, ConnectOpts},\n    relay::Address,\n};\n#[cfg(feature = \"local-dns\")]\nuse tokio::sync::Mutex;\n#[cfg(feature = \"local-fake-dns\")]\nuse tokio::sync::RwLock;\n\nuse crate::{acl::AccessControl, config::SecurityConfig, net::FlowStat};\n\n#[cfg(feature = \"local-fake-dns\")]\nuse super::fake_dns::manager::FakeDnsManager;\n\n/// Local Service Context\n#[derive(Clone)]\npub struct ServiceContext {\n    context: SharedContext,\n    connect_opts: ConnectOpts,\n    accept_opts: AcceptOpts,\n\n    // Access Control\n    acl: Option<Arc<AccessControl>>,\n\n    // Flow statistic report\n    flow_stat: Arc<FlowStat>,\n\n    // For DNS relay's ACL domain name reverse lookup -- whether the IP shall be forwarded\n    #[cfg(feature = \"local-dns\")]\n    reverse_lookup_cache: Arc<Mutex<LruCache<IpAddr, bool>>>,\n\n    #[cfg(feature = \"local-fake-dns\")]\n    fake_dns_manager: Arc<RwLock<Vec<Arc<FakeDnsManager>>>>,\n}\n\nimpl Default for ServiceContext {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nimpl ServiceContext {\n    /// Create a new `ServiceContext`\n    pub fn new() -> Self {\n        Self {\n            context: Context::new_shared(ServerType::Local),\n            connect_opts: ConnectOpts::default(),\n            accept_opts: AcceptOpts::default(),\n            acl: None,\n            flow_stat: Arc::new(FlowStat::new()),\n            #[cfg(feature = \"local-dns\")]\n            reverse_lookup_cache: Arc::new(Mutex::new(LruCache::with_expiry_duration_and_capacity(\n                Duration::from_secs(3 * 24 * 60 * 60),\n                10240, // XXX: It should be enough for a normal user.\n            ))),\n            #[cfg(feature = \"local-fake-dns\")]\n            fake_dns_manager: Arc::new(RwLock::new(Vec::new())),\n        }\n    }\n\n    /// Get cloned `shadowsocks` Context\n    pub fn context(&self) -> SharedContext {\n        self.context.clone()\n    }\n\n    /// Get `shadowsocks` Context reference\n    pub fn context_ref(&self) -> &Context {\n        self.context.as_ref()\n    }\n\n    /// Set `ConnectOpts`\n    pub fn set_connect_opts(&mut self, connect_opts: ConnectOpts) {\n        self.connect_opts = connect_opts;\n    }\n\n    /// Get `ConnectOpts` reference\n    pub fn connect_opts_ref(&self) -> &ConnectOpts {\n        &self.connect_opts\n    }\n\n    /// Set `AcceptOpts`\n    pub fn set_accept_opts(&mut self, accept_opts: AcceptOpts) {\n        self.accept_opts = accept_opts;\n    }\n\n    /// Get `AcceptOpts` cloned\n    pub fn accept_opts(&self) -> AcceptOpts {\n        self.accept_opts.clone()\n    }\n\n    /// Set Access Control List\n    pub fn set_acl(&mut self, acl: Arc<AccessControl>) {\n        self.acl = Some(acl);\n    }\n\n    /// Get Access Control List reference\n    pub fn acl(&self) -> Option<&AccessControl> {\n        self.acl.as_deref()\n    }\n\n    /// Get cloned flow statistic\n    pub fn flow_stat(&self) -> Arc<FlowStat> {\n        self.flow_stat.clone()\n    }\n\n    /// Get flow statistic reference\n    pub fn flow_stat_ref(&self) -> &FlowStat {\n        self.flow_stat.as_ref()\n    }\n\n    /// Set customized DNS resolver\n    pub fn set_dns_resolver(&mut self, resolver: Arc<DnsResolver>) {\n        let context = Arc::get_mut(&mut self.context).expect(\"cannot set DNS resolver on a shared context\");\n        context.set_dns_resolver(resolver)\n    }\n\n    /// Get reference of DNS resolver\n    pub fn dns_resolver(&self) -> &DnsResolver {\n        self.context.dns_resolver()\n    }\n\n    /// Check if target should be bypassed\n    pub async fn check_target_bypassed(&self, addr: &Address) -> bool {\n        match self.acl {\n            None => false,\n            Some(ref acl) => {\n                #[cfg(feature = \"local-dns\")]\n                {\n                    if let Address::SocketAddress(saddr) = addr {\n                        // do the reverse lookup in our local cache\n                        let mut reverse_lookup_cache = self.reverse_lookup_cache.lock().await;\n                        // if a qname is found\n                        if let Some(forward) = reverse_lookup_cache.get(&saddr.ip()) {\n                            return !*forward;\n                        }\n                    }\n                }\n\n                acl.check_target_bypassed(&self.context, addr).await\n            }\n        }\n    }\n\n    /// Add a record to the reverse lookup cache\n    #[cfg(feature = \"local-dns\")]\n    pub async fn add_to_reverse_lookup_cache(&self, addr: IpAddr, forward: bool) {\n        let is_exception = forward\n            != match self.acl {\n                // Proxy everything by default\n                None => true,\n                Some(ref a) => a.check_ip_in_proxy_list(&addr),\n            };\n        let mut reverse_lookup_cache = self.reverse_lookup_cache.lock().await;\n        match reverse_lookup_cache.get_mut(&addr) {\n            Some(value) => {\n                if is_exception {\n                    *value = forward;\n                } else {\n                    // we do not need to remember the entry if it is already matched correctly\n                    reverse_lookup_cache.remove(&addr);\n                }\n            }\n            None => {\n                if is_exception {\n                    reverse_lookup_cache.insert(addr, forward);\n                }\n            }\n        }\n    }\n\n    /// Try to connect IPv6 addresses first if hostname could be resolved to both IPv4 and IPv6\n    pub fn set_ipv6_first(&mut self, ipv6_first: bool) {\n        let context = Arc::get_mut(&mut self.context).expect(\"cannot set ipv6_first on a shared context\");\n        context.set_ipv6_first(ipv6_first);\n    }\n\n    /// Set security config\n    pub fn set_security_config(&mut self, security: &SecurityConfig) {\n        let context = Arc::get_mut(&mut self.context).expect(\"cannot set security on a shared context\");\n        context.set_replay_attack_policy(security.replay_attack.policy);\n    }\n\n    /// Set Fake DNS manager\n    #[cfg(feature = \"local-fake-dns\")]\n    pub async fn add_fake_dns_manager(&self, manager: Arc<FakeDnsManager>) {\n        let mut managers = self.fake_dns_manager.write().await;\n        managers.push(manager);\n    }\n\n    /// Fake DNS maps IP to Domain\n    #[cfg(feature = \"local-fake-dns\")]\n    pub async fn try_map_fake_address(&self, addr: &Address) -> Option<Address> {\n        let socket_addr = match addr {\n            Address::DomainNameAddress(..) => return None,\n            Address::SocketAddress(socket_addr) => socket_addr,\n        };\n        let ip_addr = socket_addr.ip();\n\n        for mgr in self.fake_dns_manager.read().await.iter() {\n            if let Ok(Some(name)) = mgr.map_ip_domain(ip_addr).await {\n                let new_addr = Address::DomainNameAddress(name.to_string(), socket_addr.port());\n                log::trace!(\"fakedns mapped {} -> {}\", addr, new_addr);\n                return Some(new_addr);\n            }\n        }\n\n        None\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/dns/client_cache.rs",
    "content": "//! DNS Client cache\n\n#[cfg(unix)]\nuse std::path::Path;\nuse std::{\n    collections::{HashMap, VecDeque, hash_map::Entry},\n    future::Future,\n    io,\n    net::SocketAddr,\n    time::Duration,\n};\n\nuse hickory_resolver::proto::{ProtoError, op::Message};\nuse log::{debug, trace};\nuse tokio::sync::Mutex;\n\nuse shadowsocks::{config::ServerConfig, net::ConnectOpts, relay::socks5::Address};\n\nuse crate::local::context::ServiceContext;\n\nuse super::upstream::DnsClient;\n\n#[derive(Clone, Debug, Hash, Eq, PartialEq, PartialOrd, Ord)]\nenum DnsClientKey {\n    TcpLocal(SocketAddr),\n    UdpLocal(SocketAddr),\n    TcpRemote(Address),\n    UdpRemote(Address),\n}\n\npub struct DnsClientCache {\n    cache: Mutex<HashMap<DnsClientKey, VecDeque<DnsClient>>>,\n    timeout: Duration,\n    retry_count: usize,\n    max_client_per_addr: usize,\n}\n\nimpl DnsClientCache {\n    pub fn new(max_client_per_addr: usize) -> Self {\n        Self {\n            cache: Mutex::new(HashMap::new()),\n            timeout: Duration::from_secs(5),\n            retry_count: 1,\n            max_client_per_addr,\n        }\n    }\n\n    pub async fn lookup_local(\n        &self,\n        ns: SocketAddr,\n        msg: Message,\n        connect_opts: &ConnectOpts,\n        is_udp: bool,\n    ) -> Result<Message, ProtoError> {\n        let key = match is_udp {\n            true => DnsClientKey::UdpLocal(ns),\n            false => DnsClientKey::TcpLocal(ns),\n        };\n        self.lookup_dns(&key, msg, Some(connect_opts), None, None).await\n    }\n\n    pub async fn lookup_remote(\n        &self,\n        context: &ServiceContext,\n        svr_cfg: &ServerConfig,\n        ns: &Address,\n        msg: Message,\n        is_udp: bool,\n    ) -> Result<Message, ProtoError> {\n        let key = match is_udp {\n            true => DnsClientKey::UdpRemote(ns.clone()),\n            false => DnsClientKey::TcpRemote(ns.clone()),\n        };\n        self.lookup_dns(&key, msg, None, Some(context), Some(svr_cfg)).await\n    }\n\n    #[cfg(unix)]\n    pub async fn lookup_unix_stream<P: AsRef<Path>>(&self, ns: &P, msg: Message) -> Result<Message, ProtoError> {\n        let mut last_err = None;\n\n        for _ in 0..self.retry_count {\n            // UNIX stream won't keep connection alive\n            //\n            // https://github.com/shadowsocks/shadowsocks-rust/pull/567\n            //\n            // 1. The cost of recreating UNIX stream sockets are very low\n            // 2. This feature is only used by shadowsocks-android, and it doesn't support connection reuse\n\n            let mut client = match DnsClient::connect_unix_stream(ns).await {\n                Ok(client) => client,\n                Err(err) => {\n                    last_err = Some(From::from(err));\n                    continue;\n                }\n            };\n\n            let res = match client.lookup_timeout(msg.clone(), self.timeout).await {\n                Ok(msg) => msg,\n                Err(error) => {\n                    last_err = Some(error);\n                    continue;\n                }\n            };\n            return Ok(res);\n        }\n        Err(last_err.unwrap())\n    }\n\n    async fn lookup_dns(\n        &self,\n        dck: &DnsClientKey,\n        msg: Message,\n        connect_opts: Option<&ConnectOpts>,\n        context: Option<&ServiceContext>,\n        svr_cfg: Option<&ServerConfig>,\n    ) -> Result<Message, ProtoError> {\n        let mut last_err = None;\n        for _ in 0..self.retry_count {\n            let create_fn = async {\n                match dck {\n                    DnsClientKey::TcpLocal(tcp_l) => {\n                        let connect_opts = connect_opts.expect(\"connect options is required for local DNS\");\n                        DnsClient::connect_tcp_local(*tcp_l, connect_opts).await\n                    }\n                    DnsClientKey::UdpLocal(udp_l) => {\n                        let connect_opts = connect_opts.expect(\"connect options is required for local DNS\");\n                        DnsClient::connect_udp_local(*udp_l, connect_opts).await\n                    }\n                    DnsClientKey::TcpRemote(tcp_l) => {\n                        let context = context.expect(\"context is required for remote DNS\");\n                        let svr_cfg = svr_cfg.expect(\"server config is required for remote DNS\");\n\n                        DnsClient::connect_tcp_remote(\n                            context.context(),\n                            svr_cfg,\n                            tcp_l,\n                            context.connect_opts_ref(),\n                            context.flow_stat(),\n                        )\n                        .await\n                    }\n                    DnsClientKey::UdpRemote(udp_l) => {\n                        let context = context.expect(\"context is required for remote DNS\");\n                        let svr_cfg = svr_cfg.expect(\"server config is required for remote DNS\");\n\n                        DnsClient::connect_udp_remote(\n                            context.context(),\n                            svr_cfg,\n                            udp_l.clone(),\n                            context.connect_opts_ref(),\n                            context.flow_stat(),\n                        )\n                        .await\n                    }\n                }\n            };\n            match self.get_client_or_create(dck, create_fn).await {\n                Ok(mut client) => match client.lookup_timeout(msg.clone(), self.timeout).await {\n                    Ok(msg) => {\n                        self.save_client(dck.clone(), client).await;\n                        return Ok(msg);\n                    }\n                    Err(err) => {\n                        last_err = Some(err);\n                        continue;\n                    }\n                },\n                Err(err) => {\n                    last_err = Some(From::from(err));\n                    continue;\n                }\n            }\n        }\n        Err(last_err.unwrap())\n    }\n\n    async fn get_client_or_create<C>(&self, key: &DnsClientKey, create_fn: C) -> io::Result<DnsClient>\n    where\n        C: Future<Output = io::Result<DnsClient>>,\n    {\n        // Check if there already is a cached client\n        if let Some(q) = self.cache.lock().await.get_mut(key) {\n            while let Some(mut c) = q.pop_front() {\n                trace!(\"take cached DNS client for {:?}\", key);\n                if !c.check_connected().await {\n                    debug!(\"cached DNS client for {:?} is lost\", key);\n                    continue;\n                }\n                return Ok(c);\n            }\n        }\n        trace!(\"creating connection to DNS server {:?}\", key);\n\n        // Create one\n        create_fn.await\n    }\n\n    async fn save_client(&self, key: DnsClientKey, client: DnsClient) {\n        match self.cache.lock().await.entry(key) {\n            Entry::Occupied(occ) => {\n                let q = occ.into_mut();\n                q.push_back(client);\n                if q.len() > self.max_client_per_addr {\n                    q.pop_front();\n                }\n            }\n            Entry::Vacant(vac) => {\n                let mut q = VecDeque::with_capacity(self.max_client_per_addr);\n                q.push_back(client);\n                vac.insert(q);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/dns/config.rs",
    "content": "//! DNS configurations\n\n#[cfg(unix)]\nuse std::{convert::Infallible, path::PathBuf};\nuse std::{\n    fmt::{self, Display},\n    net::{IpAddr, SocketAddr},\n    str::FromStr,\n};\n\n/// DNS name server address\n#[derive(Debug, Clone, Eq, PartialEq, Hash)]\npub enum NameServerAddr {\n    /// IP address\n    SocketAddr(SocketAddr),\n    /// Unix Domain Socket address\n    ///\n    /// Specifically used by Android, which served as a stream protocol based DNS server\n    #[cfg(unix)]\n    UnixSocketAddr(PathBuf),\n}\n\n/// Parse `NameServerAddr` error\n#[cfg(unix)]\npub type NameServerAddrError = Infallible;\n/// Parse `NameServerAddr` error\n#[cfg(not(unix))]\npub type NameServerAddrError = <SocketAddr as FromStr>::Err;\n\nimpl FromStr for NameServerAddr {\n    type Err = NameServerAddrError;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        if let Ok(ip) = s.parse::<IpAddr>() {\n            return Ok(Self::SocketAddr(SocketAddr::new(ip, 53)));\n        }\n\n        match s.parse::<SocketAddr>() {\n            Ok(addr) => Ok(Self::SocketAddr(addr)),\n            #[cfg(unix)]\n            Err(..) => Ok(Self::UnixSocketAddr(PathBuf::from(s))),\n            #[cfg(not(unix))]\n            Err(err) => Err(err),\n        }\n    }\n}\n\nimpl Display for NameServerAddr {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match *self {\n            Self::SocketAddr(ref sa) => Display::fmt(sa, f),\n            #[cfg(unix)]\n            Self::UnixSocketAddr(ref p) => write!(f, \"{}\", p.display()),\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/dns/dns_resolver.rs",
    "content": "//! Replacement of service's DNS resolver\n\nuse std::{\n    io::{self, ErrorKind},\n    net::{Ipv4Addr, Ipv6Addr, SocketAddr},\n};\n\nuse futures::future;\nuse hickory_resolver::proto::{\n    op::{Message, Query},\n    rr::{DNSClass, Name, RData, RecordType},\n};\nuse log::{debug, trace};\n\nuse shadowsocks::{config::Mode, dns_resolver::DnsResolve, net::ConnectOpts};\n\nuse super::{client_cache::DnsClientCache, config::NameServerAddr};\n\npub struct DnsResolver {\n    ns: NameServerAddr,\n    client_cache: DnsClientCache,\n    mode: Mode,\n    ipv6_first: bool,\n    connect_opts: ConnectOpts,\n    attempts: usize,\n}\n\nimpl DnsResolver {\n    pub fn new(ns: NameServerAddr) -> Self {\n        Self {\n            ns,\n            client_cache: DnsClientCache::new(5),\n            mode: Mode::UdpOnly,\n            ipv6_first: false,\n            connect_opts: ConnectOpts::default(),\n            attempts: 2,\n        }\n    }\n\n    pub fn set_mode(&mut self, mode: Mode) {\n        self.mode = mode;\n    }\n\n    pub fn set_ipv6_first(&mut self, ipv6_first: bool) {\n        self.ipv6_first = ipv6_first;\n    }\n\n    pub fn set_connect_opts(&mut self, connect_opts: ConnectOpts) {\n        self.connect_opts = connect_opts;\n    }\n\n    async fn lookup(&self, msg: Message) -> io::Result<Message> {\n        let mut last_err = io::Error::new(ErrorKind::InvalidData, \"resolve empty\");\n\n        for _ in 0..self.attempts {\n            match self.lookup_inner(msg.clone()).await {\n                Ok(m) => return Ok(m),\n                Err(err) => last_err = err,\n            }\n        }\n\n        Err(last_err)\n    }\n\n    async fn lookup_inner(&self, msg: Message) -> io::Result<Message> {\n        match self.ns {\n            NameServerAddr::SocketAddr(ns) => {\n                let mut last_err = io::Error::new(ErrorKind::InvalidData, \"resolve empty\");\n\n                // Query UDP then TCP\n                if self.mode.enable_udp() {\n                    match self\n                        .client_cache\n                        .lookup_local(ns, msg.clone(), &self.connect_opts, true)\n                        .await\n                    {\n                        Ok(msg) => return Ok(msg),\n                        Err(err) => {\n                            last_err = err.into();\n                        }\n                    }\n                }\n\n                if self.mode.enable_tcp() {\n                    match self.client_cache.lookup_local(ns, msg, &self.connect_opts, false).await {\n                        Ok(msg) => return Ok(msg),\n                        Err(err) => {\n                            last_err = err.into();\n                        }\n                    }\n                }\n\n                Err(last_err)\n            }\n\n            #[cfg(unix)]\n            NameServerAddr::UnixSocketAddr(ref path) => self\n                .client_cache\n                .lookup_unix_stream(path, msg)\n                .await\n                .map_err(From::from),\n        }\n    }\n}\n\nimpl DnsResolve for DnsResolver {\n    async fn resolve(&self, host: &str, port: u16) -> io::Result<Vec<SocketAddr>> {\n        let mut name = Name::from_utf8(host)?;\n        name.set_fqdn(true);\n\n        let mut queryv4 = Query::new();\n        queryv4.set_query_class(DNSClass::IN);\n        queryv4.set_name(name);\n\n        let mut queryv6 = queryv4.clone();\n        queryv4.set_query_type(RecordType::A);\n        queryv6.set_query_type(RecordType::AAAA);\n\n        let mut msgv4 = Message::new();\n        msgv4.set_recursion_desired(true);\n        msgv4.add_query(queryv4);\n\n        let mut msgv6 = Message::new();\n        msgv6.set_recursion_desired(true);\n        msgv6.add_query(queryv6);\n\n        match future::join(self.lookup(msgv4), self.lookup(msgv6)).await {\n            (Err(res_v4), Err(res_v6)) => {\n                if self.ipv6_first {\n                    Err(res_v6)\n                } else {\n                    Err(res_v4)\n                }\n            }\n\n            (res_v4, res_v6) => {\n                let mut vaddr: Vec<SocketAddr> = vec![];\n\n                if self.ipv6_first {\n                    match res_v6 {\n                        Ok(res) => vaddr = store_dns(res, port),\n                        Err(err) => debug!(\"failed to resolve AAAA records, error: {}\", err),\n                    }\n\n                    match res_v4 {\n                        Ok(res) => vaddr = store_dns(res, port),\n                        Err(err) => debug!(\"failed to resolve A records, error: {}\", err),\n                    }\n                } else {\n                    match res_v4 {\n                        Ok(res) => vaddr = store_dns(res, port),\n                        Err(err) => debug!(\"failed to resolve A records, error: {}\", err),\n                    }\n\n                    match res_v6 {\n                        Ok(res) => vaddr = store_dns(res, port),\n                        Err(err) => debug!(\"failed to resolve AAAA records, error: {}\", err),\n                    }\n                }\n\n                if vaddr.is_empty() {\n                    let err = io::Error::new(ErrorKind::InvalidData, \"resolve empty\");\n                    return Err(err);\n                }\n\n                Ok(vaddr)\n            }\n        }\n    }\n}\n\nfn store_dns(res: Message, port: u16) -> Vec<SocketAddr> {\n    let mut vaddr = Vec::new();\n    for record in res.answers() {\n        match record.data() {\n            RData::A(addr) => vaddr.push(SocketAddr::new(Ipv4Addr::from(*addr).into(), port)),\n            RData::AAAA(addr) => vaddr.push(SocketAddr::new(Ipv6Addr::from(*addr).into(), port)),\n            rdata => {\n                trace!(\"skipped rdata {:?}\", rdata);\n            }\n        }\n    }\n    vaddr\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/dns/mod.rs",
    "content": "//! Customized DNS resolver\n\npub use self::{\n    config::NameServerAddr,\n    server::{Dns, DnsBuilder},\n};\n\nmod client_cache;\npub mod config;\npub mod dns_resolver;\npub mod server;\nmod upstream;\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/dns/server.rs",
    "content": "//! Shadowsocks DNS relay local server\n//!\n//! This DNS server requires 2 upstream DNS servers, one for direct queries, and the other queries through shadowsocks proxy\n\nuse std::{\n    cmp::Ordering,\n    collections::HashSet,\n    io::{self, ErrorKind},\n    net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},\n    str::FromStr,\n    sync::Arc,\n    time::Duration,\n};\n\nuse byteorder::{BigEndian, ByteOrder};\nuse bytes::{BufMut, BytesMut};\nuse futures::{\n    FutureExt,\n    future::{self, Either},\n};\nuse hickory_resolver::proto::{\n    op::{Message, OpCode, Query, header::MessageType, response_code::ResponseCode},\n    rr::{DNSClass, Name, RData, RecordType},\n};\nuse log::{debug, error, info, trace, warn};\nuse tokio::{\n    io::{AsyncReadExt, AsyncWriteExt},\n    net::{TcpStream, UdpSocket},\n    time,\n};\n\nuse shadowsocks::{\n    ServerAddr,\n    config::Mode,\n    net::TcpListener,\n    relay::{Address, udprelay::MAXIMUM_UDP_PAYLOAD_SIZE},\n};\n\nuse crate::{\n    acl::AccessControl,\n    local::{\n        context::ServiceContext,\n        loadbalancing::PingBalancer,\n        net::{tcp::listener::create_standard_tcp_listener, udp::listener::create_standard_udp_listener},\n    },\n};\n\nuse super::{client_cache::DnsClientCache, config::NameServerAddr};\n\n/// DNS Relay server builder\npub struct DnsBuilder {\n    context: Arc<ServiceContext>,\n    mode: Mode,\n    local_addr: NameServerAddr,\n    remote_addr: Address,\n    bind_addr: ServerAddr,\n    balancer: PingBalancer,\n    client_cache_size: usize,\n    #[cfg(target_os = \"macos\")]\n    launchd_tcp_socket_name: Option<String>,\n    #[cfg(target_os = \"macos\")]\n    launchd_udp_socket_name: Option<String>,\n}\n\nimpl DnsBuilder {\n    /// Create a new DNS Relay server\n    pub fn new(\n        bind_addr: ServerAddr,\n        local_addr: NameServerAddr,\n        remote_addr: Address,\n        balancer: PingBalancer,\n        client_cache_size: usize,\n    ) -> Self {\n        let context = ServiceContext::new();\n        Self::with_context(\n            Arc::new(context),\n            bind_addr,\n            local_addr,\n            remote_addr,\n            balancer,\n            client_cache_size,\n        )\n    }\n\n    /// Create with an existed `context`\n    pub fn with_context(\n        context: Arc<ServiceContext>,\n        bind_addr: ServerAddr,\n        local_addr: NameServerAddr,\n        remote_addr: Address,\n        balancer: PingBalancer,\n        client_cache_size: usize,\n    ) -> Self {\n        Self {\n            context,\n            mode: Mode::UdpOnly,\n            local_addr,\n            remote_addr,\n            bind_addr,\n            balancer,\n            client_cache_size,\n            #[cfg(target_os = \"macos\")]\n            launchd_tcp_socket_name: None,\n            #[cfg(target_os = \"macos\")]\n            launchd_udp_socket_name: None,\n        }\n    }\n\n    /// Set remote server mode\n    pub fn set_mode(&mut self, mode: Mode) {\n        self.mode = mode;\n    }\n\n    /// macOS launchd activate socket\n    #[cfg(target_os = \"macos\")]\n    pub fn set_launchd_tcp_socket_name(&mut self, n: String) {\n        self.launchd_tcp_socket_name = Some(n);\n    }\n\n    /// macOS launchd activate socket\n    #[cfg(target_os = \"macos\")]\n    pub fn set_launchd_udp_socket_name(&mut self, n: String) {\n        self.launchd_udp_socket_name = Some(n);\n    }\n\n    /// Build DNS server\n    pub async fn build(self) -> io::Result<Dns> {\n        let client = Arc::new(DnsClient::new(\n            self.context.clone(),\n            self.balancer,\n            self.mode,\n            self.client_cache_size,\n        ));\n\n        let local_addr = Arc::new(self.local_addr);\n        let remote_addr = Arc::new(self.remote_addr);\n\n        let mut tcp_server = None;\n        if self.mode.enable_tcp() {\n            #[allow(unused_mut)]\n            let mut builder = DnsTcpServerBuilder::new(\n                self.context.clone(),\n                self.bind_addr.clone(),\n                local_addr.clone(),\n                remote_addr.clone(),\n                client.clone(),\n            );\n\n            #[cfg(target_os = \"macos\")]\n            if let Some(s) = self.launchd_tcp_socket_name {\n                builder.set_launchd_socket_name(s);\n            }\n\n            let server = builder.build().await?;\n            tcp_server = Some(server);\n        }\n\n        let mut udp_server = None;\n        if self.mode.enable_udp() {\n            #[allow(unused_mut)]\n            let mut builder = DnsUdpServerBuilder::new(self.context, self.bind_addr, local_addr, remote_addr, client);\n\n            #[cfg(target_os = \"macos\")]\n            if let Some(s) = self.launchd_udp_socket_name {\n                builder.set_launchd_socket_name(s);\n            }\n\n            let server = builder.build().await?;\n            udp_server = Some(server);\n        }\n\n        Ok(Dns { tcp_server, udp_server })\n    }\n}\n\nstruct DnsTcpServerBuilder {\n    context: Arc<ServiceContext>,\n    bind_addr: ServerAddr,\n    local_addr: Arc<NameServerAddr>,\n    remote_addr: Arc<Address>,\n    client: Arc<DnsClient>,\n    #[cfg(target_os = \"macos\")]\n    launchd_socket_name: Option<String>,\n}\n\nimpl DnsTcpServerBuilder {\n    fn new(\n        context: Arc<ServiceContext>,\n        bind_addr: ServerAddr,\n        local_addr: Arc<NameServerAddr>,\n        remote_addr: Arc<Address>,\n        client: Arc<DnsClient>,\n    ) -> Self {\n        Self {\n            context,\n            bind_addr,\n            local_addr,\n            remote_addr,\n            client,\n            #[cfg(target_os = \"macos\")]\n            launchd_socket_name: None,\n        }\n    }\n\n    /// macOS launchd activate socket\n    #[cfg(target_os = \"macos\")]\n    fn set_launchd_socket_name(&mut self, n: String) {\n        self.launchd_socket_name = Some(n);\n    }\n\n    async fn build(self) -> io::Result<DnsTcpServer> {\n        cfg_if::cfg_if! {\n            if #[cfg(target_os = \"macos\")] {\n                let listener = match self.launchd_socket_name {\n                    Some(launchd_socket_name) => {\n                        use tokio::net::TcpListener as TokioTcpListener;\n                        use crate::net::launch_activate_socket::get_launch_activate_tcp_listener;\n\n                        let std_listener = get_launch_activate_tcp_listener(&launchd_socket_name, true)?;\n                        let tokio_listener = TokioTcpListener::from_std(std_listener)?;\n                        TcpListener::from_listener(tokio_listener, self.context.accept_opts())?\n                    } _ => {\n                        create_standard_tcp_listener(&self.context, &self.bind_addr).await?\n                    }\n                };\n            } else {\n                let listener = create_standard_tcp_listener(&self.context, &self.bind_addr).await?;\n            }\n        }\n\n        Ok(DnsTcpServer {\n            listener,\n            local_addr: self.local_addr,\n            remote_addr: self.remote_addr,\n            client: self.client,\n        })\n    }\n}\n\n/// DNS TCP server instance\npub struct DnsTcpServer {\n    listener: TcpListener,\n    local_addr: Arc<NameServerAddr>,\n    remote_addr: Arc<Address>,\n    client: Arc<DnsClient>,\n}\n\nimpl DnsTcpServer {\n    /// Get server local address\n    pub fn local_addr(&self) -> io::Result<SocketAddr> {\n        self.listener.local_addr()\n    }\n\n    /// Start serving\n    pub async fn run(self) -> io::Result<()> {\n        info!(\n            \"shadowsocks dns TCP listening on {}, local: {}, remote: {}\",\n            self.listener.local_addr()?,\n            self.local_addr,\n            self.remote_addr\n        );\n\n        loop {\n            let (stream, peer_addr) = match self.listener.accept().await {\n                Ok(s) => s,\n                Err(err) => {\n                    error!(\"accept failed with error: {}\", err);\n                    time::sleep(Duration::from_secs(1)).await;\n                    continue;\n                }\n            };\n\n            tokio::spawn(Self::handle_tcp_stream(\n                self.client.clone(),\n                stream,\n                peer_addr,\n                self.local_addr.clone(),\n                self.remote_addr.clone(),\n            ));\n        }\n    }\n\n    async fn handle_tcp_stream(\n        client: Arc<DnsClient>,\n        mut stream: TcpStream,\n        peer_addr: SocketAddr,\n        local_addr: Arc<NameServerAddr>,\n        remote_addr: Arc<Address>,\n    ) -> io::Result<()> {\n        let mut length_buf = [0u8; 2];\n        let mut message_buf = BytesMut::new();\n        loop {\n            match stream.read_exact(&mut length_buf).await {\n                Ok(..) => {}\n                Err(ref err) if err.kind() == ErrorKind::UnexpectedEof => {\n                    break;\n                }\n                Err(err) => {\n                    error!(\"udp tcp {} read length failed, error: {}\", peer_addr, err);\n                    return Err(err);\n                }\n            }\n\n            let length = BigEndian::read_u16(&length_buf) as usize;\n\n            message_buf.clear();\n            message_buf.reserve(length);\n            unsafe {\n                message_buf.advance_mut(length);\n            }\n\n            match stream.read_exact(&mut message_buf).await {\n                Ok(..) => {}\n                Err(err) => {\n                    error!(\"dns tcp {} read message failed, error: {}\", peer_addr, err);\n                    return Err(err);\n                }\n            }\n\n            let message = match Message::from_vec(&message_buf) {\n                Ok(m) => m,\n                Err(err) => {\n                    error!(\"dns tcp {} parse message failed, error: {}\", peer_addr, err);\n                    return Err(err.into());\n                }\n            };\n\n            let respond_message = match client.resolve(message, &local_addr, &remote_addr).await {\n                Ok(m) => m,\n                Err(err) => {\n                    error!(\"dns tcp {} lookup error: {}\", peer_addr, err);\n                    return Err(err);\n                }\n            };\n\n            let mut buf = respond_message.to_vec()?;\n            let length = buf.len();\n            buf.resize(length + 2, 0);\n            buf.copy_within(..length, 2);\n            BigEndian::write_u16(&mut buf[..2], length as u16);\n\n            stream.write_all(&buf).await?;\n        }\n\n        trace!(\"dns tcp connection {} closed\", peer_addr);\n\n        Ok(())\n    }\n}\n\nstruct DnsUdpServerBuilder {\n    context: Arc<ServiceContext>,\n    bind_addr: ServerAddr,\n    local_addr: Arc<NameServerAddr>,\n    remote_addr: Arc<Address>,\n    client: Arc<DnsClient>,\n    #[cfg(target_os = \"macos\")]\n    launchd_socket_name: Option<String>,\n}\n\nimpl DnsUdpServerBuilder {\n    fn new(\n        context: Arc<ServiceContext>,\n        bind_addr: ServerAddr,\n        local_addr: Arc<NameServerAddr>,\n        remote_addr: Arc<Address>,\n        client: Arc<DnsClient>,\n    ) -> Self {\n        Self {\n            context,\n            bind_addr,\n            local_addr,\n            remote_addr,\n            client,\n            #[cfg(target_os = \"macos\")]\n            launchd_socket_name: None,\n        }\n    }\n\n    /// macOS launchd activate socket\n    #[cfg(target_os = \"macos\")]\n    fn set_launchd_socket_name(&mut self, n: String) {\n        self.launchd_socket_name = Some(n);\n    }\n\n    async fn build(self) -> io::Result<DnsUdpServer> {\n        cfg_if::cfg_if! {\n            if #[cfg(target_os = \"macos\")] {\n                let socket = match self.launchd_socket_name { Some(launchd_socket_name) => {\n                    use tokio::net::UdpSocket as TokioUdpSocket;\n                    use crate::net::launch_activate_socket::get_launch_activate_udp_socket;\n\n                    let std_socket = get_launch_activate_udp_socket(&launchd_socket_name, true)?;\n                    TokioUdpSocket::from_std(std_socket)?\n                } _ => {\n                    create_standard_udp_listener(&self.context, &self.bind_addr).await?.into()\n                }};\n            } else {\n                let socket = create_standard_udp_listener(&self.context, &self.bind_addr).await?.into();\n            }\n        }\n\n        Ok(DnsUdpServer {\n            listener: Arc::new(socket),\n            local_addr: self.local_addr,\n            remote_addr: self.remote_addr,\n            client: self.client,\n        })\n    }\n}\n\n/// DNS UDP server instance\npub struct DnsUdpServer {\n    listener: Arc<UdpSocket>,\n    local_addr: Arc<NameServerAddr>,\n    remote_addr: Arc<Address>,\n    client: Arc<DnsClient>,\n}\n\nimpl DnsUdpServer {\n    /// Get server local address\n    pub fn local_addr(&self) -> io::Result<SocketAddr> {\n        self.listener.local_addr()\n    }\n\n    /// Start serving\n    pub async fn run(self) -> io::Result<()> {\n        info!(\n            \"shadowsocks dns UDP listening on {}, local: {}, remote: {}\",\n            self.listener.local_addr()?,\n            self.local_addr,\n            self.remote_addr\n        );\n\n        let mut buffer = [0u8; MAXIMUM_UDP_PAYLOAD_SIZE];\n        loop {\n            let (n, peer_addr) = match self.listener.recv_from(&mut buffer).await {\n                Ok(s) => s,\n                Err(err) => {\n                    error!(\"udp server recv_from failed with error: {}\", err);\n                    time::sleep(Duration::from_secs(1)).await;\n                    continue;\n                }\n            };\n\n            let data = &buffer[..n];\n\n            let message = match Message::from_vec(data) {\n                Ok(m) => m,\n                Err(err) => {\n                    error!(\"dns udp {} query message parse error: {}\", peer_addr, err);\n                    continue;\n                }\n            };\n\n            tokio::spawn(Self::handle_udp_packet(\n                self.client.clone(),\n                self.listener.clone(),\n                peer_addr,\n                message,\n                self.local_addr.clone(),\n                self.remote_addr.clone(),\n            ));\n        }\n    }\n\n    async fn handle_udp_packet(\n        client: Arc<DnsClient>,\n        listener: Arc<UdpSocket>,\n        peer_addr: SocketAddr,\n        message: Message,\n        local_addr: Arc<NameServerAddr>,\n        remote_addr: Arc<Address>,\n    ) -> io::Result<()> {\n        let respond_message = match client.resolve(message, &local_addr, &remote_addr).await {\n            Ok(m) => m,\n            Err(err) => {\n                error!(\"dns udp {} lookup failed, error: {}\", peer_addr, err);\n                return Err(err);\n            }\n        };\n\n        let buf = respond_message.to_vec()?;\n        listener.send_to(&buf, peer_addr).await?;\n\n        Ok(())\n    }\n}\n\n/// DNS Relay server\npub struct Dns {\n    tcp_server: Option<DnsTcpServer>,\n    udp_server: Option<DnsUdpServer>,\n}\n\nimpl Dns {\n    /// Get TCP server instance\n    pub fn tcp_server(&self) -> Option<&DnsTcpServer> {\n        self.tcp_server.as_ref()\n    }\n\n    /// Get UDP server instance\n    pub fn udp_server(&self) -> Option<&DnsUdpServer> {\n        self.udp_server.as_ref()\n    }\n\n    /// Run server\n    pub async fn run(self) -> io::Result<()> {\n        let mut vfut = Vec::new();\n\n        if let Some(tcp_server) = self.tcp_server {\n            vfut.push(tcp_server.run().boxed());\n        }\n\n        if let Some(udp_server) = self.udp_server {\n            // NOTE: SOCKS 5 RFC requires TCP handshake for UDP ASSOCIATE command\n            // But here we can start a standalone UDP SOCKS 5 relay server, for special use cases\n            vfut.push(udp_server.run().boxed());\n        }\n\n        let (res, ..) = future::select_all(vfut).await;\n        res\n    }\n}\n\nfn should_forward_by_ptr_name(acl: &AccessControl, name: &Name) -> bool {\n    let mut iter = name.iter().rev();\n    let mut next = || match iter.next() {\n        Some(label) => std::str::from_utf8(label).unwrap_or(\"*\"),\n        None => \"0\", // zero fill the missing labels\n    };\n    if !\"arpa\".eq_ignore_ascii_case(next()) {\n        return acl.is_default_in_proxy_list();\n    }\n    match &next().to_ascii_lowercase()[..] {\n        \"in-addr\" => {\n            let mut octets: [u8; 4] = [0; 4];\n            for octet in octets.iter_mut() {\n                match next().parse() {\n                    Ok(result) => *octet = result,\n                    Err(_) => return acl.is_default_in_proxy_list(),\n                }\n            }\n            acl.check_ip_in_proxy_list(&IpAddr::V4(Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3])))\n        }\n        \"ip6\" => {\n            let mut segments: [u16; 8] = [0; 8];\n            for segment in segments.iter_mut() {\n                match u16::from_str_radix(&[next(), next(), next(), next()].concat(), 16) {\n                    Ok(result) => *segment = result,\n                    Err(_) => return acl.is_default_in_proxy_list(),\n                }\n            }\n            acl.check_ip_in_proxy_list(&IpAddr::V6(Ipv6Addr::new(\n                segments[0],\n                segments[1],\n                segments[2],\n                segments[3],\n                segments[4],\n                segments[5],\n                segments[6],\n                segments[7],\n            )))\n        }\n        _ => acl.is_default_in_proxy_list(),\n    }\n}\n\nfn check_name_in_proxy_list(acl: &AccessControl, name: &Name) -> Option<bool> {\n    if name.is_fqdn() {\n        // convert to ASCII representation\n        let mut name = name.to_ascii();\n        name.make_ascii_lowercase();\n        acl.check_ascii_host_in_proxy_list(&name)\n    } else {\n        // unconditionally use default for PQDNs\n        Some(acl.is_default_in_proxy_list())\n    }\n}\n\n/// given the query, determine whether remote/local query should be used, or inconclusive\nfn should_forward_by_query(context: &ServiceContext, balancer: &PingBalancer, query: &Query) -> Option<bool> {\n    // No server was configured, then always resolve with local\n    if balancer.is_empty() {\n        return Some(false);\n    }\n\n    // Check if we are trying to make queries for remote servers\n    //\n    // This happens normally because VPN or TUN device receives DNS queries from local servers' plugins\n    // https://github.com/shadowsocks/shadowsocks-android/issues/2722\n    for server in balancer.servers() {\n        let svr_cfg = server.server_config();\n        if let ServerAddr::DomainName(dn, ..) = svr_cfg.addr() {\n            // Convert domain name to `Name`\n            // Ignore it if error occurs\n            if let Ok(mut name) = Name::from_str(dn) {\n                // cmp will handle FQDN in case insensitive way\n                if let Ordering::Equal = query.name().cmp(&name) {\n                    // It seems that query is for this server, just bypass it to local resolver\n                    trace!(\"DNS querying name {} of server {:?}\", query.name(), svr_cfg);\n                    return Some(false);\n                }\n                // test it again with fqdn set\n                name.set_fqdn(true);\n                if let Ordering::Equal = query.name().cmp(&name) {\n                    trace!(\"DNS querying name {} of server {:?}\", query.name(), svr_cfg);\n                    return Some(false);\n                }\n            }\n        }\n    }\n\n    if let Some(acl) = context.acl() {\n        if query.query_class() != DNSClass::IN {\n            // unconditionally use default for all non-IN queries\n            Some(acl.is_default_in_proxy_list())\n        } else if query.query_type() == RecordType::PTR {\n            Some(should_forward_by_ptr_name(acl, query.name()))\n        } else {\n            let result = check_name_in_proxy_list(acl, query.name());\n            if result.is_none() && acl.is_ip_empty() && acl.is_host_empty() {\n                Some(acl.is_default_in_proxy_list())\n            } else {\n                result\n            }\n        }\n    } else {\n        Some(true)\n    }\n}\n\n/// given the local response, determine whether remote response should be used instead\nfn should_forward_by_response(\n    acl: Option<&AccessControl>,\n    local_response: &io::Result<Message>,\n    query: &Query,\n) -> bool {\n    if let Some(acl) = acl {\n        if let Ok(local_response) = local_response {\n            let mut names = HashSet::new();\n            names.insert(query.name());\n            macro_rules! examine_name {\n                ($name:expr_2021, $is_answer:expr_2021) => {{\n                    names.insert($name);\n                    if $is_answer {\n                        if let Some(value) = check_name_in_proxy_list(acl, $name) {\n                            value\n                        } else {\n                            acl.is_default_in_proxy_list()\n                        }\n                    } else {\n                        acl.is_default_in_proxy_list()\n                    }\n                }};\n            }\n            macro_rules! examine_record {\n                ($rec:ident, $is_answer:expr_2021) => {\n                    if let RData::CNAME(name) = $rec.data() {\n                        if $is_answer {\n                            if let Some(value) = check_name_in_proxy_list(acl, name) {\n                                return value;\n                            }\n                        }\n                        names.insert(name);\n                        continue;\n                    }\n                    if $is_answer && !query.query_type().is_any() && $rec.record_type() != query.query_type() {\n                        warn!(\n                            \"local DNS response has inconsistent answer type {} for query {}\",\n                            $rec.record_type(),\n                            query\n                        );\n                        return true;\n                    }\n                    let forward = match $rec.data() {\n                        RData::A(ip) => acl.check_ip_in_proxy_list(&IpAddr::V4((*ip).into())),\n                        RData::AAAA(ip) => acl.check_ip_in_proxy_list(&IpAddr::V6((*ip).into())),\n                        // MX records cause type A additional section processing for the host specified by EXCHANGE.\n                        RData::MX(mx) => examine_name!(mx.exchange(), $is_answer),\n                        // NS records cause both the usual additional section processing to locate a type A record...\n                        RData::NS(name) => examine_name!(name, $is_answer),\n                        RData::PTR(_) => unreachable!(),\n                        _ => acl.is_default_in_proxy_list(),\n                    };\n                    if !forward {\n                        return false;\n                    }\n                };\n            }\n            for rec in local_response.answers() {\n                if !names.contains(rec.name()) {\n                    warn!(\n                        \"local DNS response contains unexpected name {} for query {}\",\n                        rec.name(),\n                        query\n                    );\n                    return true;\n                }\n                examine_record!(rec, true);\n            }\n            for rec in local_response.additionals() {\n                if names.contains(rec.name()) {\n                    examine_record!(rec, false);\n                }\n            }\n        }\n        true\n    } else {\n        unreachable!()\n    }\n}\n\nstruct DnsClient {\n    context: Arc<ServiceContext>,\n    client_cache: DnsClientCache,\n    mode: Mode,\n    balancer: PingBalancer,\n    attempts: usize,\n}\n\nimpl DnsClient {\n    fn new(context: Arc<ServiceContext>, balancer: PingBalancer, mode: Mode, client_cache_size: usize) -> Self {\n        Self {\n            context,\n            client_cache: DnsClientCache::new(client_cache_size),\n            mode,\n            balancer,\n            attempts: 2,\n        }\n    }\n\n    async fn resolve(\n        &self,\n        request: Message,\n        local_addr: &NameServerAddr,\n        remote_addr: &Address,\n    ) -> io::Result<Message> {\n        let mut message = Message::new();\n        message.set_id(request.id());\n        message.set_recursion_desired(true);\n        message.set_recursion_available(true);\n        message.set_message_type(MessageType::Response);\n\n        if !request.recursion_desired() {\n            // RD is required by default. Otherwise it may not get valid respond from remote servers\n\n            message.set_recursion_desired(false);\n            message.set_response_code(ResponseCode::NotImp);\n        } else if request.op_code() != OpCode::Query || request.message_type() != MessageType::Query {\n            // Other ops are not supported\n\n            message.set_response_code(ResponseCode::NotImp);\n        } else if request.query_count() > 0 {\n            // Make queries according to ACL rules\n\n            let (r, forward) = self.acl_lookup(&request.queries()[0], local_addr, remote_addr).await;\n            if let Ok(result) = r {\n                for rec in result.answers() {\n                    trace!(\"dns answer: {:?}\", rec);\n                    match rec.data() {\n                        RData::A(ip) => {\n                            self.context\n                                .add_to_reverse_lookup_cache(Ipv4Addr::from(*ip).into(), forward)\n                                .await\n                        }\n                        RData::AAAA(ip) => {\n                            self.context\n                                .add_to_reverse_lookup_cache(Ipv6Addr::from(*ip).into(), forward)\n                                .await\n                        }\n                        _ => (),\n                    }\n                }\n                message = result;\n                message.set_id(request.id());\n            } else {\n                message.set_response_code(ResponseCode::ServFail);\n            }\n        }\n        Ok(message)\n    }\n\n    async fn acl_lookup(\n        &self,\n        query: &Query,\n        local_addr: &NameServerAddr,\n        remote_addr: &Address,\n    ) -> (io::Result<Message>, bool) {\n        // Start querying name servers\n        debug!(\"DNS lookup {:?} {}\", query.query_type(), query.name());\n\n        match should_forward_by_query(&self.context, &self.balancer, query) {\n            Some(true) => {\n                let remote_response = self.lookup_remote(query, remote_addr).await;\n                trace!(\"pick remote response (query): {:?}\", remote_response);\n                return (remote_response, true);\n            }\n            Some(false) => {\n                let local_response = self.lookup_local(query, local_addr).await;\n                trace!(\"pick local response (query): {:?}\", local_response);\n                return (local_response, false);\n            }\n            None => (),\n        }\n\n        let decider = async {\n            let local_response = self.lookup_local(query, local_addr).await;\n            if should_forward_by_response(self.context.acl(), &local_response, query) {\n                None\n            } else {\n                Some(local_response)\n            }\n        };\n\n        let remote_response_fut = self.lookup_remote(query, remote_addr);\n        tokio::pin!(remote_response_fut, decider);\n\n        let mut use_remote = false;\n        let mut remote_response = None;\n        loop {\n            tokio::select! {\n                response = &mut remote_response_fut, if remote_response.is_none() => {\n                    if use_remote {\n                        trace!(\"pick remote response (response): {:?}\", response);\n                        return (response, true);\n                    } else {\n                        remote_response = Some(response);\n                    }\n                }\n                decision = &mut decider, if !use_remote => {\n                    if let Some(local_response) = decision {\n                        trace!(\"pick local response (response): {:?}\", local_response);\n                        return (local_response, false);\n                    } else if let Some(remote_response) = remote_response {\n                        trace!(\"pick remote response (response): {:?}\", remote_response);\n                        return (remote_response, true);\n                    } else {\n                        use_remote = true;\n                    }\n                }\n                else => unreachable!(),\n            }\n        }\n    }\n\n    async fn lookup_remote(&self, query: &Query, remote_addr: &Address) -> io::Result<Message> {\n        let mut last_err = io::Error::new(ErrorKind::InvalidData, \"resolve empty\");\n\n        for _ in 0..self.attempts {\n            match self.lookup_remote_inner(query, remote_addr).await {\n                Ok(m) => {\n                    return Ok(m);\n                }\n                Err(err) => last_err = err,\n            }\n        }\n\n        Err(last_err)\n    }\n\n    async fn lookup_remote_inner(&self, query: &Query, remote_addr: &Address) -> io::Result<Message> {\n        let mut message = Message::new();\n        message.set_id(rand::random());\n        message.set_recursion_desired(true);\n        message.add_query(query.clone());\n\n        // Query UDP and TCP\n\n        match self.mode {\n            Mode::TcpOnly => {\n                let server = self.balancer.best_tcp_server();\n                self.client_cache\n                    .lookup_remote(&self.context, server.server_config(), remote_addr, message, false)\n                    .await\n                    .map_err(From::from)\n            }\n            Mode::UdpOnly => {\n                let server = self.balancer.best_udp_server();\n                self.client_cache\n                    .lookup_remote(&self.context, server.server_config(), remote_addr, message, true)\n                    .await\n                    .map_err(From::from)\n            }\n            Mode::TcpAndUdp => {\n                // Query TCP & UDP simultaneously\n\n                let message2 = message.clone();\n                let tcp_fut = async {\n                    // For most cases UDP query will return in 1s,\n                    // Then this future will be disabled and have no effect\n                    //\n                    // Randomly choose from 500ms ~ 1.5s for preventing obvious request pattern\n                    let sleep_time = rand::random_range(500..=1500);\n                    time::sleep(Duration::from_millis(sleep_time)).await;\n\n                    let server = self.balancer.best_tcp_server();\n                    self.client_cache\n                        .lookup_remote(&self.context, server.server_config(), remote_addr, message2, false)\n                        .await\n                };\n                let udp_fut = async {\n                    let server = self.balancer.best_udp_server();\n                    self.client_cache\n                        .lookup_remote(&self.context, server.server_config(), remote_addr, message, true)\n                        .await\n                };\n\n                tokio::pin!(tcp_fut);\n                tokio::pin!(udp_fut);\n\n                match future::select(tcp_fut, udp_fut).await {\n                    Either::Left((res, next)) => match res {\n                        Ok(o) => Ok(o),\n                        Err(..) => next.await.map_err(From::from),\n                    },\n                    Either::Right((res, next)) => match res {\n                        Ok(o) => Ok(o),\n                        Err(..) => next.await.map_err(From::from),\n                    },\n                }\n            }\n        }\n    }\n\n    async fn lookup_local(&self, query: &Query, local_addr: &NameServerAddr) -> io::Result<Message> {\n        let mut last_err = io::Error::new(ErrorKind::InvalidData, \"resolve empty\");\n\n        for _ in 0..self.attempts {\n            match self.lookup_local_inner(query, local_addr).await {\n                Ok(m) => {\n                    return Ok(m);\n                }\n                Err(err) => last_err = err,\n            }\n        }\n\n        Err(last_err)\n    }\n\n    async fn lookup_local_inner(&self, query: &Query, local_addr: &NameServerAddr) -> io::Result<Message> {\n        let mut message = Message::new();\n        message.set_id(rand::random());\n        message.set_recursion_desired(true);\n        message.add_query(query.clone());\n\n        match *local_addr {\n            NameServerAddr::SocketAddr(ns) => {\n                // Query UDP then TCP\n\n                let udp_query =\n                    self.client_cache\n                        .lookup_local(ns, message.clone(), self.context.connect_opts_ref(), true);\n                let tcp_query = async move {\n                    // Send TCP query after 500ms, because UDP will always return faster than TCP, there is no need to send queries simultaneously\n                    time::sleep(Duration::from_millis(500)).await;\n\n                    self.client_cache\n                        .lookup_local(ns, message, self.context.connect_opts_ref(), false)\n                        .await\n                };\n\n                tokio::pin!(udp_query);\n                tokio::pin!(tcp_query);\n\n                match future::select(udp_query, tcp_query).await {\n                    Either::Left((Ok(m), ..)) => Ok(m),\n                    Either::Left((Err(..), next)) => next.await.map_err(From::from),\n                    Either::Right((Ok(m), ..)) => Ok(m),\n                    Either::Right((Err(..), next)) => next.await.map_err(From::from),\n                }\n            }\n            #[cfg(unix)]\n            NameServerAddr::UnixSocketAddr(ref path) => self\n                .client_cache\n                .lookup_unix_stream(path, message)\n                .await\n                .map_err(From::from),\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/dns/upstream.rs",
    "content": "//! DNS Relay Upstream\n\n#[cfg(unix)]\nuse std::path::Path;\nuse std::{\n    cmp::Ordering,\n    io::{self, ErrorKind},\n    net::SocketAddr,\n    sync::Arc,\n    time::Duration,\n};\n\nuse byteorder::{BigEndian, ByteOrder};\nuse bytes::{BufMut, BytesMut};\nuse hickory_resolver::proto::{ProtoError, ProtoErrorKind, op::Message};\nuse log::{error, trace};\nuse lru_time_cache::{Entry, LruCache};\nuse shadowsocks::{\n    config::ServerConfig,\n    context::SharedContext,\n    net::{ConnectOpts, TcpStream as ShadowTcpStream, UdpSocket as ShadowUdpSocket},\n    relay::{\n        Address,\n        tcprelay::ProxyClientStream,\n        udprelay::{ProxySocket, options::UdpSocketControlData},\n    },\n};\n#[cfg(unix)]\nuse tokio::net::UnixStream;\nuse tokio::{\n    io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt},\n    net::UdpSocket,\n    time,\n};\n\nuse crate::{\n    DEFAULT_UDP_EXPIRY_DURATION,\n    local::net::udp::generate_client_session_id,\n    net::{FlowStat, MonProxySocket, MonProxyStream, packet_window::PacketWindowFilter},\n};\n\n/// Collection of various DNS connections\n#[allow(clippy::large_enum_variant)]\npub enum DnsClient {\n    TcpLocal {\n        stream: ShadowTcpStream,\n    },\n    UdpLocal {\n        socket: UdpSocket,\n    },\n    #[cfg(unix)]\n    #[allow(dead_code)]\n    UnixStream {\n        stream: UnixStream,\n    },\n    TcpRemote {\n        stream: ProxyClientStream<MonProxyStream<ShadowTcpStream>>,\n    },\n    UdpRemote {\n        socket: MonProxySocket<ShadowUdpSocket>,\n        ns: Address,\n        control: UdpSocketControlData,\n        server_windows: LruCache<u64, PacketWindowFilter>,\n    },\n}\n\nimpl DnsClient {\n    /// Connect to local provided TCP DNS server\n    pub async fn connect_tcp_local(ns: SocketAddr, connect_opts: &ConnectOpts) -> io::Result<Self> {\n        let stream = ShadowTcpStream::connect_with_opts(&ns, connect_opts).await?;\n        Ok(Self::TcpLocal { stream })\n    }\n\n    /// Connect to local provided UDP DNS server\n    pub async fn connect_udp_local(ns: SocketAddr, connect_opts: &ConnectOpts) -> io::Result<Self> {\n        let socket = ShadowUdpSocket::connect_with_opts(&ns, connect_opts).await?.into();\n        Ok(Self::UdpLocal { socket })\n    }\n\n    #[cfg(unix)]\n    /// Connect to local provided Unix Domain Socket DNS server, in TCP-like protocol\n    pub async fn connect_unix_stream<P: AsRef<Path>>(path: &P) -> io::Result<Self> {\n        let stream = UnixStream::connect(path).await?;\n        Ok(Self::UnixStream { stream })\n    }\n\n    /// Connect to remote DNS server through proxy in TCP\n    pub async fn connect_tcp_remote(\n        context: SharedContext,\n        svr_cfg: &ServerConfig,\n        ns: &Address,\n        connect_opts: &ConnectOpts,\n        flow_stat: Arc<FlowStat>,\n    ) -> io::Result<Self> {\n        let stream = ProxyClientStream::connect_with_opts_map(context, svr_cfg, ns, connect_opts, |s| {\n            MonProxyStream::from_stream(s, flow_stat)\n        })\n        .await?;\n        Ok(Self::TcpRemote { stream })\n    }\n\n    /// Connect to remote DNS server through proxy in UDP\n    pub async fn connect_udp_remote(\n        context: SharedContext,\n        svr_cfg: &ServerConfig,\n        ns: Address,\n        connect_opts: &ConnectOpts,\n        flow_stat: Arc<FlowStat>,\n    ) -> io::Result<Self> {\n        let socket = ProxySocket::connect_with_opts(context.clone(), svr_cfg, connect_opts).await?;\n        let socket = MonProxySocket::from_socket(socket, flow_stat.clone());\n        let mut control = UdpSocketControlData::default();\n        control.client_session_id = generate_client_session_id();\n        control.packet_id = 0; // AEAD-2022 Packet ID starts from 1\n        Ok(Self::UdpRemote {\n            socket,\n            ns,\n            control,\n            // NOTE: expiry duration should be configurable. But the Client is held by DnsClientCache, which expires very quickly.\n            server_windows: LruCache::with_expiry_duration(DEFAULT_UDP_EXPIRY_DURATION),\n        })\n    }\n\n    /// Make a DNS lookup\n    #[allow(dead_code)]\n    pub async fn lookup(&mut self, mut msg: Message) -> Result<Message, ProtoError> {\n        self.inner_lookup(&mut msg).await\n    }\n\n    /// Make a DNS lookup with timeout\n    pub async fn lookup_timeout(&mut self, mut msg: Message, timeout: Duration) -> Result<Message, ProtoError> {\n        match time::timeout(timeout, self.inner_lookup(&mut msg)).await {\n            Ok(Ok(msg)) => Ok(msg),\n            Ok(Err(error)) => Err(error),\n            Err(..) => Err(ProtoErrorKind::Timeout.into()),\n        }\n    }\n\n    async fn inner_lookup(&mut self, msg: &mut Message) -> Result<Message, ProtoError> {\n        // Make a random ID\n        msg.set_id(rand::random());\n\n        trace!(\"DNS lookup {:?}\", msg);\n\n        match *self {\n            Self::TcpLocal { ref mut stream } => stream_query(stream, msg).await,\n            Self::UdpLocal { ref socket } => {\n                let bytes = msg.to_vec()?;\n                socket.send(&bytes).await?;\n\n                let mut recv_buf = [0u8; 512];\n                let n = socket.recv(&mut recv_buf).await?;\n\n                Message::from_vec(&recv_buf[..n])\n            }\n            #[cfg(unix)]\n            Self::UnixStream { ref mut stream } => stream_query(stream, msg).await,\n            Self::TcpRemote { ref mut stream } => stream_query(stream, msg).await,\n            Self::UdpRemote {\n                ref mut socket,\n                ref ns,\n                ref mut control,\n                ref mut server_windows,\n            } => {\n                control.packet_id = match control.packet_id.checked_add(1) {\n                    Some(i) => i,\n                    None => return Err(ProtoErrorKind::Message(\"packet id overflows\").into()),\n                };\n\n                let bytes = msg.to_vec()?;\n                socket.send_with_ctrl(ns, control, &bytes).await?;\n\n                let mut recv_buf = [0u8; 512];\n                let (n, _, recv_control) = socket.recv_with_ctrl(&mut recv_buf).await?;\n\n                if let Some(server_control) = recv_control {\n                    let filter = match server_windows.entry(server_control.server_session_id) {\n                        Entry::Occupied(occ) => occ.into_mut(),\n                        Entry::Vacant(vac) => vac.insert(PacketWindowFilter::new()),\n                    };\n\n                    if !filter.validate_packet_id(server_control.packet_id, u64::MAX) {\n                        error!(\n                            \"dns client for {} packet_id {} out of window\",\n                            ns, server_control.packet_id\n                        );\n\n                        return Err(ProtoErrorKind::Message(\"packet id out of window\").into());\n                    }\n                }\n\n                Message::from_vec(&recv_buf[..n])\n            }\n        }\n    }\n\n    /// Check if the underlying connection is still connecting\n    ///\n    /// This will only work for TCP and UNIX Stream connections.\n    /// UDP clients will always return `true`.\n    pub async fn check_connected(&mut self) -> bool {\n        #[cfg(unix)]\n        fn check_peekable<F: std::os::unix::io::AsRawFd>(fd: &mut F) -> bool {\n            let fd = fd.as_raw_fd();\n\n            unsafe {\n                let mut peek_buf = [0u8; 1];\n\n                let ret = libc::recv(\n                    fd,\n                    peek_buf.as_mut_ptr() as *mut libc::c_void,\n                    peek_buf.len(),\n                    libc::MSG_PEEK | libc::MSG_DONTWAIT,\n                );\n\n                match ret.cmp(&0) {\n                    // EOF, connection lost\n                    Ordering::Equal => false,\n                    // Data in buffer\n                    Ordering::Greater => true,\n                    Ordering::Less => {\n                        let err = io::Error::last_os_error();\n                        // EAGAIN, EWOULDBLOCK\n                        // Still connected.\n                        err.kind() == ErrorKind::WouldBlock\n                    }\n                }\n            }\n        }\n\n        #[cfg(windows)]\n        fn check_peekable<F: std::os::windows::io::AsRawSocket>(s: &mut F) -> bool {\n            use windows_sys::{\n                Win32::Networking::WinSock::{MSG_PEEK, SOCKET, recv},\n                core::PSTR,\n            };\n\n            let sock = s.as_raw_socket() as SOCKET;\n\n            unsafe {\n                let mut peek_buf = [0u8; 1];\n\n                let ret = recv(sock, peek_buf.as_mut_ptr() as PSTR, peek_buf.len() as i32, MSG_PEEK);\n\n                match ret.cmp(&0) {\n                    // EOF, connection lost\n                    Ordering::Equal => false,\n                    // Data in buffer\n                    Ordering::Greater => true,\n                    Ordering::Less => {\n                        let err = io::Error::last_os_error();\n                        // I have to trust the `s` have already set to non-blocking mode\n                        // Because windows doesn't have MSG_DONTWAIT\n                        err.kind() == ErrorKind::WouldBlock\n                    }\n                }\n            }\n        }\n\n        match *self {\n            Self::TcpLocal { ref mut stream } => check_peekable(stream),\n            Self::UdpLocal { .. } => true,\n            #[cfg(unix)]\n            Self::UnixStream { ref mut stream } => check_peekable(stream),\n            Self::TcpRemote { ref mut stream } => check_peekable(stream.get_mut().get_mut()),\n            Self::UdpRemote { .. } => true,\n        }\n    }\n}\n\npub async fn stream_query<S>(stream: &mut S, r: &Message) -> Result<Message, ProtoError>\nwhere\n    S: AsyncRead + AsyncWrite + Unpin,\n{\n    let mut req_bytes = r.to_vec()?;\n\n    // Prepend length\n    let length = req_bytes.len();\n    req_bytes.resize(length + 2, 0);\n    req_bytes.copy_within(..length, 2);\n    BigEndian::write_u16(&mut req_bytes[0..2], length as u16);\n\n    stream.write_all(&req_bytes).await?;\n\n    // Read response, [LENGTH][Message]\n    let mut length_buf = [0u8; 2];\n    stream.read_exact(&mut length_buf).await?;\n\n    let length = BigEndian::read_u16(&length_buf);\n    let mut rsp_bytes = BytesMut::with_capacity(length as usize);\n    unsafe {\n        rsp_bytes.advance_mut(length as usize);\n    }\n    stream.read_exact(&mut rsp_bytes).await?;\n\n    Message::from_vec(&rsp_bytes)\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/fake_dns/manager.rs",
    "content": "//! Fake DNS manager\n\nuse std::{\n    io,\n    iter::Cycle,\n    net::{IpAddr, Ipv4Addr, Ipv6Addr},\n    path::Path,\n    time::{Duration, SystemTime},\n};\n\nuse hickory_resolver::proto::rr::Name;\nuse ipnet::{Ipv4AddrRange, Ipv4Net, Ipv6AddrRange, Ipv6Net};\nuse log::{error, trace, warn};\nuse rocksdb::DB as RocksDB;\nuse tokio::sync::Mutex;\n\nuse super::proto;\n\nconst FAKE_DNS_MANAGER_STORAGE_VERSION: u32 = 3;\n\n/// Error type of FakeDns manager\n#[derive(thiserror::Error, Debug)]\npub enum FakeDnsError {\n    /// std::io::Error wrapper\n    #[error(\"{0}\")]\n    IoError(#[from] io::Error),\n    /// rocksdb::Error\n    #[error(\"{0}\")]\n    RocksDBError(#[from] rocksdb::Error),\n}\n\nimpl From<FakeDnsError> for io::Error {\n    fn from(value: FakeDnsError) -> Self {\n        match value {\n            FakeDnsError::IoError(e) => e,\n            FakeDnsError::RocksDBError(e) => Self::other(e),\n        }\n    }\n}\n\n/// FakeDns Api Result type\npub type FakeDnsResult<T> = Result<T, FakeDnsError>;\n\n/// Fake DNS manager\npub struct FakeDnsManager {\n    db: Mutex<RocksDB>,\n    ipv4_network: Mutex<Cycle<Ipv4AddrRange>>,\n    ipv6_network: Mutex<Cycle<Ipv6AddrRange>>,\n    expire_duration: Duration,\n}\n\nmacro_rules! map_domain_ip {\n    ($self:ident, $domain:ident, $addr_ty:ty, $addr_field:ident, $network_field:ident) => {{\n        let db = $self.db.lock().await;\n        let name2ip_key = FakeDnsManager::get_name2ip_key($domain);\n\n        loop {\n            let mut domain_name_mapping = proto::DomainNameMapping::default();\n\n            if let Some(v) = db.get(&name2ip_key)? {\n                domain_name_mapping = proto::DomainNameMapping::decode(&v)?;\n\n                if !domain_name_mapping.$addr_field.is_empty() {\n                    match domain_name_mapping.$addr_field.parse::<$addr_ty>() {\n                        Ok(i) => {\n                            let now = FakeDnsManager::get_current_timestamp();\n                            let expire_secs =\n                                FakeDnsManager::get_current_timestamp() + $self.expire_duration.as_secs() as i64;\n\n                            if domain_name_mapping.expire_time >= now {\n                                // Not expired yet.\n                                domain_name_mapping.expire_time = expire_secs;\n                                let nv = domain_name_mapping.encode_to_vec()?;\n\n                                db.put(&name2ip_key, nv)?;\n                                trace!(\n                                    \"fakedns mapping {} -> {}, expires {}\",\n                                    $domain, i, domain_name_mapping.expire_time\n                                );\n                                return Ok((i, $self.expire_duration));\n                            } else {\n                                // Expired. Try to reuse.\n\n                                let ip2name_key = FakeDnsManager::get_ip2name_key(i.into());\n                                if let Some(v) = db.get(&ip2name_key)? {\n                                    let mut ip_mapping = proto::IpAddrMapping::decode(&v)?;\n                                    if ip_mapping.domain_name == $domain.to_string() {\n                                        // Try to extend its expire time\n                                        ip_mapping.expire_time = expire_secs;\n                                        let nv = ip_mapping.encode_to_vec()?;\n\n                                        db.put(&ip2name_key, nv)?;\n                                        trace!(\n                                            \"fakedns mapping {} -> {}, expires {}\",\n                                            $domain, i, domain_name_mapping.expire_time\n                                        );\n                                        return Ok((i, $self.expire_duration));\n                                    }\n                                }\n                            }\n                        }\n                        Err(..) => {\n                            warn!(\"failed to parse {}, going to replace\", domain_name_mapping.$addr_field);\n                        }\n                    }\n                }\n            }\n\n            // Allocate a new IPv4 address for this domain\n            while let Some(ip) = $self.$network_field.lock().await.next() {\n                let ip2name_key = FakeDnsManager::get_ip2name_key(ip.into());\n\n                if let Some(v) = db.get(&ip2name_key)? {\n                    let ip_mapping = proto::IpAddrMapping::decode(&v)?;\n\n                    let now = FakeDnsManager::get_current_timestamp();\n                    if ip_mapping.expire_time > now {\n                        continue;\n                    }\n                }\n\n                let mut ip_mapping = proto::IpAddrMapping::default();\n\n                let expire_secs = FakeDnsManager::get_current_timestamp() + $self.expire_duration.as_secs() as i64;\n                ip_mapping.expire_time = expire_secs;\n                ip_mapping.domain_name = $domain.to_string();\n\n                let nv = ip_mapping.encode_to_vec()?;\n\n                db.put(&ip2name_key, nv)?;\n                // Replace name2ip\n\n                domain_name_mapping.$addr_field = ip.to_string();\n                domain_name_mapping.expire_time = ip_mapping.expire_time;\n                let nv = domain_name_mapping.encode_to_vec()?;\n\n                db.put(&name2ip_key, nv)?;\n                trace!(\n                    \"fakedns mapping {} -> {}, expires {} created\",\n                    $domain, ip, domain_name_mapping.expire_time\n                );\n\n                return Ok((ip, $self.expire_duration));\n            }\n        }\n    }};\n}\n\nimpl FakeDnsManager {\n    pub fn open<P: AsRef<Path>>(\n        db_path: P,\n        ipv4_network: Ipv4Net,\n        ipv6_network: Ipv6Net,\n        expire_duration: Duration,\n    ) -> FakeDnsResult<Self> {\n        let db_path = db_path.as_ref();\n\n        // https://github.com/facebook/rocksdb/wiki/Setup-Options-and-Basic-Tuning\n        let mut db_options = rocksdb::Options::default();\n        db_options.create_if_missing(true);\n        db_options.set_compression_type(rocksdb::DBCompressionType::Zstd);\n        db_options.set_bottommost_compression_type(rocksdb::DBCompressionType::Zstd);\n        db_options.set_bottommost_zstd_max_train_bytes(0, true);\n        db_options.set_max_background_jobs(6);\n        db_options.set_bytes_per_sync(1048576);\n        db_options.set_compaction_pri(rocksdb::CompactionPri::MinOverlappingRatio);\n        let mut db = match RocksDB::open(&db_options, db_path) {\n            Ok(db) => db,\n            Err(err) => {\n                error!(\"failed to open rocksdb, path: {}, error: {}\", db_path.display(), err);\n                return Err(err.into());\n            }\n        };\n\n        let ipv4_network_str = ipv4_network.to_string();\n        let ipv6_network_str = ipv6_network.to_string();\n\n        let mut recreate_database = true;\n\n        let key = \"shadowsocks_fakedns_meta\";\n        match db.get(key) {\n            Ok(Some(v)) => {\n                if let Ok(c) = proto::StorageMeta::decode(&v) {\n                    if c.version == FAKE_DNS_MANAGER_STORAGE_VERSION {\n                        if ipv4_network_str != c.ipv4_network || ipv6_network_str != c.ipv6_network {\n                            warn!(\n                                \"IPv4 network {} (storage {}), IPv6 network {} (storage {}) not match\",\n                                ipv4_network_str, c.ipv4_network, ipv6_network_str, c.ipv6_network\n                            );\n                        } else {\n                            recreate_database = false;\n                        }\n                    } else {\n                        warn!(\"storage version {} not match, recreating database\", c.version);\n                    }\n                } else {\n                    warn!(\"storage meta parse failed. recreating database\");\n                }\n            }\n            Ok(None) => {\n                // New DB without an META\n            }\n            Err(err) => {\n                error!(\"failed to get {}, error: {}\", key, err);\n                return Err(err.into());\n            }\n        }\n\n        if recreate_database {\n            drop(db);\n            let _ = RocksDB::destroy(&db_options, db_path);\n\n            // Re-create by Open\n            db = match RocksDB::open(&db_options, db_path) {\n                Ok(db) => db,\n                Err(err) => {\n                    error!(\n                        \"failed to recreate rocksdb, path: {}, error: {}\",\n                        db_path.display(),\n                        err\n                    );\n                    return Err(err.into());\n                }\n            };\n\n            let c = proto::StorageMeta {\n                ipv4_network: ipv4_network_str,\n                ipv6_network: ipv6_network_str,\n                version: FAKE_DNS_MANAGER_STORAGE_VERSION,\n            };\n\n            let v = c.encode_to_vec()?;\n            if let Err(err) = db.put(key, v) {\n                error!(\"failed to init storage, key: {}, error: {}\", key, err);\n                return Err(err.into());\n            }\n\n            trace!(\"FakeDNS database created. {:?}\", c);\n        }\n\n        Ok(Self {\n            db: Mutex::new(db),\n            ipv4_network: Mutex::new(ipv4_network.hosts().cycle()),\n            ipv6_network: Mutex::new(ipv6_network.hosts().cycle()),\n            expire_duration,\n        })\n    }\n\n    #[inline]\n    fn get_current_timestamp() -> i64 {\n        SystemTime::now()\n            .duration_since(SystemTime::UNIX_EPOCH)\n            .expect(\"SystemTime\")\n            .as_secs() as i64\n    }\n\n    #[inline]\n    fn get_name2ip_key(domain: &Name) -> String {\n        format!(\"shadowsocks_fakedns_name2ip_{domain}\")\n    }\n\n    #[inline]\n    fn get_ip2name_key(ip: IpAddr) -> String {\n        format!(\"shadowsocks_fakedns_ip2name_{ip}\")\n    }\n\n    /// Get or create an IPv4 mapping for `domain`\n    pub async fn map_domain_ipv4(&self, domain: &Name) -> FakeDnsResult<(Ipv4Addr, Duration)> {\n        map_domain_ip!(self, domain, Ipv4Addr, ipv4_addr, ipv4_network)\n    }\n\n    /// Get or create an IPv6 mapping for `domain`\n    pub async fn map_domain_ipv6(&self, domain: &Name) -> FakeDnsResult<(Ipv6Addr, Duration)> {\n        map_domain_ip!(self, domain, Ipv6Addr, ipv6_addr, ipv6_network)\n    }\n\n    /// Get IP mapped domain name\n    pub async fn map_ip_domain(&self, ip: IpAddr) -> FakeDnsResult<Option<Name>> {\n        let db = self.db.lock().await;\n\n        // ip -> domain_name\n        let ip2name_key = Self::get_ip2name_key(ip);\n        match db.get(&ip2name_key)? {\n            None => Ok(None),\n            Some(v) => {\n                // Got ip -> domain_name\n\n                let mut ip_mapping = proto::IpAddrMapping::decode(&v)?;\n                let now = Self::get_current_timestamp();\n                if ip_mapping.expire_time >= now {\n                    // Ok. It is not expired yet. Try to extend its expire time.\n                    ip_mapping.expire_time = now + self.expire_duration.as_secs() as i64;\n                    let nv = ip_mapping.encode_to_vec()?;\n                    db.put(&ip2name_key, nv)?;\n\n                    // Update name2ip's expire time\n\n                    let name = match ip_mapping.domain_name.parse::<Name>() {\n                        Ok(n) => n,\n                        Err(..) => return Ok(None),\n                    };\n\n                    {\n                        let name2ip_key = Self::get_name2ip_key(&name);\n                        match db.get(&name2ip_key)? {\n                            Some(v) => {\n                                let mut domain_name_mapping = proto::DomainNameMapping::decode(&v)?;\n                                domain_name_mapping.expire_time = ip_mapping.expire_time;\n                                let nv = domain_name_mapping.encode_to_vec()?;\n                                db.put(&name2ip_key, nv)?;\n                            }\n                            None => {\n                                // Interesting. No name2ip.\n                                return Ok(None);\n                            }\n                        }\n                    }\n\n                    Ok(Some(name))\n                } else {\n                    Ok(None)\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/fake_dns/mod.rs",
    "content": "//! Fake DNS\n//!\n//! Start a DNS resolver server, mapping requested names to local private network addresses.\n//! When local server receives proxy request with those mapped addresses, it could translate\n//! it back to the original domain names.\n//!\n//! It normally cooperates with `local-redir` and `local-tun`.\n\npub use self::server::{FakeDns, FakeDnsBuilder};\n\npub mod manager;\nmod processor;\nmod proto;\npub mod server;\nmod tcp_server;\nmod udp_server;\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/fake_dns/processor.rs",
    "content": "//! DNS request processor\n\nuse std::io;\n\nuse hickory_resolver::proto::{\n    op::{Header, Message, OpCode, header::MessageType, response_code::ResponseCode},\n    rr::{\n        DNSClass, RData, Record, RecordType,\n        rdata::{A, AAAA},\n    },\n};\nuse log::{debug, trace, warn};\n\nuse super::manager::FakeDnsManager;\n\npub async fn handle_dns_request(req_message: &Message, manager: &FakeDnsManager) -> io::Result<Message> {\n    let mut rsp_message = Message::new();\n    let rsp_header = Header::response_from_request(req_message.header());\n    rsp_message.set_header(rsp_header);\n\n    if req_message.op_code() != OpCode::Query || req_message.message_type() != MessageType::Query {\n        rsp_message.set_response_code(ResponseCode::NotImp);\n    } else {\n        for query in req_message.queries() {\n            // Copy all the queries into response.\n            rsp_message.add_query(query.clone());\n\n            if query.query_class() != DNSClass::IN {\n                // let record = Record::<RData>::from_rdata(query.name().clone(), 0, query.query_type());\n                // rsp_message.add_answer(record);\n                warn!(\n                    \"Query class: {:?} is not supported. Full {:?}\",\n                    query.query_class(),\n                    req_message\n                );\n                continue;\n            }\n\n            match query.query_type() {\n                RecordType::A => {\n                    let (ip_addr, expire_duration) = manager.map_domain_ipv4(query.name()).await?;\n\n                    let mut record = Record::<RData>::from_rdata(\n                        query.name().clone(),\n                        expire_duration.as_secs() as u32,\n                        RData::A(A(ip_addr)),\n                    );\n                    record.set_dns_class(query.query_class());\n                    rsp_message.add_answer(record);\n                }\n                RecordType::AAAA => {\n                    let (ip_addr, expire_duration) = manager.map_domain_ipv6(query.name()).await?;\n\n                    let mut record = Record::<RData>::from_rdata(\n                        query.name().clone(),\n                        expire_duration.as_secs() as u32,\n                        RData::AAAA(AAAA(ip_addr)),\n                    );\n                    record.set_dns_class(query.query_class());\n                    rsp_message.add_answer(record);\n                }\n                _ => {\n                    debug!(\"fakedns {} not supported. {:?}\", query.query_type(), query);\n                }\n            }\n        }\n    }\n\n    trace!(\"QUERY {:?} ANSWER {:?}\", req_message, rsp_message);\n\n    Ok(rsp_message)\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/fake_dns/proto.rs",
    "content": "//! Data representation in Database\n\nuse std::io;\n\nuse serde::{Deserialize, Serialize};\n\n#[derive(Serialize, Deserialize, Default, Clone, Debug)]\npub struct StorageMeta {\n    pub ipv4_network: String,\n    pub ipv6_network: String,\n    pub version: u32,\n}\n\nimpl StorageMeta {\n    pub fn decode(v: &[u8]) -> io::Result<Self> {\n        bson::deserialize_from_slice(v).map_err(io::Error::other)\n    }\n\n    pub fn encode_to_vec(&self) -> io::Result<Vec<u8>> {\n        bson::serialize_to_vec(self).map_err(io::Error::other)\n    }\n}\n\n#[derive(Serialize, Deserialize, Default, Clone, Debug)]\npub struct IpAddrMapping {\n    pub domain_name: String,\n    pub expire_time: i64,\n}\n\nimpl IpAddrMapping {\n    pub fn decode(v: &[u8]) -> io::Result<Self> {\n        bson::deserialize_from_slice(v).map_err(io::Error::other)\n    }\n\n    pub fn encode_to_vec(&self) -> io::Result<Vec<u8>> {\n        bson::serialize_to_vec(self).map_err(io::Error::other)\n    }\n}\n\n#[derive(Serialize, Deserialize, Default, Clone, Debug)]\npub struct DomainNameMapping {\n    pub ipv4_addr: String,\n    pub ipv6_addr: String,\n    pub expire_time: i64,\n}\n\nimpl DomainNameMapping {\n    pub fn decode(v: &[u8]) -> io::Result<Self> {\n        bson::deserialize_from_slice(v).map_err(io::Error::other)\n    }\n\n    pub fn encode_to_vec(&self) -> io::Result<Vec<u8>> {\n        bson::serialize_to_vec(self).map_err(io::Error::other)\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/fake_dns/server.rs",
    "content": "//! Fake DNS server\n\nuse std::{\n    io,\n    net::{Ipv4Addr, Ipv6Addr},\n    path::{Path, PathBuf},\n    sync::Arc,\n    time::Duration,\n};\n\nuse futures::{FutureExt, future};\nuse ipnet::{Ipv4Net, Ipv6Net};\nuse shadowsocks::config::{Mode, ServerAddr};\n\nuse crate::local::context::ServiceContext;\n\nuse super::{manager::FakeDnsManager, tcp_server::FakeDnsTcpServer, udp_server::FakeDnsUdpServer};\n\n/// Fake DNS builder\npub struct FakeDnsBuilder {\n    context: Arc<ServiceContext>,\n    mode: Mode,\n    client_addr: ServerAddr,\n    database_path: PathBuf,\n    ipv4_network: Ipv4Net,\n    ipv6_network: Ipv6Net,\n    expire_duration: Duration,\n}\n\nimpl FakeDnsBuilder {\n    /// Create a new Fake DNS server\n    pub fn new(client_addr: ServerAddr) -> Self {\n        let context = ServiceContext::new();\n        Self::with_context(Arc::new(context), client_addr)\n    }\n\n    /// Create a new Fake DNS server with context\n    pub fn with_context(context: Arc<ServiceContext>, client_addr: ServerAddr) -> Self {\n        Self {\n            context,\n            mode: Mode::TcpAndUdp,\n            client_addr,\n            database_path: \"shadowsocks-fakedns.sled\".into(),\n            ipv4_network: Ipv4Net::new(Ipv4Addr::new(172, 16, 0, 0), 12).unwrap(),\n            ipv6_network: Ipv6Net::new(Ipv6Addr::new(0xfc00, 0, 0, 0, 0, 0, 0, 0), 7).unwrap(),\n            expire_duration: Duration::from_secs(10),\n        }\n    }\n\n    /// Set IPv4 network\n    pub fn set_ipv4_network(&mut self, ipv4_network: Ipv4Net) {\n        self.ipv4_network = ipv4_network;\n    }\n\n    /// Set IPv6 network\n    pub fn set_ipv6_network(&mut self, ipv6_network: Ipv6Net) {\n        self.ipv6_network = ipv6_network;\n    }\n\n    /// Set expire duration\n    pub fn set_expire_duration(&mut self, expire: Duration) {\n        self.expire_duration = expire;\n    }\n\n    /// Set database path\n    pub fn set_database_path<P: AsRef<Path>>(&mut self, database_path: P) {\n        self.database_path = database_path.as_ref().to_path_buf();\n    }\n\n    /// Build Fake DNS server\n    pub async fn build(self) -> io::Result<FakeDns> {\n        let manager = FakeDnsManager::open(\n            &self.database_path,\n            self.ipv4_network,\n            self.ipv6_network,\n            self.expire_duration,\n        )?;\n        let manager = Arc::new(manager);\n\n        let mut tcp_server = None;\n        if self.mode.enable_tcp() {\n            let server = FakeDnsTcpServer::new(self.context.clone(), &self.client_addr, manager.clone()).await?;\n            tcp_server = Some(server);\n        }\n\n        let mut udp_server = None;\n        if self.mode.enable_udp() {\n            let server = FakeDnsUdpServer::new(self.context.clone(), &self.client_addr, manager.clone()).await?;\n            udp_server = Some(server);\n        }\n\n        Ok(FakeDns {\n            tcp_server,\n            udp_server,\n            manager,\n        })\n    }\n}\n\n/// Fake DNS server instance\npub struct FakeDns {\n    tcp_server: Option<FakeDnsTcpServer>,\n    udp_server: Option<FakeDnsUdpServer>,\n    manager: Arc<FakeDnsManager>,\n}\n\nimpl FakeDns {\n    /// TCP Server instance\n    pub fn tcp_server(&self) -> Option<&FakeDnsTcpServer> {\n        self.tcp_server.as_ref()\n    }\n\n    /// UDP Server instance\n    pub fn udp_server(&self) -> Option<&FakeDnsUdpServer> {\n        self.udp_server.as_ref()\n    }\n\n    /// Get the manager\n    pub fn clone_manager(&self) -> Arc<FakeDnsManager> {\n        self.manager.clone()\n    }\n\n    /// Run server\n    pub async fn run(self) -> io::Result<()> {\n        let mut vfut = Vec::new();\n\n        if let Some(tcp_server) = self.tcp_server {\n            vfut.push(tcp_server.run().boxed());\n        }\n\n        if let Some(udp_server) = self.udp_server {\n            vfut.push(udp_server.run().boxed());\n        }\n\n        let (res, ..) = future::select_all(vfut).await;\n        res\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/fake_dns/tcp_server.rs",
    "content": "//! Fake DNS TCP server\n\nuse std::{\n    io::{self, ErrorKind},\n    net::SocketAddr,\n    sync::Arc,\n    time::Duration,\n};\n\nuse byteorder::{BigEndian, ByteOrder};\nuse bytes::{BufMut, BytesMut};\nuse hickory_resolver::proto::{\n    op::{Message, response_code::ResponseCode},\n    serialize::binary::{BinEncodable, BinEncoder, EncodeMode},\n};\nuse log::{error, trace};\nuse shadowsocks::{ServerAddr, lookup_then, net::TcpListener as ShadowTcpListener};\nuse tokio::{\n    io::{AsyncReadExt, AsyncWriteExt},\n    net::TcpStream,\n    time,\n};\n\nuse crate::local::context::ServiceContext;\n\nuse super::{manager::FakeDnsManager, processor::handle_dns_request};\n\n/// Fake DNS TCP server\npub struct FakeDnsTcpServer {\n    context: Arc<ServiceContext>,\n    listener: ShadowTcpListener,\n    manager: Arc<FakeDnsManager>,\n}\n\nimpl FakeDnsTcpServer {\n    pub(crate) async fn new(\n        context: Arc<ServiceContext>,\n        client_config: &ServerAddr,\n        manager: Arc<FakeDnsManager>,\n    ) -> io::Result<Self> {\n        let listener = match *client_config {\n            ServerAddr::SocketAddr(ref saddr) => {\n                ShadowTcpListener::bind_with_opts(saddr, context.accept_opts()).await?\n            }\n            ServerAddr::DomainName(ref dname, port) => {\n                lookup_then!(context.context_ref(), dname, port, |addr| {\n                    ShadowTcpListener::bind_with_opts(&addr, context.accept_opts()).await\n                })?\n                .1\n            }\n        };\n\n        Ok(Self {\n            context,\n            listener,\n            manager,\n        })\n    }\n\n    /// Get TCP local address\n    pub fn local_addr(&self) -> io::Result<SocketAddr> {\n        self.listener.local_addr()\n    }\n\n    /// Run TCP server loop\n    pub async fn run(self) -> io::Result<()> {\n        loop {\n            let (stream, peer_addr) = match self.listener.accept().await {\n                Ok(s) => s,\n                Err(err) => {\n                    error!(\"failed to accept Fake DNS connection, err: {}\", err);\n                    time::sleep(Duration::from_secs(1)).await;\n                    continue;\n                }\n            };\n\n            trace!(\"Fake DNS accepted TCP client {}\", peer_addr);\n\n            let context = self.context.clone();\n            let manager = self.manager.clone();\n            tokio::spawn(async move {\n                if let Err(err) = Self::handle_client(context, peer_addr, stream, manager).await {\n                    error!(\n                        \"failed to handle Fake DNS tcp client, peer: {}, err: {}\",\n                        peer_addr, err\n                    );\n                }\n            });\n        }\n    }\n\n    async fn handle_client(\n        _context: Arc<ServiceContext>,\n        peer_addr: SocketAddr,\n        mut stream: TcpStream,\n        manager: Arc<FakeDnsManager>,\n    ) -> io::Result<()> {\n        let mut length_buf = [0u8; 2];\n        let mut message_buf = BytesMut::new();\n\n        loop {\n            match stream.read_exact(&mut length_buf).await {\n                Ok(..) => {}\n                Err(ref err) if err.kind() == ErrorKind::UnexpectedEof => {\n                    break;\n                }\n                Err(err) => {\n                    error!(\"udp tcp {} read length failed, error: {}\", peer_addr, err);\n                    return Err(err);\n                }\n            }\n\n            let length = BigEndian::read_u16(&length_buf) as usize;\n\n            message_buf.clear();\n            message_buf.reserve(length);\n            unsafe {\n                message_buf.advance_mut(length);\n            }\n\n            match stream.read_exact(&mut message_buf).await {\n                Ok(..) => {}\n                Err(err) => {\n                    error!(\"dns tcp {} read message failed, error: {}\", peer_addr, err);\n                    return Err(err);\n                }\n            }\n\n            let req_message = match Message::from_vec(&message_buf) {\n                Ok(m) => m,\n                Err(err) => {\n                    error!(\"dns tcp {} parse message failed, error: {}\", peer_addr, err);\n                    return Err(err.into());\n                }\n            };\n\n            let rsp_message = match handle_dns_request(&req_message, &manager).await {\n                Ok(m) => m,\n                Err(err) => {\n                    error!(\"failed to handle DNS request, error: {}\", err);\n\n                    Message::error_msg(req_message.id(), req_message.op_code(), ResponseCode::ServFail)\n                }\n            };\n\n            let mut rsp_buffer = Vec::with_capacity(2 + 512);\n            rsp_buffer.resize(2, 0);\n            let mut rsp_encoder = BinEncoder::with_offset(&mut rsp_buffer, 2, EncodeMode::Normal);\n            rsp_message.emit(&mut rsp_encoder)?;\n\n            let rsp_length = (rsp_buffer.len() - 2) as u16;\n            BigEndian::write_u16(&mut rsp_buffer[0..2], rsp_length);\n\n            stream.write_all(&rsp_buffer).await?;\n        }\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/fake_dns/udp_server.rs",
    "content": "//! Fake DNS UDP server\n\nuse std::{io, net::SocketAddr, sync::Arc, time::Duration};\n\nuse hickory_resolver::proto::op::{Message, response_code::ResponseCode};\nuse log::error;\nuse shadowsocks::{ServerAddr, lookup_then, net::UdpSocket as ShadowUdpSocket};\nuse tokio::time;\n\nuse crate::local::context::ServiceContext;\n\nuse super::{manager::FakeDnsManager, processor::handle_dns_request};\n\n/// Fake DNS UDP server instance\npub struct FakeDnsUdpServer {\n    listener: ShadowUdpSocket,\n    manager: Arc<FakeDnsManager>,\n}\n\nimpl FakeDnsUdpServer {\n    pub(crate) async fn new(\n        context: Arc<ServiceContext>,\n        client_config: &ServerAddr,\n        manager: Arc<FakeDnsManager>,\n    ) -> io::Result<Self> {\n        let listener = match *client_config {\n            ServerAddr::SocketAddr(ref saddr) => {\n                ShadowUdpSocket::listen_with_opts(saddr, context.accept_opts()).await?\n            }\n            ServerAddr::DomainName(ref dname, port) => {\n                lookup_then!(context.context_ref(), dname, port, |addr| {\n                    ShadowUdpSocket::listen_with_opts(&addr, context.accept_opts()).await\n                })?\n                .1\n            }\n        };\n\n        Ok(Self { listener, manager })\n    }\n\n    /// Get UDP local address\n    pub fn local_addr(&self) -> io::Result<SocketAddr> {\n        self.listener.local_addr()\n    }\n\n    /// Start server accept loop\n    pub async fn run(self) -> io::Result<()> {\n        let mut buffer = [0u8; 65535];\n        loop {\n            let (n, peer_addr) = match self.listener.recv_from(&mut buffer).await {\n                Ok(n) => n,\n                Err(err) => {\n                    error!(\"fakedns UDP recv_from failed, error: {}\", err);\n                    time::sleep(Duration::from_secs(1)).await;\n                    continue;\n                }\n            };\n\n            let req_message = match Message::from_vec(&buffer[..n]) {\n                Ok(m) => m,\n                Err(err) => {\n                    error!(\"failed to parse DNS request, error: {}\", err);\n                    continue;\n                }\n            };\n\n            let rsp_message = match handle_dns_request(&req_message, &self.manager).await {\n                Ok(m) => m,\n                Err(err) => {\n                    error!(\"failed to handle DNS request, error: {}\", err);\n\n                    Message::error_msg(req_message.id(), req_message.op_code(), ResponseCode::ServFail)\n                }\n            };\n\n            let rsp_buffer = rsp_message.to_vec()?;\n            let _ = self.listener.send_to(&rsp_buffer, peer_addr).await;\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/http/config.rs",
    "content": "//! HTTP protocol configuration\n\nuse std::{\n    collections::HashMap,\n    fs::OpenOptions,\n    io::{self, Read},\n    path::Path,\n};\n\nuse base64::Engine as _;\nuse log::trace;\nuse serde::Deserialize;\n\nconst BASIC_AUTH_BASE64_ENGINE: base64::engine::GeneralPurpose = base64::engine::GeneralPurpose::new(\n    &base64::alphabet::STANDARD,\n    base64::engine::GeneralPurposeConfig::new()\n        .with_encode_padding(true)\n        .with_decode_padding_mode(base64::engine::DecodePaddingMode::Indifferent),\n);\n\n#[derive(Deserialize, Debug)]\nstruct SSHttpAuthBasicUserConfig {\n    user_name: String,\n    password: String,\n}\n\n#[derive(Deserialize, Debug)]\nstruct SSHttpAuthBasicConfig {\n    users: Vec<SSHttpAuthBasicUserConfig>,\n}\n\n#[derive(Deserialize, Debug)]\nstruct SSHttpAuthConfig {\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    basic: Option<SSHttpAuthBasicConfig>,\n}\n\n/// HTTP Authentication method\n#[derive(Debug, Clone)]\npub struct HttpAuthConfig {\n    pub basic: HttpAuthBasicConfig,\n}\n\nimpl HttpAuthConfig {\n    /// Create a new HTTP Authentication configuration\n    pub fn new() -> Self {\n        Self {\n            basic: HttpAuthBasicConfig::new(),\n        }\n    }\n\n    /// Load from configuration file\n    ///\n    /// ```json\n    /// {\n    ///     \"basic\": {\n    ///         \"users\": [\n    ///             {\n    ///                 \"user_name\": \"USER_NAME\",\n    ///                 \"password\": \"PASSWORD\"\n    ///             }\n    ///         ]\n    ///      }\n    /// }\n    pub fn load_from_file<P: AsRef<Path> + ?Sized>(filename: &P) -> io::Result<Self> {\n        let filename = filename.as_ref();\n\n        trace!(\n            \"loading socks5 authentication configuration from {}\",\n            filename.display()\n        );\n\n        let mut reader = OpenOptions::new().read(true).open(filename)?;\n        let mut content = String::new();\n        reader.read_to_string(&mut content)?;\n\n        let jconf: SSHttpAuthConfig = match json5::from_str(&content) {\n            Ok(c) => c,\n            Err(err) => return Err(io::Error::other(err)),\n        };\n\n        let mut basic = HttpAuthBasicConfig::new();\n        if let Some(p) = jconf.basic {\n            for user in p.users {\n                basic.add_user(user.user_name, user.password);\n            }\n        }\n\n        Ok(Self { basic })\n    }\n\n    /// Check if authentication is required\n    pub fn auth_required(&self) -> bool {\n        self.basic.total_users() > 0\n    }\n\n    /// Check Basic Authentication\n    pub fn verify_basic_auth(&self, header_value: &str) -> bool {\n        const BASIC_PREFIX: &str = \"Basic \";\n\n        if !header_value.starts_with(BASIC_PREFIX) {\n            return false;\n        }\n        let b64_encoded = &header_value[BASIC_PREFIX.len()..];\n        let decoded_bytes = match BASIC_AUTH_BASE64_ENGINE.decode(b64_encoded) {\n            Ok(b) => b,\n            Err(_) => return false,\n        };\n        let decoded_str = match String::from_utf8(decoded_bytes) {\n            Ok(s) => s,\n            Err(_) => return false,\n        };\n        let (user_name, password) = match decoded_str.split_once(':') {\n            Some((u, p)) => (u, p),\n            None => return false,\n        };\n        self.basic.check_user(user_name, password)\n    }\n}\n\nimpl Default for HttpAuthConfig {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\n/// HTTP server User/Password Authentication configuration\n///\n/// RFC9110 https://httpwg.org/specs/rfc9110.html#auth.client.proxy\n#[derive(Debug, Clone)]\npub struct HttpAuthBasicConfig {\n    users: HashMap<String, String>,\n}\n\nimpl HttpAuthBasicConfig {\n    /// Create an empty `Passwd` configuration\n    pub fn new() -> Self {\n        Self { users: HashMap::new() }\n    }\n\n    /// Add a user with password\n    pub fn add_user<U, P>(&mut self, user_name: U, password: P)\n    where\n        U: Into<String>,\n        P: Into<String>,\n    {\n        self.users.insert(user_name.into(), password.into());\n    }\n\n    /// Check if `user_name` exists and validate `password`\n    pub fn check_user<U, P>(&self, user_name: U, password: P) -> bool\n    where\n        U: AsRef<str>,\n        P: AsRef<str>,\n    {\n        match self.users.get(user_name.as_ref()) {\n            Some(pwd) => pwd == password.as_ref(),\n            None => false,\n        }\n    }\n\n    /// Total users\n    pub fn total_users(&self) -> usize {\n        self.users.len()\n    }\n}\n\nimpl Default for HttpAuthBasicConfig {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/http/http_client.rs",
    "content": "//! HTTP Client\n\nuse std::{\n    borrow::Cow,\n    collections::VecDeque,\n    fmt::Debug,\n    future::Future,\n    io::{self, ErrorKind},\n    pin::Pin,\n    sync::Arc,\n    task::{Context, Poll},\n    time::{Duration, Instant},\n};\n\nuse http::{HeaderValue, Method as HttpMethod, Uri, Version as HttpVersion, header::InvalidHeaderValue};\nuse hyper::{\n    Request, Response,\n    body::{self, Body},\n    client::conn::{TrySendError, http1, http2},\n    http::uri::Scheme,\n    rt::{Sleep, Timer},\n};\nuse log::{debug, error, trace};\nuse lru_time_cache::LruCache;\nuse pin_project::pin_project;\nuse shadowsocks::relay::Address;\nuse tokio::sync::Mutex;\n\nuse crate::local::{context::ServiceContext, loadbalancing::PingBalancer, net::AutoProxyClientStream};\n\nuse super::{\n    http_stream::ProxyHttpStream,\n    tokio_rt::{TokioExecutor, TokioIo},\n    utils::{check_keep_alive, connect_host, host_addr},\n};\n\nconst CONNECTION_EXPIRE_DURATION: Duration = Duration::from_secs(20);\n\n/// HTTPClient API request errors\n#[derive(thiserror::Error, Debug)]\npub enum HttpClientError {\n    /// Errors from hyper\n    #[error(\"{0}\")]\n    Hyper(#[from] hyper::Error),\n    /// std::io::Error\n    #[error(\"{0}\")]\n    Io(#[from] io::Error),\n    /// Errors from http\n    #[error(\"{0}\")]\n    Http(#[from] http::Error),\n    /// Errors from http header\n    #[error(\"{0}\")]\n    InvalidHeaderValue(#[from] InvalidHeaderValue),\n}\n\n#[allow(clippy::large_enum_variant)]\n#[derive(thiserror::Error, Debug)]\nenum SendRequestError<B> {\n    #[error(\"{0}\")]\n    Http(#[from] http::Error),\n\n    #[error(\"{0}\")]\n    TrySend(#[from] TrySendError<Request<B>>),\n}\n\n#[derive(Clone, Debug)]\npub struct TokioTimer;\n\nimpl Timer for TokioTimer {\n    fn sleep(&self, duration: Duration) -> Pin<Box<dyn Sleep>> {\n        Box::pin(TokioSleep {\n            inner: tokio::time::sleep(duration),\n        })\n    }\n\n    fn sleep_until(&self, deadline: Instant) -> Pin<Box<dyn Sleep>> {\n        Box::pin(TokioSleep {\n            inner: tokio::time::sleep_until(deadline.into()),\n        })\n    }\n\n    fn reset(&self, sleep: &mut Pin<Box<dyn Sleep>>, new_deadline: Instant) {\n        if let Some(sleep) = sleep.as_mut().downcast_mut_pin::<TokioSleep>() {\n            sleep.reset(new_deadline)\n        }\n    }\n}\n\n#[pin_project]\npub(crate) struct TokioSleep {\n    #[pin]\n    pub(crate) inner: tokio::time::Sleep,\n}\n\nimpl Future for TokioSleep {\n    type Output = ();\n\n    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {\n        self.project().inner.poll(cx)\n    }\n}\n\nimpl Sleep for TokioSleep {}\n\nimpl TokioSleep {\n    pub fn reset(self: Pin<&mut Self>, deadline: Instant) {\n        self.project().inner.as_mut().reset(deadline.into());\n    }\n}\n\n/// HTTPClient, supporting HTTP/1.1 and H2, HTTPS.\npub struct HttpClient<B> {\n    #[allow(clippy::type_complexity)]\n    cache_conn: Arc<Mutex<LruCache<Address, VecDeque<(HttpConnection<B>, Instant)>>>>,\n}\n\nimpl<B> Clone for HttpClient<B> {\n    fn clone(&self) -> Self {\n        Self {\n            cache_conn: self.cache_conn.clone(),\n        }\n    }\n}\n\nimpl<B> Default for HttpClient<B>\nwhere\n    B: Body + Send + Unpin + Debug + 'static,\n    B::Data: Send,\n    B::Error: Into<Box<dyn ::std::error::Error + Send + Sync>>,\n{\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nimpl<B> HttpClient<B>\nwhere\n    B: Body + Send + Unpin + Debug + 'static,\n    B::Data: Send,\n    B::Error: Into<Box<dyn ::std::error::Error + Send + Sync>>,\n{\n    /// Create a new HttpClient\n    pub fn new() -> Self {\n        Self {\n            cache_conn: Arc::new(Mutex::new(LruCache::with_expiry_duration(CONNECTION_EXPIRE_DURATION))),\n        }\n    }\n\n    /// Make HTTP requests\n    #[inline]\n    pub async fn send_request(\n        &self,\n        context: Arc<ServiceContext>,\n        req: Request<B>,\n        balancer: Option<&PingBalancer>,\n    ) -> Result<Response<body::Incoming>, HttpClientError> {\n        let host = match host_addr(req.uri()) {\n            Some(h) => h,\n            None => panic!(\"URI missing host: {}\", req.uri()),\n        };\n\n        // Set Host header if it was missing in the Request\n        let (mut req_parts, req_body) = req.into_parts();\n        if let Some(authority) = req_parts.uri.authority() {\n            let headers = &mut req_parts.headers;\n            if !headers.contains_key(\"Host\") {\n                let uri = &req_parts.uri;\n                let host_value = if (uri.scheme_str() == Some(\"http\")\n                    && matches!(authority.port_u16(), None | Some(80)))\n                    || (uri.scheme_str() == Some(\"https\") && matches!(authority.port_u16(), None | Some(443)))\n                {\n                    HeaderValue::from_str(authority.host())?\n                } else {\n                    HeaderValue::from_str(authority.as_str())?\n                };\n\n                headers.insert(\"Host\", host_value);\n            }\n        }\n        let mut req = Request::from_parts(req_parts, req_body);\n\n        // 1. Check if there is an available client\n        if let Some(c) = self.get_cached_connection(&host).await {\n            trace!(\"HTTP client for host: {} taken from cache\", host);\n            match self.send_request_conn(host.clone(), c, req).await {\n                Ok(response) => return Ok(response),\n                Err(SendRequestError::TrySend(mut err)) => {\n                    if let Some(inner_req) = err.take_message() {\n                        req = inner_req;\n\n                        // If TrySendError, the connection is probably broken, we should make a new connection\n                        debug!(\n                            \"failed to send request via cached connection to host: {}, error: {}. retry with a new connection\",\n                            host,\n                            err.error()\n                        );\n                    } else {\n                        error!(\n                            \"failed to send request via cached connection to host: {}, error: {}. no request to retry\",\n                            host,\n                            err.error()\n                        );\n                        return Err(err.into_error().into());\n                    }\n                }\n                Err(SendRequestError::Http(err)) => {\n                    error!(\n                        \"failed to send request via cached connection to host: {}, error: {}\",\n                        host, err\n                    );\n                    return Err(err.into());\n                }\n            }\n        }\n\n        // 2. If no. Make a new connection\n        let scheme = match req.uri().scheme() {\n            Some(s) => s,\n            None => &Scheme::HTTP,\n        };\n\n        let domain = match host {\n            Address::DomainNameAddress(ref domain, _) => Cow::Borrowed(domain.as_str()),\n            Address::SocketAddress(ref saddr) => Cow::Owned(saddr.ip().to_string()),\n        };\n\n        let c = match HttpConnection::connect(context.clone(), scheme, host.clone(), &domain, balancer).await {\n            Ok(c) => c,\n            Err(err) => {\n                error!(\"failed to connect to host: {}, error: {}\", host, err);\n                return Err(err.into());\n            }\n        };\n\n        match self.send_request_conn(host, c, req).await {\n            Ok(response) => Ok(response),\n            Err(SendRequestError::TrySend(err)) => Err(err.into_error().into()),\n            Err(SendRequestError::Http(err)) => Err(err.into()),\n        }\n    }\n\n    async fn get_cached_connection(&self, host: &Address) -> Option<HttpConnection<B>> {\n        if let Some(q) = self.cache_conn.lock().await.get_mut(host) {\n            while let Some((c, inst)) = q.pop_front() {\n                let now = Instant::now();\n                if now - inst >= CONNECTION_EXPIRE_DURATION {\n                    continue;\n                }\n                if c.is_closed() {\n                    continue;\n                }\n                if !c.is_ready() {\n                    continue;\n                }\n                return Some(c);\n            }\n        }\n        None\n    }\n\n    async fn send_request_conn(\n        &self,\n        host: Address,\n        mut c: HttpConnection<B>,\n        req: Request<B>,\n    ) -> Result<Response<body::Incoming>, SendRequestError<B>> {\n        trace!(\"HTTP making request to host: {}, request: {:?}\", host, req);\n        let response = c.send_request(req).await?;\n        trace!(\"HTTP received response from host: {}, response: {:?}\", host, response);\n\n        // Check keep-alive\n        if check_keep_alive(response.version(), response.headers(), false) {\n            trace!(\n                \"HTTP connection keep-alive for host: {}, response: {:?}\",\n                host, response\n            );\n            let cache_conn = self.cache_conn.clone();\n            tokio::spawn(async move {\n                match c.ready().await {\n                    Ok(_) => {\n                        trace!(\"HTTP connection for host: {host} is ready and will be cached\");\n                        cache_conn\n                            .lock()\n                            .await\n                            .entry(host)\n                            .or_insert_with(VecDeque::new)\n                            .push_back((c, Instant::now()));\n                    }\n                    Err(e) => {\n                        trace!(\"HTTP connection for host: {host}  failed to become ready: {}\", e);\n                    }\n                };\n            });\n        }\n\n        Ok(response)\n    }\n}\n\nenum HttpConnection<B> {\n    Http1(http1::SendRequest<B>),\n    Http2(http2::SendRequest<B>),\n}\n\nimpl<B> HttpConnection<B>\nwhere\n    B: Body + Send + Unpin + 'static,\n    B::Data: Send,\n    B::Error: Into<Box<dyn ::std::error::Error + Send + Sync>>,\n{\n    async fn connect(\n        context: Arc<ServiceContext>,\n        scheme: &Scheme,\n        host: Address,\n        domain: &str,\n        balancer: Option<&PingBalancer>,\n    ) -> io::Result<Self> {\n        if *scheme != Scheme::HTTP && *scheme != Scheme::HTTPS {\n            return Err(io::Error::new(ErrorKind::InvalidInput, \"invalid scheme\"));\n        }\n\n        let (stream, _) = connect_host(context, &host, balancer).await?;\n\n        if *scheme == Scheme::HTTP {\n            Self::connect_http_http1(scheme, host, stream).await\n        } else if *scheme == Scheme::HTTPS {\n            Self::connect_https(scheme, host, domain, stream).await\n        } else {\n            unreachable!()\n        }\n    }\n\n    async fn connect_http_http1(scheme: &Scheme, host: Address, stream: AutoProxyClientStream) -> io::Result<Self> {\n        trace!(\n            \"HTTP making new HTTP/1.1 connection to host: {}, scheme: {}\",\n            host, scheme\n        );\n\n        let stream = ProxyHttpStream::connect_http(stream);\n\n        // HTTP/1.x\n        let (send_request, connection) = match http1::Builder::new()\n            .preserve_header_case(true)\n            .title_case_headers(true)\n            .handshake(TokioIo::new(stream))\n            .await\n        {\n            Ok(s) => s,\n            Err(err) => return Err(io::Error::other(err)),\n        };\n\n        tokio::spawn(async move {\n            if let Err(err) = connection.await {\n                error!(\"HTTP/1.x connection to host: {} aborted with error: {}\", host, err);\n            }\n        });\n\n        Ok(Self::Http1(send_request))\n    }\n\n    async fn connect_https(\n        scheme: &Scheme,\n        host: Address,\n        domain: &str,\n        stream: AutoProxyClientStream,\n    ) -> io::Result<Self> {\n        trace!(\"HTTP making new TLS connection to host: {}, scheme: {}\", host, scheme);\n\n        // TLS handshake, check alpn for h2 support.\n        let stream = ProxyHttpStream::connect_https(stream, domain).await?;\n\n        if stream.negotiated_http2() {\n            // H2 connection\n            let (send_request, connection) = match http2::Builder::new(TokioExecutor)\n                .timer(TokioTimer)\n                .keep_alive_interval(Duration::from_secs(15))\n                .handshake(TokioIo::new(stream))\n                .await\n            {\n                Ok(s) => s,\n                Err(err) => return Err(io::Error::other(err)),\n            };\n\n            tokio::spawn(async move {\n                if let Err(err) = connection.await {\n                    error!(\"HTTP/2 TLS connection to host: {} aborted with error: {}\", host, err);\n                }\n            });\n\n            Ok(Self::Http2(send_request))\n        } else {\n            // HTTP/1.x TLS\n            let (send_request, connection) = match http1::Builder::new()\n                .preserve_header_case(true)\n                .title_case_headers(true)\n                .handshake(TokioIo::new(stream))\n                .await\n            {\n                Ok(s) => s,\n                Err(err) => return Err(io::Error::other(err)),\n            };\n\n            tokio::spawn(async move {\n                if let Err(err) = connection.await {\n                    error!(\"HTTP/1.x TLS connection to host: {} aborted with error: {}\", host, err);\n                }\n            });\n\n            Ok(Self::Http1(send_request))\n        }\n    }\n\n    #[inline]\n    pub async fn send_request(&mut self, mut req: Request<B>) -> Result<Response<body::Incoming>, SendRequestError<B>> {\n        match self {\n            Self::Http1(r) => {\n                if !matches!(\n                    req.version(),\n                    HttpVersion::HTTP_09 | HttpVersion::HTTP_10 | HttpVersion::HTTP_11\n                ) {\n                    trace!(\n                        \"HTTP client changed Request.version to HTTP/1.1 from {:?}\",\n                        req.version()\n                    );\n\n                    *req.version_mut() = HttpVersion::HTTP_11;\n                }\n\n                // Remove Scheme, Host part from URI\n                if req.method() != HttpMethod::CONNECT\n                    && (req.uri().scheme().is_some() || req.uri().authority().is_some())\n                {\n                    let mut builder = Uri::builder();\n                    match req.uri().path_and_query() {\n                        Some(path_and_query) => {\n                            builder = builder.path_and_query(path_and_query.as_str());\n                        }\n                        _ => {\n                            builder = builder.path_and_query(\"/\");\n                        }\n                    }\n                    *(req.uri_mut()) = builder.build()?;\n                }\n\n                r.try_send_request(req).await.map_err(Into::into)\n            }\n            Self::Http2(r) => {\n                if !matches!(req.version(), HttpVersion::HTTP_2) {\n                    trace!(\"HTTP client changed Request.version to HTTP/2 from {:?}\", req.version());\n\n                    *req.version_mut() = HttpVersion::HTTP_2;\n                }\n\n                r.try_send_request(req).await.map_err(Into::into)\n            }\n        }\n    }\n\n    pub fn is_closed(&self) -> bool {\n        match self {\n            Self::Http1(r) => r.is_closed(),\n            Self::Http2(r) => r.is_closed(),\n        }\n    }\n\n    pub fn is_ready(&self) -> bool {\n        match self {\n            Self::Http1(r) => r.is_ready(),\n            Self::Http2(r) => r.is_ready(),\n        }\n    }\n\n    pub async fn ready(&mut self) -> Result<(), hyper::Error> {\n        match self {\n            HttpConnection::Http1(r) => r.ready().await,\n            HttpConnection::Http2(r) => r.ready().await,\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/http/http_service.rs",
    "content": "//! Shadowsocks HTTP Proxy server dispatcher\n\nuse std::{net::SocketAddr, str::FromStr, sync::Arc};\n\nuse bytes::Bytes;\nuse http_body_util::{BodyExt, combinators::BoxBody};\nuse hyper::{\n    HeaderMap, Method, Request, Response, StatusCode, Uri, Version, body,\n    header::{self, HeaderValue},\n    http::uri::{Authority, Scheme},\n};\nuse log::{debug, error, trace};\nuse shadowsocks::relay::Address;\n\nuse crate::local::{\n    context::ServiceContext,\n    http::{http_client::HttpClientError, tokio_rt::TokioIo},\n    loadbalancing::PingBalancer,\n    net::AutoProxyIo,\n    utils::{establish_tcp_tunnel, establish_tcp_tunnel_bypassed},\n};\n\nuse super::{\n    config::HttpAuthConfig,\n    http_client::HttpClient,\n    utils::{authority_addr, check_keep_alive, connect_host, host_addr},\n};\n\npub struct HttpService {\n    context: Arc<ServiceContext>,\n    peer_addr: SocketAddr,\n    http_client: HttpClient<body::Incoming>,\n    balancer: PingBalancer,\n    http_auth: Arc<HttpAuthConfig>,\n}\n\nimpl HttpService {\n    pub fn new(\n        context: Arc<ServiceContext>,\n        peer_addr: SocketAddr,\n        http_client: HttpClient<body::Incoming>,\n        balancer: PingBalancer,\n        http_auth: Arc<HttpAuthConfig>,\n    ) -> Self {\n        Self {\n            context,\n            peer_addr,\n            http_client,\n            balancer,\n            http_auth,\n        }\n    }\n\n    pub async fn serve_connection(\n        self,\n        mut req: Request<body::Incoming>,\n    ) -> hyper::Result<Response<BoxBody<Bytes, hyper::Error>>> {\n        trace!(\"request {} {:?}\", self.peer_addr, req);\n\n        if self.http_auth.auth_required() {\n            // Only support Basic authentication for now\n            match req.headers().get(header::PROXY_AUTHORIZATION) {\n                Some(header_value) => {\n                    if let Ok(header_str) = header_value.to_str() {\n                        if !self.http_auth.verify_basic_auth(header_str) {\n                            error!(\n                                \"HTTP {} URI {} invalid proxy-authorization: {}\",\n                                req.method(),\n                                req.uri(),\n                                header_str\n                            );\n                            return make_proxy_authentication_required();\n                        }\n                    } else {\n                        error!(\n                            \"HTTP {} URI {} invalid proxy-authorization header encoding: {:?}\",\n                            req.method(),\n                            req.uri(),\n                            header_value\n                        );\n                        return make_proxy_authentication_required();\n                    }\n                }\n                None => {\n                    error!(\"HTTP {} URI {} missing proxy-authorization\", req.method(), req.uri());\n                    return make_proxy_authentication_required();\n                }\n            }\n        }\n\n        // Parse URI\n        //\n        // Proxy request URI must contains a host\n        let host = match host_addr(req.uri()) {\n            None => {\n                if req.uri().authority().is_some() {\n                    // URI has authority but invalid\n                    error!(\"HTTP {} URI {} doesn't have a valid host\", req.method(), req.uri());\n                    return make_bad_request();\n                } else {\n                    trace!(\"HTTP {} URI {} doesn't have a valid host\", req.method(), req.uri());\n                }\n\n                match get_addr_from_header(&mut req) {\n                    Ok(h) => h,\n                    Err(()) => return make_bad_request(),\n                }\n            }\n            Some(h) => h,\n        };\n\n        if req.method() == Method::CONNECT {\n            // Establish a TCP tunnel\n            // https://tools.ietf.org/html/draft-luotonen-web-proxy-tunneling-01\n\n            debug!(\"HTTP CONNECT {}\", host);\n\n            // Connect to Shadowsocks' remote\n            //\n            // FIXME: What STATUS should I return for connection error?\n            let (mut stream, server_opt) = match connect_host(self.context, &host, Some(&self.balancer)).await {\n                Ok(s) => s,\n                Err(err) => {\n                    error!(\"failed to CONNECT host: {}, error: {}\", host, err);\n                    return make_internal_server_error();\n                }\n            };\n\n            debug!(\n                \"CONNECT relay connected {} <-> {} ({})\",\n                self.peer_addr,\n                host,\n                if stream.is_bypassed() { \"bypassed\" } else { \"proxied\" }\n            );\n\n            let client_addr = self.peer_addr;\n            tokio::spawn(async move {\n                match hyper::upgrade::on(req).await {\n                    Ok(upgraded) => {\n                        trace!(\"CONNECT tunnel upgrade success, {} <-> {}\", client_addr, host);\n\n                        let mut upgraded_io = TokioIo::new(upgraded);\n\n                        let _ = match server_opt {\n                            Some(server) => {\n                                establish_tcp_tunnel(\n                                    server.server_config(),\n                                    &mut upgraded_io,\n                                    &mut stream,\n                                    client_addr,\n                                    &host,\n                                )\n                                .await\n                            }\n                            None => {\n                                establish_tcp_tunnel_bypassed(&mut upgraded_io, &mut stream, client_addr, &host).await\n                            }\n                        };\n                    }\n                    Err(err) => {\n                        error!(\"failed to upgrade CONNECT request, error: {}\", err);\n                    }\n                }\n            });\n\n            return Ok(Response::new(empty_body()));\n        }\n\n        // Traditional HTTP Proxy request\n\n        let method = req.method().clone();\n        let version = req.version();\n        debug!(\"HTTP {} {} {:?}\", method, host, version);\n\n        // Check if client wants us to keep long connection\n        let conn_keep_alive = check_keep_alive(version, req.headers(), true);\n\n        // Remove non-forwardable headers\n        clear_hop_headers(req.headers_mut());\n\n        // Set keep-alive for connection with remote\n        set_conn_keep_alive(version, req.headers_mut(), conn_keep_alive);\n\n        let mut res = match self\n            .http_client\n            .send_request(self.context, req, Some(&self.balancer))\n            .await\n        {\n            Ok(resp) => resp,\n            Err(HttpClientError::Hyper(e)) => return Err(e),\n            Err(HttpClientError::Io(err)) => {\n                error!(\"failed to make request to host: {}, error: {}\", host, err);\n                return make_internal_server_error();\n            }\n            Err(HttpClientError::Http(err)) => {\n                error!(\"failed to make request to host: {}, error: {}\", host, err);\n                return make_bad_request();\n            }\n            Err(HttpClientError::InvalidHeaderValue(err)) => {\n                error!(\"failed to make request to host: {}, error: {}\", host, err);\n                return make_bad_request();\n            }\n        };\n\n        trace!(\"received {} <- {} {:?}\", self.peer_addr, host, res);\n\n        let res_keep_alive = conn_keep_alive && check_keep_alive(res.version(), res.headers(), false);\n\n        // Clear unforwardable headers\n        clear_hop_headers(res.headers_mut());\n\n        if res.version() != version {\n            // Reset version to matches req's version\n            trace!(\"response version {:?} => {:?}\", res.version(), version);\n            *res.version_mut() = version;\n        }\n\n        // Set Connection header\n        set_conn_keep_alive(res.version(), res.headers_mut(), res_keep_alive);\n\n        trace!(\"response {} <- {} {:?}\", self.peer_addr, host, res);\n\n        debug!(\"HTTP {} relay {} <-> {} finished\", method, self.peer_addr, host);\n\n        Ok(res.map(|b| b.boxed()))\n    }\n}\n\nfn empty_body() -> BoxBody<Bytes, hyper::Error> {\n    http_body_util::Empty::<Bytes>::new()\n        .map_err(|never| match never {})\n        .boxed()\n}\n\nfn make_bad_request() -> Result<Response<BoxBody<Bytes, hyper::Error>>, hyper::Error> {\n    Ok(Response::builder()\n        .status(StatusCode::BAD_REQUEST)\n        .body(empty_body())\n        .unwrap())\n}\n\nfn make_proxy_authentication_required() -> Result<Response<BoxBody<Bytes, hyper::Error>>, hyper::Error> {\n    Ok(Response::builder()\n        .status(StatusCode::PROXY_AUTHENTICATION_REQUIRED)\n        .header(header::PROXY_AUTHENTICATE, \"Basic charset=\\\"UTF-8\\\"\")\n        .body(empty_body())\n        .unwrap())\n}\n\nfn make_internal_server_error() -> Result<Response<BoxBody<Bytes, hyper::Error>>, hyper::Error> {\n    Ok(Response::builder()\n        .status(StatusCode::INTERNAL_SERVER_ERROR)\n        .body(empty_body())\n        .unwrap())\n}\n\nfn get_extra_headers(headers: header::GetAll<HeaderValue>) -> Vec<String> {\n    let mut extra_headers = Vec::new();\n    for connection in headers {\n        if let Ok(conn) = connection.to_str() {\n            // close is a command instead of a header\n            if conn.eq_ignore_ascii_case(\"close\") {\n                continue;\n            }\n            for header in conn.split(',') {\n                let header = header.trim();\n                extra_headers.push(header.to_owned());\n            }\n        }\n    }\n    extra_headers\n}\n\nfn clear_hop_headers(headers: &mut HeaderMap<HeaderValue>) {\n    // Clear headers indicated by Connection and Proxy-Connection\n    let mut extra_headers = get_extra_headers(headers.get_all(\"Connection\"));\n    extra_headers.extend(get_extra_headers(headers.get_all(\"Proxy-Connection\")));\n\n    for header in extra_headers {\n        while headers.remove(&header).is_some() {}\n    }\n\n    // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Connection\n    const HOP_BY_HOP_HEADERS: [&str; 9] = [\n        \"Keep-Alive\",\n        \"Transfer-Encoding\",\n        \"TE\",\n        \"Connection\",\n        \"Trailer\",\n        \"Upgrade\",\n        \"Proxy-Authorization\",\n        \"Proxy-Authenticate\",\n        \"Proxy-Connection\", // Not standard, but many implementations do send this header\n    ];\n\n    for header in &HOP_BY_HOP_HEADERS {\n        while headers.remove(*header).is_some() {}\n    }\n}\n\nfn set_conn_keep_alive(version: Version, headers: &mut HeaderMap<HeaderValue>, keep_alive: bool) {\n    match version {\n        Version::HTTP_09 | Version::HTTP_10 => {\n            // HTTP/1.0 close connection by default\n            if keep_alive {\n                headers.insert(\"Connection\", HeaderValue::from_static(\"keep-alive\"));\n            }\n        }\n        _ => {\n            // HTTP/1.1, HTTP/2, HTTP/3 keep-alive connection by default\n            if !keep_alive {\n                headers.insert(\"Connection\", HeaderValue::from_static(\"close\"));\n            }\n        }\n    }\n}\n\nfn get_addr_from_header(req: &mut Request<body::Incoming>) -> Result<Address, ()> {\n    // Try to be compatible as a transparent HTTP proxy\n    match req.headers().get(\"Host\") {\n        Some(hhost) => match hhost.to_str() {\n            Ok(shost) => {\n                match Authority::from_str(shost) {\n                    Ok(authority) => match authority_addr(req.uri().scheme_str(), &authority) {\n                        Some(host) => {\n                            trace!(\"HTTP {} URI {} got host from header: {}\", req.method(), req.uri(), host);\n\n                            // Reassemble URI\n                            let mut parts = req.uri().clone().into_parts();\n                            if parts.scheme.is_none() {\n                                // Use http as default.\n                                parts.scheme = Some(Scheme::HTTP);\n                            }\n                            parts.authority = Some(authority);\n\n                            // Replaces URI\n                            *req.uri_mut() = Uri::from_parts(parts).expect(\"Reassemble URI failed\");\n\n                            debug!(\"reassembled URI from \\\"Host\\\", {}\", req.uri());\n\n                            Ok(host)\n                        }\n                        None => {\n                            error!(\n                                \"HTTP {} URI {} \\\"Host\\\" header invalid, value: {}\",\n                                req.method(),\n                                req.uri(),\n                                shost\n                            );\n\n                            Err(())\n                        }\n                    },\n                    Err(..) => {\n                        error!(\n                            \"HTTP {} URI {} \\\"Host\\\" header is not an Authority, value: {:?}\",\n                            req.method(),\n                            req.uri(),\n                            hhost\n                        );\n\n                        Err(())\n                    }\n                }\n            }\n            Err(..) => {\n                error!(\n                    \"HTTP {} URI {} \\\"Host\\\" header invalid encoding, value: {:?}\",\n                    req.method(),\n                    req.uri(),\n                    hhost\n                );\n\n                Err(())\n            }\n        },\n        None => {\n            error!(\n                \"HTTP {} URI doesn't have valid host and missing the \\\"Host\\\" header, URI: {}\",\n                req.method(),\n                req.uri()\n            );\n\n            Err(())\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/http/http_stream.rs",
    "content": "//! Proxied HTTP stream\n\nuse std::{\n    io::{self, ErrorKind},\n    pin::Pin,\n    task::{self, Poll},\n};\n\nuse pin_project::pin_project;\nuse tokio::io::{AsyncRead, AsyncWrite, ReadBuf};\n\nuse crate::local::net::AutoProxyClientStream;\n\n#[allow(clippy::large_enum_variant)]\n#[pin_project(project = ProxyHttpStreamProj)]\npub enum ProxyHttpStream {\n    Http(#[pin] AutoProxyClientStream),\n    #[cfg(feature = \"local-http-native-tls\")]\n    Https(#[pin] tokio_native_tls::TlsStream<AutoProxyClientStream>, bool),\n    #[cfg(feature = \"local-http-rustls\")]\n    Https(#[pin] tokio_rustls::client::TlsStream<AutoProxyClientStream>, bool),\n}\n\nimpl ProxyHttpStream {\n    pub fn connect_http(stream: AutoProxyClientStream) -> Self {\n        Self::Http(stream)\n    }\n\n    #[cfg(feature = \"local-http-native-tls\")]\n    pub async fn connect_https(stream: AutoProxyClientStream, domain: &str) -> io::Result<ProxyHttpStream> {\n        use native_tls::TlsConnector;\n\n        let cx = match TlsConnector::builder().request_alpns(&[\"h2\", \"http/1.1\"]).build() {\n            Ok(c) => c,\n            Err(err) => {\n                return Err(io::Error::other(format!(\"tls build: {err}\")));\n            }\n        };\n        let cx = tokio_native_tls::TlsConnector::from(cx);\n\n        match cx.connect(domain, stream).await {\n            Ok(s) => {\n                let negotiated_h2 = match s.get_ref().negotiated_alpn() {\n                    Ok(Some(alpn)) => alpn == b\"h2\",\n                    Ok(None) => false,\n                    Err(err) => {\n                        let ierr = io::Error::other(format!(\"tls alpn negotiate: {err}\"));\n                        return Err(ierr);\n                    }\n                };\n\n                Ok(ProxyHttpStream::Https(s, negotiated_h2))\n            }\n            Err(err) => {\n                let ierr = io::Error::other(format!(\"tls connect: {err}\"));\n                Err(ierr)\n            }\n        }\n    }\n\n    #[cfg(feature = \"local-http-rustls\")]\n    pub async fn connect_https(stream: AutoProxyClientStream, domain: &str) -> io::Result<Self> {\n        use log::warn;\n        use rustls_native_certs::CertificateResult;\n        use std::sync::{Arc, LazyLock};\n        use tokio_rustls::{\n            TlsConnector,\n            rustls::{ClientConfig, RootCertStore, pki_types::ServerName},\n        };\n\n        static TLS_CONFIG: LazyLock<Arc<ClientConfig>> = LazyLock::new(|| {\n            let mut config = ClientConfig::builder()\n                .with_root_certificates({\n                    // Load WebPKI roots (Mozilla's root certificates)\n                    let mut store = RootCertStore::empty();\n                    store.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());\n\n                    let CertificateResult { certs, errors, .. } = rustls_native_certs::load_native_certs();\n                    if !errors.is_empty() {\n                        for error in errors {\n                            warn!(\"failed to load cert (native), error: {}\", error);\n                        }\n                    }\n\n                    for cert in certs {\n                        if let Err(err) = store.add(cert) {\n                            warn!(\"failed to add cert (native), error: {}\", err);\n                        }\n                    }\n\n                    store\n                })\n                .with_no_client_auth();\n\n            // Try to negotiate HTTP/2\n            config.alpn_protocols = vec![b\"h2\".to_vec(), b\"http/1.1\".to_vec()];\n            Arc::new(config)\n        });\n\n        let connector = TlsConnector::from(TLS_CONFIG.clone());\n\n        let host = match ServerName::try_from(domain) {\n            Ok(n) => n,\n            Err(_) => {\n                return Err(io::Error::new(\n                    ErrorKind::InvalidInput,\n                    format!(\"invalid dnsname \\\"{domain}\\\"\"),\n                ));\n            }\n        };\n\n        let tls_stream = connector.connect(host.to_owned(), stream).await?;\n\n        let (_, session) = tls_stream.get_ref();\n        let negotiated_http2 = matches!(session.alpn_protocol(), Some(b\"h2\"));\n\n        Ok(Self::Https(tls_stream, negotiated_http2))\n    }\n\n    #[cfg(not(any(feature = \"local-http-native-tls\", feature = \"local-http-rustls\")))]\n    pub async fn connect_https(_stream: AutoProxyClientStream, _domain: &str) -> io::Result<ProxyHttpStream> {\n        let err = io::Error::other(\n            \"https is not supported, consider enable it by feature \\\"local-http-native-tls\\\" or \\\"local-http-rustls\\\"\",\n        );\n        Err(err)\n    }\n\n    pub fn negotiated_http2(&self) -> bool {\n        match *self {\n            Self::Http(..) => false,\n            #[cfg(any(feature = \"local-http-native-tls\", feature = \"local-http-rustls\"))]\n            Self::Https(_, n) => n,\n        }\n    }\n}\n\nmacro_rules! forward_call {\n    ($self:expr, $method:ident $(, $param:expr)*) => {\n        match $self.as_mut().project() {\n            ProxyHttpStreamProj::Http(stream) => stream.$method($($param),*),\n            #[cfg(any(feature = \"local-http-native-tls\", feature = \"local-http-rustls\"))]\n            ProxyHttpStreamProj::Https(stream, ..) => stream.$method($($param),*),\n        }\n    };\n}\n\nimpl AsyncRead for ProxyHttpStream {\n    fn poll_read(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>, buf: &mut ReadBuf<'_>) -> Poll<io::Result<()>> {\n        forward_call!(self, poll_read, cx, buf)\n    }\n}\n\nimpl AsyncWrite for ProxyHttpStream {\n    fn poll_write(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>, buf: &[u8]) -> Poll<io::Result<usize>> {\n        forward_call!(self, poll_write, cx, buf)\n    }\n\n    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<io::Result<()>> {\n        forward_call!(self, poll_flush, cx)\n    }\n\n    fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<io::Result<()>> {\n        forward_call!(self, poll_shutdown, cx)\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/http/mod.rs",
    "content": "//! Shadowsocks Local HTTP proxy server\n//!\n//! https://www.ietf.org/rfc/rfc2068.txt\n\npub use self::{\n    http_client::{HttpClient, HttpClientError},\n    server::{Http, HttpBuilder, HttpConnectionHandler},\n};\n\npub mod config;\nmod http_client;\nmod http_service;\nmod http_stream;\npub mod server;\nmod tokio_rt;\nmod utils;\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/http/server.rs",
    "content": "//! Shadowsocks Local HTTP proxy server\n//!\n//! https://www.ietf.org/rfc/rfc2068.txt\n\nuse std::{io, net::SocketAddr, sync::Arc, time::Duration};\n\nuse hyper::{body, server::conn::http1, service};\nuse log::{error, info, trace};\nuse shadowsocks::{config::ServerAddr, net::TcpListener};\nuse tokio::{\n    io::{AsyncRead, AsyncWrite},\n    time,\n};\n\nuse crate::local::{\n    context::ServiceContext, loadbalancing::PingBalancer, net::tcp::listener::create_standard_tcp_listener,\n};\n\nuse super::{config::HttpAuthConfig, http_client::HttpClient, http_service::HttpService, tokio_rt::TokioIo};\n\n/// HTTP Local server builder\npub struct HttpBuilder {\n    context: Arc<ServiceContext>,\n    client_config: ServerAddr,\n    balancer: PingBalancer,\n    #[cfg(target_os = \"macos\")]\n    launchd_tcp_socket_name: Option<String>,\n    http_auth: HttpAuthConfig,\n}\n\nimpl HttpBuilder {\n    /// Create a new HTTP Local server builder\n    pub fn new(client_config: ServerAddr, balancer: PingBalancer) -> Self {\n        let context = ServiceContext::new();\n        Self::with_context(Arc::new(context), client_config, balancer)\n    }\n\n    /// Create with an existed context\n    pub fn with_context(context: Arc<ServiceContext>, client_config: ServerAddr, balancer: PingBalancer) -> Self {\n        Self {\n            context,\n            client_config,\n            balancer,\n            #[cfg(target_os = \"macos\")]\n            launchd_tcp_socket_name: None,\n            http_auth: HttpAuthConfig::default(),\n        }\n    }\n\n    #[cfg(target_os = \"macos\")]\n    pub fn set_launchd_tcp_socket_name(&mut self, n: String) {\n        self.launchd_tcp_socket_name = Some(n);\n    }\n\n    pub fn set_http_auth(&mut self, auth: HttpAuthConfig) {\n        self.http_auth = auth;\n    }\n\n    /// Build HTTP server instance\n    pub async fn build(self) -> io::Result<Http> {\n        cfg_if::cfg_if! {\n            if #[cfg(target_os = \"macos\")] {\n                let listener = match self.launchd_tcp_socket_name {\n                    Some(launchd_socket_name) => {\n                        use tokio::net::TcpListener as TokioTcpListener;\n                        use crate::net::launch_activate_socket::get_launch_activate_tcp_listener;\n\n                        let std_listener = get_launch_activate_tcp_listener(&launchd_socket_name, true)?;\n                        let tokio_listener = TokioTcpListener::from_std(std_listener)?;\n                        TcpListener::from_listener(tokio_listener, self.context.accept_opts())?\n                    } _ => {\n                        create_standard_tcp_listener(&self.context, &self.client_config).await?\n                    }\n                };\n            } else {\n                let listener = create_standard_tcp_listener(&self.context, &self.client_config).await?;\n            }\n        }\n\n        // let proxy_client_cache = Arc::new(ProxyClientCache::new(self.context.clone()));\n\n        Ok(Http {\n            context: self.context,\n            listener,\n            balancer: self.balancer,\n            http_auth: Arc::new(self.http_auth),\n        })\n    }\n}\n\n/// HTTP Local server\npub struct Http {\n    context: Arc<ServiceContext>,\n    listener: TcpListener,\n    balancer: PingBalancer,\n    http_auth: Arc<HttpAuthConfig>,\n}\n\nimpl Http {\n    /// Server's local address\n    pub fn local_addr(&self) -> io::Result<SocketAddr> {\n        self.listener.local_addr()\n    }\n\n    /// Run server\n    pub async fn run(self) -> io::Result<()> {\n        // https://www.ietf.org/rfc/rfc2068.txt\n        // HTTP Proxy is based on HTTP/1.1\n\n        info!(\n            \"shadowsocks HTTP listening on {}\",\n            self.listener.local_addr().expect(\"http local_addr\")\n        );\n\n        let handler = HttpConnectionHandler::new(self.context, self.balancer, self.http_auth);\n\n        loop {\n            let (stream, peer_addr) = match self.listener.accept().await {\n                Ok(s) => s,\n                Err(err) => {\n                    error!(\"failed to accept HTTP clients, err: {}\", err);\n                    time::sleep(Duration::from_secs(1)).await;\n                    continue;\n                }\n            };\n\n            trace!(\"HTTP accepted client from {}\", peer_addr);\n            let handler = handler.clone();\n            tokio::spawn(async move {\n                if let Err(err) = handler.serve_connection(stream, peer_addr).await {\n                    error!(\"HTTP connection {} handler failed with error: {}\", peer_addr, err);\n                }\n            });\n        }\n    }\n}\n\n/// HTTP Proxy handler for `accept()`ed HTTP clients\n///\n/// It should be created once and then `clone()` for every individual TCP connections\n#[derive(Clone)]\npub struct HttpConnectionHandler {\n    context: Arc<ServiceContext>,\n    balancer: PingBalancer,\n    http_client: HttpClient<body::Incoming>,\n    http_auth: Arc<HttpAuthConfig>,\n}\n\nimpl HttpConnectionHandler {\n    /// Create a new Handler\n    pub fn new(context: Arc<ServiceContext>, balancer: PingBalancer, http_auth: Arc<HttpAuthConfig>) -> Self {\n        Self {\n            context,\n            balancer,\n            http_client: HttpClient::new(),\n            http_auth,\n        }\n    }\n\n    /// Handle a TCP HTTP connection\n    pub async fn serve_connection<S>(self, stream: S, peer_addr: SocketAddr) -> hyper::Result<()>\n    where\n        S: AsyncRead + AsyncWrite + Unpin + Send + 'static,\n    {\n        let Self {\n            context,\n            balancer,\n            http_client,\n            http_auth,\n        } = self;\n\n        let io = TokioIo::new(stream);\n\n        // NOTE: Some stupid clients requires HTTP header keys to be case-sensitive.\n        // For example: Nintendo Switch\n        http1::Builder::new()\n            .keep_alive(true)\n            .title_case_headers(true)\n            .preserve_header_case(true)\n            .serve_connection(\n                io,\n                service::service_fn(move |req| {\n                    HttpService::new(\n                        context.clone(),\n                        peer_addr,\n                        http_client.clone(),\n                        balancer.clone(),\n                        http_auth.clone(),\n                    )\n                    .serve_connection(req)\n                }),\n            )\n            .with_upgrades()\n            .await\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/http/tokio_rt.rs",
    "content": "use std::{\n    future::Future,\n    pin::Pin,\n    task::{Context, Poll},\n};\n\nuse pin_project::pin_project;\n\n#[derive(Debug)]\n#[pin_project]\npub struct TokioIo<T> {\n    #[pin]\n    inner: T,\n}\n\nimpl<T> TokioIo<T> {\n    pub fn new(inner: T) -> Self {\n        Self { inner }\n    }\n\n    // pub fn inner(self) -> T {\n    //     self.inner\n    // }\n}\n\nimpl<T> hyper::rt::Read for TokioIo<T>\nwhere\n    T: tokio::io::AsyncRead,\n{\n    fn poll_read(\n        self: Pin<&mut Self>,\n        cx: &mut Context<'_>,\n        mut buf: hyper::rt::ReadBufCursor<'_>,\n    ) -> Poll<Result<(), std::io::Error>> {\n        let n = unsafe {\n            let mut tbuf = tokio::io::ReadBuf::uninit(buf.as_mut());\n            match tokio::io::AsyncRead::poll_read(self.project().inner, cx, &mut tbuf) {\n                Poll::Ready(Ok(())) => tbuf.filled().len(),\n                other => return other,\n            }\n        };\n\n        unsafe {\n            buf.advance(n);\n        }\n        Poll::Ready(Ok(()))\n    }\n}\n\nimpl<T> hyper::rt::Write for TokioIo<T>\nwhere\n    T: tokio::io::AsyncWrite,\n{\n    fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize, std::io::Error>> {\n        tokio::io::AsyncWrite::poll_write(self.project().inner, cx, buf)\n    }\n\n    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), std::io::Error>> {\n        tokio::io::AsyncWrite::poll_flush(self.project().inner, cx)\n    }\n\n    fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), std::io::Error>> {\n        tokio::io::AsyncWrite::poll_shutdown(self.project().inner, cx)\n    }\n\n    fn is_write_vectored(&self) -> bool {\n        tokio::io::AsyncWrite::is_write_vectored(&self.inner)\n    }\n\n    fn poll_write_vectored(\n        self: Pin<&mut Self>,\n        cx: &mut Context<'_>,\n        bufs: &[std::io::IoSlice<'_>],\n    ) -> Poll<Result<usize, std::io::Error>> {\n        tokio::io::AsyncWrite::poll_write_vectored(self.project().inner, cx, bufs)\n    }\n}\n\nimpl<T> tokio::io::AsyncRead for TokioIo<T>\nwhere\n    T: hyper::rt::Read,\n{\n    fn poll_read(\n        self: Pin<&mut Self>,\n        cx: &mut Context<'_>,\n        tbuf: &mut tokio::io::ReadBuf<'_>,\n    ) -> Poll<Result<(), std::io::Error>> {\n        // let init = tbuf.initialized().len();\n        let filled = tbuf.filled().len();\n        let sub_filled = unsafe {\n            let mut buf = hyper::rt::ReadBuf::uninit(tbuf.unfilled_mut());\n\n            match hyper::rt::Read::poll_read(self.project().inner, cx, buf.unfilled()) {\n                Poll::Ready(Ok(())) => buf.filled().len(),\n                other => return other,\n            }\n        };\n\n        let n_filled = filled + sub_filled;\n        // At least sub_filled bytes had to have been initialized.\n        let n_init = sub_filled;\n        unsafe {\n            tbuf.assume_init(n_init);\n            tbuf.set_filled(n_filled);\n        }\n\n        Poll::Ready(Ok(()))\n    }\n}\n\nimpl<T> tokio::io::AsyncWrite for TokioIo<T>\nwhere\n    T: hyper::rt::Write,\n{\n    fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize, std::io::Error>> {\n        hyper::rt::Write::poll_write(self.project().inner, cx, buf)\n    }\n\n    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), std::io::Error>> {\n        hyper::rt::Write::poll_flush(self.project().inner, cx)\n    }\n\n    fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), std::io::Error>> {\n        hyper::rt::Write::poll_shutdown(self.project().inner, cx)\n    }\n\n    fn is_write_vectored(&self) -> bool {\n        hyper::rt::Write::is_write_vectored(&self.inner)\n    }\n\n    fn poll_write_vectored(\n        self: Pin<&mut Self>,\n        cx: &mut Context<'_>,\n        bufs: &[std::io::IoSlice<'_>],\n    ) -> Poll<Result<usize, std::io::Error>> {\n        hyper::rt::Write::poll_write_vectored(self.project().inner, cx, bufs)\n    }\n}\n\n#[derive(Clone)]\npub struct TokioExecutor;\n\nimpl<F> hyper::rt::Executor<F> for TokioExecutor\nwhere\n    F: Future + Send + 'static,\n    F::Output: Send + 'static,\n{\n    fn execute(&self, future: F) {\n        tokio::spawn(future);\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/http/utils.rs",
    "content": "//! HTTP Utilities\n\nuse std::{\n    io,\n    net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},\n    sync::Arc,\n};\n\nuse hyper::{\n    HeaderMap, Uri, Version,\n    header::{self, HeaderValue},\n    http::uri::Authority,\n};\nuse log::error;\nuse shadowsocks::relay::socks5::Address;\n\nuse crate::local::{\n    context::ServiceContext,\n    loadbalancing::{PingBalancer, ServerIdent},\n    net::AutoProxyClientStream,\n};\n\npub fn authority_addr(scheme_str: Option<&str>, authority: &Authority) -> Option<Address> {\n    // RFC7230 indicates that we should ignore userinfo\n    // https://tools.ietf.org/html/rfc7230#section-5.3.3\n\n    // Check if URI has port\n    let port = match authority.port_u16() {\n        Some(port) => port,\n        None => {\n            match scheme_str {\n                None => 80, // Assume it is http\n                Some(\"http\") => 80,\n                Some(\"https\") => 443,\n                _ => return None, // Not supported\n            }\n        }\n    };\n\n    let host_str = authority.host();\n\n    // RFC3986 indicates that IPv6 address should be wrapped in [ and ]\n    // https://tools.ietf.org/html/rfc3986#section-3.2.2\n    //\n    // Example: [::1] without port\n    if host_str.starts_with('[') && host_str.ends_with(']') {\n        // Must be a IPv6 address\n        let addr = &host_str[1..host_str.len() - 1];\n        match addr.parse::<Ipv6Addr>() {\n            Ok(a) => Some(Address::from(SocketAddr::new(IpAddr::V6(a), port))),\n            // Ignore invalid IPv6 address\n            Err(..) => None,\n        }\n    } else {\n        // It must be a IPv4 address\n        match host_str.parse::<Ipv4Addr>() {\n            Ok(a) => Some(Address::from(SocketAddr::new(IpAddr::V4(a), port))),\n            // Should be a domain name, or a invalid IP address.\n            // Let DNS deal with it.\n            Err(..) => Some(Address::DomainNameAddress(host_str.to_owned(), port)),\n        }\n    }\n}\n\npub fn host_addr(uri: &Uri) -> Option<Address> {\n    match uri.authority() {\n        None => None,\n        Some(authority) => authority_addr(uri.scheme_str(), authority),\n    }\n}\n\nfn get_keep_alive_val(values: header::GetAll<HeaderValue>) -> Option<bool> {\n    let mut conn_keep_alive = None;\n    for value in values {\n        if let Ok(value) = value.to_str() {\n            if value.eq_ignore_ascii_case(\"close\") {\n                conn_keep_alive = Some(false);\n            } else {\n                for part in value.split(',') {\n                    let part = part.trim();\n                    if part.eq_ignore_ascii_case(\"keep-alive\") {\n                        conn_keep_alive = Some(true);\n                        break;\n                    }\n                }\n            }\n        }\n    }\n    conn_keep_alive\n}\n\npub fn check_keep_alive(version: Version, headers: &HeaderMap<HeaderValue>, check_proxy: bool) -> bool {\n    // HTTP/1.1, HTTP/2, HTTP/3 keeps alive by default\n    let mut conn_keep_alive = !matches!(version, Version::HTTP_09 | Version::HTTP_10);\n\n    if check_proxy {\n        // Modern browsers will send Proxy-Connection instead of Connection\n        // for HTTP/1.0 proxies which blindly forward Connection to remote\n        //\n        // https://tools.ietf.org/html/rfc7230#appendix-A.1.2\n        if let Some(b) = get_keep_alive_val(headers.get_all(\"Proxy-Connection\")) {\n            conn_keep_alive = b\n        }\n    }\n\n    // Connection will replace Proxy-Connection\n    //\n    // But why client sent both Connection and Proxy-Connection? That's not standard!\n    if let Some(b) = get_keep_alive_val(headers.get_all(\"Connection\")) {\n        conn_keep_alive = b\n    }\n\n    conn_keep_alive\n}\n\npub async fn connect_host(\n    context: Arc<ServiceContext>,\n    host: &Address,\n    balancer: Option<&PingBalancer>,\n) -> io::Result<(AutoProxyClientStream, Option<Arc<ServerIdent>>)> {\n    match balancer {\n        None => match AutoProxyClientStream::connect_bypassed(context, host).await {\n            Ok(s) => Ok((s, None)),\n            Err(err) => {\n                error!(\"failed to connect host {} bypassed, err: {}\", host, err);\n                Err(err)\n            }\n        },\n        Some(balancer) if balancer.is_empty() => match AutoProxyClientStream::connect_bypassed(context, host).await {\n            Ok(s) => Ok((s, None)),\n            Err(err) => {\n                error!(\"failed to connect host {} bypassed, err: {}\", host, err);\n                Err(err)\n            }\n        },\n        Some(balancer) => {\n            let server = balancer.best_tcp_server();\n\n            match AutoProxyClientStream::connect_with_opts(context, server.as_ref(), host, server.connect_opts_ref())\n                .await\n            {\n                Ok(s) => Ok((s, Some(server))),\n                Err(err) => {\n                    error!(\n                        \"failed to connect host {} proxied, svr_cfg: {}, error: {}\",\n                        host,\n                        server.server_config().addr(),\n                        err\n                    );\n                    Err(err)\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/loadbalancing/mod.rs",
    "content": "//! Load balancer\n\npub use self::{\n    ping_balancer::{PingBalancer, PingBalancerBuilder, ServerType},\n    server_data::{ServerIdent, ServerScore},\n};\n\npub mod ping_balancer;\npub mod server_data;\npub mod server_stat;\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/loadbalancing/ping_balancer.rs",
    "content": "//! Load Balancer chooses server by statistic latency data collected from active probing\n\nuse std::{\n    cmp,\n    fmt::{self, Debug, Display},\n    io,\n    iter::Iterator,\n    net::{Ipv4Addr, SocketAddr},\n    sync::{\n        Arc,\n        atomic::{AtomicUsize, Ordering},\n    },\n    time::{Duration, Instant},\n};\n\nuse arc_swap::ArcSwap;\nuse byte_string::ByteStr;\nuse futures::future;\nuse log::{debug, error, info, trace, warn};\nuse shadowsocks::{\n    ServerConfig,\n    config::{Mode, ServerSource},\n    plugin::{Plugin, PluginMode},\n    relay::{\n        socks5::Address,\n        tcprelay::proxy_stream::ProxyClientStream,\n        udprelay::{MAXIMUM_UDP_PAYLOAD_SIZE, options::UdpSocketControlData, proxy_socket::ProxySocket},\n    },\n};\nuse spin::Mutex as SpinMutex;\nuse tokio::{\n    io::{AsyncBufReadExt, AsyncWriteExt, BufReader},\n    sync::Notify,\n    task::JoinHandle,\n    time,\n};\n\nuse crate::{config::ServerInstanceConfig, local::context::ServiceContext};\n\nuse super::{\n    server_data::ServerIdent,\n    server_stat::{DEFAULT_CHECK_INTERVAL_SEC, DEFAULT_CHECK_TIMEOUT_SEC, Score},\n};\n\nconst EXPECTED_CHECK_POINTS_IN_CHECK_WINDOW: u32 = 67;\n\n/// Remote Server Type\n#[derive(Debug, Clone, Copy)]\npub enum ServerType {\n    Tcp,\n    Udp,\n}\n\nimpl fmt::Display for ServerType {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        match *self {\n            Self::Tcp => f.write_str(\"TCP\"),\n            Self::Udp => f.write_str(\"UDP\"),\n        }\n    }\n}\n\n/// Build a `PingBalancer`\npub struct PingBalancerBuilder {\n    servers: Vec<Arc<ServerIdent>>,\n    context: Arc<ServiceContext>,\n    mode: Mode,\n    max_server_rtt: Duration,\n    check_interval: Duration,\n    check_best_interval: Option<Duration>,\n}\n\nimpl PingBalancerBuilder {\n    pub fn new(context: Arc<ServiceContext>, mode: Mode) -> Self {\n        Self {\n            servers: Vec::new(),\n            context,\n            mode,\n            max_server_rtt: Duration::from_secs(DEFAULT_CHECK_TIMEOUT_SEC),\n            check_interval: Duration::from_secs(DEFAULT_CHECK_INTERVAL_SEC),\n            check_best_interval: None,\n        }\n    }\n\n    pub fn add_server(&mut self, server: ServerInstanceConfig) {\n        let ident = ServerIdent::new(\n            self.context.clone(),\n            server,\n            self.max_server_rtt,\n            self.check_interval * EXPECTED_CHECK_POINTS_IN_CHECK_WINDOW,\n        );\n        self.servers.push(Arc::new(ident));\n    }\n\n    pub fn max_server_rtt(&mut self, rtt: Duration) {\n        self.max_server_rtt = rtt;\n    }\n\n    pub fn check_interval(&mut self, intv: Duration) {\n        self.check_interval = intv;\n    }\n\n    pub fn check_best_interval(&mut self, intv: Duration) {\n        self.check_best_interval = Some(intv);\n    }\n\n    fn find_best_idx(servers: &[Arc<ServerIdent>], mode: Mode) -> (usize, usize) {\n        if servers.is_empty() {\n            trace!(\"init without any TCP and UDP servers\");\n            return (0, 0);\n        }\n\n        let mut best_tcp_idx = 0;\n        let mut best_udp_idx = 0;\n\n        if mode.enable_tcp() {\n            let mut found_tcp_idx = false;\n            for (idx, server) in servers.iter().enumerate() {\n                if PingBalancerContext::check_server_tcp_enabled(server.server_config()) {\n                    best_tcp_idx = idx;\n                    found_tcp_idx = true;\n                    break;\n                }\n            }\n\n            if !found_tcp_idx {\n                warn!(\n                    \"no valid TCP server serving for TCP clients, consider disable TCP with \\\"mode\\\": \\\"udp_only\\\", currently chose {}\",\n                    ServerConfigFormatter::new(servers[best_tcp_idx].server_config())\n                );\n            } else {\n                trace!(\n                    \"init chose TCP server {}\",\n                    ServerConfigFormatter::new(servers[best_tcp_idx].server_config())\n                );\n            }\n        }\n\n        if mode.enable_udp() {\n            let mut found_udp_idx = false;\n            for (idx, server) in servers.iter().enumerate() {\n                if PingBalancerContext::check_server_udp_enabled(server.server_config()) {\n                    best_udp_idx = idx;\n                    found_udp_idx = true;\n                    break;\n                }\n            }\n\n            if !found_udp_idx {\n                warn!(\n                    \"no valid UDP server serving for UDP clients, consider disable UDP with \\\"mode\\\": \\\"tcp_only\\\", currently chose {}\",\n                    ServerConfigFormatter::new(servers[best_udp_idx].server_config())\n                );\n            } else {\n                trace!(\n                    \"init chose UDP server {}\",\n                    ServerConfigFormatter::new(servers[best_udp_idx].server_config())\n                );\n            }\n        }\n\n        (best_tcp_idx, best_udp_idx)\n    }\n\n    pub async fn build(self) -> io::Result<PingBalancer> {\n        if let Some(intv) = self.check_best_interval\n            && intv > self.check_interval\n        {\n            return Err(io::Error::other(\"check_interval must be >= check_best_interval\"));\n        }\n\n        let (shared_context, task_abortable) = PingBalancerContext::new(\n            self.servers,\n            self.context,\n            self.mode,\n            self.max_server_rtt,\n            self.check_interval,\n            self.check_best_interval,\n        )\n        .await?;\n\n        Ok(PingBalancer {\n            inner: Arc::new(PingBalancerInner {\n                context: ArcSwap::new(shared_context),\n                task_abortable: SpinMutex::new(task_abortable),\n            }),\n        })\n    }\n}\n\nstruct PingBalancerContextTask {\n    checker_abortable: JoinHandle<()>,\n    plugin_abortable: Option<JoinHandle<()>>,\n}\n\nimpl Drop for PingBalancerContextTask {\n    fn drop(&mut self) {\n        self.checker_abortable.abort();\n        if let Some(ref p) = self.plugin_abortable {\n            p.abort();\n        }\n    }\n}\n\nstruct PingBalancerContext {\n    servers: Vec<Arc<ServerIdent>>,\n    best_tcp_idx: AtomicUsize,\n    best_udp_idx: AtomicUsize,\n    context: Arc<ServiceContext>,\n    mode: Mode,\n    max_server_rtt: Duration,\n    check_interval: Duration,\n    check_best_interval: Option<Duration>,\n    best_task_notify: Notify,\n}\n\nimpl PingBalancerContext {\n    fn best_tcp_server(&self) -> Arc<ServerIdent> {\n        assert!(!self.is_empty(), \"no available server\");\n        self.servers[self.best_tcp_idx.load(Ordering::Relaxed)].clone()\n    }\n\n    fn best_udp_server(&self) -> Arc<ServerIdent> {\n        assert!(!self.is_empty(), \"no available server\");\n        self.servers[self.best_udp_idx.load(Ordering::Relaxed)].clone()\n    }\n\n    #[inline]\n    fn is_empty(&self) -> bool {\n        self.servers.is_empty()\n    }\n}\n\nimpl PingBalancerContext {\n    pub(crate) async fn new(\n        mut servers: Vec<Arc<ServerIdent>>,\n        context: Arc<ServiceContext>,\n        mode: Mode,\n        max_server_rtt: Duration,\n        check_interval: Duration,\n        check_best_interval: Option<Duration>,\n    ) -> io::Result<(Arc<Self>, PingBalancerContextTask)> {\n        let plugin_abortable = {\n            // Start plugins for TCP proxies\n\n            let mut plugins = Vec::with_capacity(servers.len());\n\n            for server in &mut servers {\n                let server = Arc::get_mut(server).unwrap();\n                let svr_cfg = server.server_config_mut();\n\n                if let Some(p) = svr_cfg.plugin() {\n                    // Start Plugin Process\n                    let plugin = Plugin::start(p, svr_cfg.addr(), PluginMode::Client)?;\n                    svr_cfg.set_plugin_addr(plugin.local_addr().into());\n                    plugins.push(plugin);\n                }\n            }\n\n            if plugins.is_empty() {\n                None\n            } else {\n                // Load balancer will check all servers' score before server's actual start.\n                // So we have to ensure all plugins have been started before that.\n\n                let mut check_fut = Vec::with_capacity(plugins.len());\n\n                for plugin in &plugins {\n                    // 3 seconds is not a carefully selected value\n                    // I choose that because any values bigger will make me felt too long.\n                    check_fut.push(plugin.wait_started(Duration::from_secs(3)));\n                }\n\n                // Run all of them simultaneously\n                let _ = future::join_all(check_fut).await;\n\n                let plugin_abortable = tokio::spawn(async move {\n                    let mut vfut = Vec::with_capacity(plugins.len());\n\n                    for plugin in plugins {\n                        vfut.push(async move {\n                            match plugin.join().await {\n                                Ok(status) => {\n                                    error!(\"plugin exited with status: {}\", status);\n                                    Ok(())\n                                }\n                                Err(err) => {\n                                    error!(\"plugin exited with error: {}\", err);\n                                    Err(err)\n                                }\n                            }\n                        });\n                    }\n\n                    let _ = future::join_all(vfut).await;\n\n                    panic!(\"all plugins are exited. all connections may fail, check your configuration\");\n                });\n\n                Some(plugin_abortable)\n            }\n        };\n\n        let (best_tcp_idx, best_udp_idx) = PingBalancerBuilder::find_best_idx(&servers, mode);\n\n        let balancer_context = Self {\n            servers,\n            best_tcp_idx: AtomicUsize::new(best_tcp_idx),\n            best_udp_idx: AtomicUsize::new(best_udp_idx),\n            context,\n            mode,\n            max_server_rtt,\n            check_interval,\n            check_best_interval,\n            best_task_notify: Notify::new(),\n        };\n\n        balancer_context.init_score().await;\n\n        let shared_context = Arc::new(balancer_context);\n\n        let checker_abortable = {\n            let shared_context = shared_context.clone();\n            tokio::spawn(async move { shared_context.checker_task().await })\n        };\n\n        Ok((\n            shared_context,\n            PingBalancerContextTask {\n                checker_abortable,\n                plugin_abortable,\n            },\n        ))\n    }\n\n    async fn init_score(&self) {\n        if self.servers.is_empty() {\n            return;\n        }\n        self.check_once(true).await;\n    }\n\n    fn check_server_tcp_enabled(svr_cfg: &ServerConfig) -> bool {\n        svr_cfg.mode().enable_tcp() && svr_cfg.weight().tcp_weight() > 0.0\n    }\n\n    fn check_server_udp_enabled(svr_cfg: &ServerConfig) -> bool {\n        svr_cfg.mode().enable_udp() && svr_cfg.weight().udp_weight() > 0.0\n    }\n\n    fn probing_required(&self) -> bool {\n        if self.servers.is_empty() {\n            return false;\n        }\n\n        let mut tcp_count = 0;\n        let mut udp_count = 0;\n\n        for server in self.servers.iter() {\n            let svr_cfg = server.server_config();\n            if self.mode.enable_tcp() && Self::check_server_tcp_enabled(svr_cfg) {\n                tcp_count += 1;\n            }\n            if self.mode.enable_udp() && Self::check_server_udp_enabled(svr_cfg) {\n                udp_count += 1;\n            }\n        }\n\n        tcp_count > 1 || udp_count > 1\n    }\n\n    async fn checker_task(self: Arc<Self>) {\n        if !self.probing_required() {\n            self.checker_task_dummy().await\n        } else {\n            self.checker_task_real().await\n        }\n    }\n\n    /// Dummy task that will do nothing if there only have one server in the balancer\n    async fn checker_task_dummy(self: Arc<Self>) {\n        future::pending().await\n    }\n\n    /// Check each servers' score and update the best server's index\n    async fn check_once(&self, first_run: bool) {\n        let servers = &self.servers;\n        if servers.is_empty() {\n            return;\n        }\n\n        let mut vfut_tcp = Vec::with_capacity(servers.len());\n        let mut vfut_udp = Vec::with_capacity(servers.len());\n\n        for server in servers.iter() {\n            let svr_cfg = server.server_config();\n\n            if self.mode.enable_tcp() && Self::check_server_tcp_enabled(svr_cfg) {\n                let checker = PingChecker {\n                    server: server.clone(),\n                    server_type: ServerType::Tcp,\n                    context: self.context.clone(),\n                    max_server_rtt: self.max_server_rtt,\n                };\n                vfut_tcp.push(checker.check_update_score());\n            }\n\n            if self.mode.enable_udp() && Self::check_server_udp_enabled(svr_cfg) {\n                let checker = PingChecker {\n                    server: server.clone(),\n                    server_type: ServerType::Udp,\n                    context: self.context.clone(),\n                    max_server_rtt: self.max_server_rtt,\n                };\n                vfut_udp.push(checker.check_update_score());\n            }\n        }\n\n        let check_tcp = vfut_tcp.len() > 1;\n        let check_udp = vfut_udp.len() > 1;\n\n        if !check_tcp && !check_udp {\n            return;\n        }\n\n        let vfut = if !check_tcp {\n            vfut_udp\n        } else if !check_udp {\n            vfut_tcp\n        } else {\n            vfut_tcp.append(&mut vfut_udp);\n            vfut_tcp\n        };\n\n        future::join_all(vfut).await;\n\n        if self.mode.enable_tcp() && check_tcp {\n            let old_best_idx = self.best_tcp_idx.load(Ordering::Acquire);\n\n            let mut best_idx = 0;\n            let mut best_score = u32::MAX;\n            for (idx, server) in servers.iter().enumerate() {\n                let score = server.tcp_score().score();\n                if score < best_score {\n                    best_idx = idx;\n                    best_score = score;\n                }\n            }\n            self.best_tcp_idx.store(best_idx, Ordering::Release);\n\n            if first_run {\n                info!(\n                    \"chose best TCP server {}\",\n                    ServerConfigFormatter::new(servers[best_idx].server_config())\n                );\n            } else if best_idx != old_best_idx {\n                info!(\n                    \"switched best TCP server from {} to {}\",\n                    ServerConfigFormatter::new(servers[old_best_idx].server_config()),\n                    ServerConfigFormatter::new(servers[best_idx].server_config())\n                );\n            } else {\n                debug!(\n                    \"kept best TCP server {}\",\n                    ServerConfigFormatter::new(servers[old_best_idx].server_config())\n                );\n            }\n        }\n\n        if self.mode.enable_udp() && check_udp {\n            let old_best_idx = self.best_udp_idx.load(Ordering::Acquire);\n\n            let mut best_idx = 0;\n            let mut best_score = u32::MAX;\n            for (idx, server) in servers.iter().enumerate() {\n                let score = server.udp_score().score();\n                if score < best_score {\n                    best_idx = idx;\n                    best_score = score;\n                }\n            }\n            self.best_udp_idx.store(best_idx, Ordering::Release);\n\n            if first_run {\n                info!(\n                    \"chose best UDP server {}\",\n                    ServerConfigFormatter::new(servers[best_idx].server_config())\n                );\n            } else if best_idx != old_best_idx {\n                info!(\n                    \"switched best UDP server from {} to {}\",\n                    ServerConfigFormatter::new(servers[old_best_idx].server_config()),\n                    ServerConfigFormatter::new(servers[best_idx].server_config())\n                );\n            } else {\n                debug!(\n                    \"kept best UDP server {}\",\n                    ServerConfigFormatter::new(servers[old_best_idx].server_config())\n                );\n            }\n        }\n    }\n\n    /// Check the best server only\n    async fn check_best_server(&self) {\n        let servers = &self.servers;\n        if servers.is_empty() {\n            return;\n        }\n\n        let mut vfut = Vec::new();\n\n        let best_tcp_idx = self.best_tcp_idx.load(Ordering::Acquire);\n        let best_udp_idx = self.best_udp_idx.load(Ordering::Acquire);\n\n        let best_tcp_server = &servers[best_tcp_idx];\n        let best_tcp_svr_cfg = best_tcp_server.server_config();\n        let best_udp_server = &servers[best_udp_idx];\n        let best_udp_svr_cfg = best_udp_server.server_config();\n\n        let mut check_tcp = false;\n        let mut check_udp = false;\n\n        if self.mode.enable_tcp() && Self::check_server_tcp_enabled(best_tcp_svr_cfg) {\n            let checker = PingChecker {\n                server: best_tcp_server.clone(),\n                server_type: ServerType::Tcp,\n                context: self.context.clone(),\n                max_server_rtt: self.max_server_rtt,\n            };\n            vfut.push(checker.check_update_score());\n            check_tcp = true;\n        }\n\n        if self.mode.enable_udp() && Self::check_server_udp_enabled(best_udp_svr_cfg) {\n            let checker = PingChecker {\n                server: best_udp_server.clone(),\n                server_type: ServerType::Udp,\n                context: self.context.clone(),\n                max_server_rtt: self.max_server_rtt,\n            };\n            vfut.push(checker.check_update_score());\n            check_udp = true;\n        }\n\n        future::join_all(vfut).await;\n\n        if self.mode.enable_tcp() && check_tcp {\n            let old_best_idx = self.best_tcp_idx.load(Ordering::Acquire);\n\n            let mut best_idx = 0;\n            let mut best_score = u32::MAX;\n            for (idx, server) in servers.iter().enumerate() {\n                let score = server.tcp_score().score();\n                if score < best_score {\n                    best_idx = idx;\n                    best_score = score;\n                }\n            }\n            self.best_tcp_idx.store(best_idx, Ordering::Release);\n\n            if best_idx != old_best_idx {\n                info!(\n                    \"switched best TCP server from {} to {} (best check)\",\n                    ServerConfigFormatter::new(servers[old_best_idx].server_config()),\n                    ServerConfigFormatter::new(servers[best_idx].server_config())\n                );\n            } else {\n                debug!(\n                    \"kept best TCP server {} (best check)\",\n                    ServerConfigFormatter::new(servers[old_best_idx].server_config())\n                );\n            }\n        }\n\n        if self.mode.enable_udp() && check_udp {\n            let old_best_idx = self.best_udp_idx.load(Ordering::Acquire);\n\n            let mut best_idx = 0;\n            let mut best_score = u32::MAX;\n            for (idx, server) in servers.iter().enumerate() {\n                let score = server.udp_score().score();\n                if score < best_score {\n                    best_idx = idx;\n                    best_score = score;\n                }\n            }\n            self.best_udp_idx.store(best_idx, Ordering::Release);\n\n            if best_idx != old_best_idx {\n                info!(\n                    \"switched best UDP server from {} to {} (best check)\",\n                    ServerConfigFormatter::new(servers[old_best_idx].server_config()),\n                    ServerConfigFormatter::new(servers[best_idx].server_config())\n                );\n            } else {\n                debug!(\n                    \"kept best UDP server {} (best check)\",\n                    ServerConfigFormatter::new(servers[old_best_idx].server_config())\n                );\n            }\n        }\n    }\n\n    async fn checker_task_real(&self) {\n        if self.check_best_interval.is_none() {\n            return self.checker_task_all_servers().await;\n        }\n\n        let best = self.checker_task_best_server();\n        let all = self.checker_task_all_servers();\n        futures::join!(best, all);\n    }\n\n    async fn checker_task_all_servers(&self) {\n        if let Some(check_best_interval) = self.check_best_interval {\n            // Get at least 10 points to get the precise scores\n\n            let interval = cmp::min(check_best_interval, self.check_interval);\n\n            let mut count = 0;\n            while count < EXPECTED_CHECK_POINTS_IN_CHECK_WINDOW {\n                time::sleep(interval).await;\n\n                // Sleep before check.\n                // PingBalancer already checked once when constructing\n                self.check_once(false).await;\n\n                count += 1;\n            }\n\n            self.best_task_notify.notify_one();\n\n            trace!(\"finished initializing server scores\");\n        }\n\n        loop {\n            time::sleep(self.check_interval).await;\n\n            // Sleep before check.\n            // PingBalancer already checked once when constructing\n            self.check_once(false).await;\n        }\n    }\n\n    async fn checker_task_best_server(&self) {\n        // Wait until checker_task_all_servers notify.\n        // Because when server starts, the scores are unstable, so we have to run check_all for multiple times\n        self.best_task_notify.notified().await;\n\n        let check_best_interval = self.check_best_interval.unwrap();\n\n        loop {\n            time::sleep(check_best_interval).await;\n\n            // Sleep before check.\n            // PingBalancer already checked once when constructing\n            self.check_best_server().await;\n        }\n    }\n}\n\nstruct PingBalancerInner {\n    context: ArcSwap<PingBalancerContext>,\n    task_abortable: SpinMutex<PingBalancerContextTask>,\n}\n\nimpl Drop for PingBalancerInner {\n    fn drop(&mut self) {\n        trace!(\"ping balancer stopped\");\n    }\n}\n\n/// Balancer with active probing\n#[derive(Clone)]\npub struct PingBalancer {\n    inner: Arc<PingBalancerInner>,\n}\n\nimpl PingBalancer {\n    /// Get service context\n    pub fn context(&self) -> Arc<ServiceContext> {\n        let context = self.inner.context.load();\n        context.context.clone()\n    }\n\n    /// Pick the best TCP server\n    pub fn best_tcp_server(&self) -> Arc<ServerIdent> {\n        let context = self.inner.context.load();\n        context.best_tcp_server()\n    }\n\n    /// Pick the best UDP server\n    pub fn best_udp_server(&self) -> Arc<ServerIdent> {\n        let context = self.inner.context.load();\n        context.best_udp_server()\n    }\n\n    /// Check if there is no available server\n    #[inline]\n    pub fn is_empty(&self) -> bool {\n        let context = self.inner.context.load();\n        context.is_empty()\n    }\n\n    /// Get the server list\n    pub fn servers(&self) -> PingServerIter<'_> {\n        let context = self.inner.context.load();\n        let servers: &Vec<Arc<ServerIdent>> = unsafe { &*(&context.servers as *const _) };\n        PingServerIter {\n            context: context.clone(),\n            iter: servers.iter(),\n        }\n    }\n\n    /// Reset servers in load balancer. Designed for auto-reloading configuration file.\n    pub async fn reset_servers(\n        &self,\n        servers: Vec<ServerInstanceConfig>,\n        replace_server_sources: &[ServerSource],\n    ) -> io::Result<()> {\n        let old_context = self.inner.context.load();\n\n        let mut old_servers = old_context.servers.clone();\n        let mut idx = 0;\n        while idx < old_servers.len() {\n            let source_match = replace_server_sources\n                .iter()\n                .any(|src| *src == old_servers[idx].server_config().source());\n            if source_match {\n                old_servers.swap_remove(idx);\n            } else {\n                idx += 1;\n            }\n        }\n\n        trace!(\n            \"ping balancer going to replace {} servers (total: {}) with {} servers, sources: {:?}\",\n            old_context.servers.len() - old_servers.len(),\n            old_context.servers.len(),\n            servers.len(),\n            replace_server_sources\n        );\n\n        let mut servers = servers\n            .into_iter()\n            .map(|s| {\n                Arc::new(ServerIdent::new(\n                    old_context.context.clone(),\n                    s,\n                    old_context.max_server_rtt,\n                    old_context.check_interval * EXPECTED_CHECK_POINTS_IN_CHECK_WINDOW,\n                ))\n            })\n            .collect::<Vec<Arc<ServerIdent>>>();\n\n        // Recreate a new instance for old servers (old server instance may still being held by clients)\n        for old_server in old_servers {\n            servers.push(Arc::new(ServerIdent::new(\n                old_context.context.clone(),\n                old_server.server_instance_config().clone(),\n                old_context.max_server_rtt,\n                old_context.check_interval * EXPECTED_CHECK_POINTS_IN_CHECK_WINDOW,\n            )));\n        }\n\n        trace!(\"ping balancer merged {} new servers\", servers.len());\n\n        let (shared_context, task_abortable) = PingBalancerContext::new(\n            servers,\n            old_context.context.clone(),\n            old_context.mode,\n            old_context.max_server_rtt,\n            old_context.check_interval,\n            old_context.check_best_interval,\n        )\n        .await?;\n\n        {\n            // Stop the previous task and replace with the new task\n            let mut abortable = self.inner.task_abortable.lock();\n            *abortable = task_abortable;\n        }\n\n        // Replace with the new context\n        self.inner.context.store(shared_context);\n\n        Ok(())\n    }\n}\n\nimpl Debug for PingBalancer {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        let context = self.inner.context.load();\n\n        f.debug_struct(\"PingBalancer\")\n            .field(\"servers\", &context.servers)\n            .field(\"best_tcp_idx\", &context.best_tcp_idx.load(Ordering::Relaxed))\n            .field(\"best_udp_idx\", &context.best_udp_idx.load(Ordering::Relaxed))\n            .finish()\n    }\n}\n\nstruct PingChecker {\n    server: Arc<ServerIdent>,\n    server_type: ServerType,\n    context: Arc<ServiceContext>,\n    max_server_rtt: Duration,\n}\n\nimpl PingChecker {\n    /// Checks server's score and update into `ServerScore<E>`\n    async fn check_update_score(self) {\n        let server_score = match self.server_type {\n            ServerType::Tcp => self.server.tcp_score(),\n            ServerType::Udp => self.server.udp_score(),\n        };\n\n        let (score, stat_data) = match self.check_delay().await {\n            Ok(d) => server_score.push_score_fetch_statistic(Score::Latency(d)).await,\n            // Penalty\n            Err(..) => server_score.push_score_fetch_statistic(Score::Errored).await,\n        };\n\n        if stat_data.fail_rate > 0.8 {\n            warn!(\n                \"balancer: checked & updated remote {} server {} (score: {}), {:?}\",\n                self.server_type,\n                ServerConfigFormatter::new(self.server.server_config()),\n                score,\n                stat_data,\n            );\n        } else {\n            debug!(\n                \"balancer: checked & updated remote {} server {} (score: {}), {:?}\",\n                self.server_type,\n                ServerConfigFormatter::new(self.server.server_config()),\n                score,\n                stat_data,\n            );\n        }\n    }\n\n    /// Detect TCP connectivity with Chromium [Network Portal Detection](https://www.chromium.org/chromium-os/chromiumos-design-docs/network-portal-detection)\n    #[allow(dead_code)]\n    async fn check_request_tcp_chromium(&self) -> io::Result<()> {\n        use std::io::{Error, ErrorKind};\n\n        const GET_BODY: &[u8] =\n            b\"GET /generate_204 HTTP/1.1\\r\\nHost: clients3.google.com\\r\\nConnection: close\\r\\nAccept: */*\\r\\n\\r\\n\";\n\n        let addr = Address::DomainNameAddress(\"clients3.google.com\".to_owned(), 80);\n\n        let mut stream = ProxyClientStream::connect_with_opts(\n            self.context.context(),\n            self.server.server_config(),\n            &addr,\n            self.server.connect_opts_ref(),\n        )\n        .await?;\n        stream.write_all(GET_BODY).await?;\n\n        let mut reader = BufReader::new(stream);\n\n        let mut buf = Vec::new();\n        reader.read_until(b'\\n', &mut buf).await?;\n\n        let mut headers = [httparse::EMPTY_HEADER; 1];\n        let mut response = httparse::Response::new(&mut headers);\n\n        if response.parse(&buf).is_ok() && matches!(response.code, Some(204)) {\n            return Ok(());\n        }\n\n        Err(Error::new(\n            ErrorKind::InvalidData,\n            format!(\n                \"unexpected response from http://clients3.google.com/generate_204, {:?}\",\n                ByteStr::new(&buf)\n            ),\n        ))\n    }\n\n    /// Detect TCP connectivity with Firefox's http://detectportal.firefox.com/success.txt\n    async fn check_request_tcp_firefox(&self) -> io::Result<()> {\n        use std::io::{Error, ErrorKind};\n\n        const GET_BODY: &[u8] =\n            b\"GET /success.txt HTTP/1.1\\r\\nHost: detectportal.firefox.com\\r\\nConnection: close\\r\\nAccept: */*\\r\\n\\r\\n\";\n\n        let addr = Address::DomainNameAddress(\"detectportal.firefox.com\".to_owned(), 80);\n\n        let mut stream = ProxyClientStream::connect_with_opts(\n            self.context.context(),\n            self.server.server_config(),\n            &addr,\n            self.server.connect_opts_ref(),\n        )\n        .await?;\n        stream.write_all(GET_BODY).await?;\n\n        let mut reader = BufReader::new(stream);\n\n        let mut buf = Vec::new();\n        reader.read_until(b'\\n', &mut buf).await?;\n\n        let mut headers = [httparse::EMPTY_HEADER; 1];\n        let mut response = httparse::Response::new(&mut headers);\n\n        if response.parse(&buf).is_ok() && matches!(response.code, Some(200) | Some(204)) {\n            return Ok(());\n        }\n\n        Err(Error::new(\n            ErrorKind::InvalidData,\n            format!(\n                \"unexpected response from http://detectportal.firefox.com/success.txt, {:?}\",\n                ByteStr::new(&buf)\n            ),\n        ))\n    }\n\n    async fn check_request_udp(&self) -> io::Result<()> {\n        // TransactionID: 0x1234\n        // Flags: 0x0100 RD\n        // Questions: 0x0001\n        // Answer RRs: 0x0000\n        // Authority RRs: 0x0000\n        // Additional RRs: 0x0000\n        // Queries\n        //    - QNAME: \\x07 firefox \\x03 com \\x00\n        //    - QTYPE: 0x0001 A\n        //    - QCLASS: 0x0001 IN\n        const DNS_QUERY: &[u8] =\n            b\"\\x12\\x34\\x01\\x00\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x07firefox\\x03com\\x00\\x00\\x01\\x00\\x01\";\n\n        let addr = Address::SocketAddress(SocketAddr::new(Ipv4Addr::new(8, 8, 8, 8).into(), 53));\n\n        let client = ProxySocket::connect_with_opts(\n            self.context.context(),\n            self.server.server_config(),\n            self.server.connect_opts_ref(),\n        )\n        .await?;\n\n        let mut control = UdpSocketControlData::default();\n        control.client_session_id = rand::random::<u64>();\n        control.packet_id = 1;\n        client.send_with_ctrl(&addr, &control, DNS_QUERY).await?;\n\n        let mut buffer = [0u8; MAXIMUM_UDP_PAYLOAD_SIZE];\n        let (n, ..) = client.recv(&mut buffer).await?;\n\n        let dns_answer = &buffer[..n];\n\n        // DNS packet must have at least 6 * 2 bytes\n        if dns_answer.len() < 12 || &dns_answer[0..2] != b\"\\x12\\x34\" {\n            use std::io::{Error, ErrorKind};\n\n            debug!(\"unexpected response from 8.8.8.8:53, {:?}\", ByteStr::new(dns_answer));\n\n            let err = Error::new(ErrorKind::InvalidData, \"unexpected response from 8.8.8.8:53\");\n            return Err(err);\n        }\n\n        Ok(())\n    }\n\n    async fn check_request(&self) -> io::Result<()> {\n        match self.server_type {\n            ServerType::Tcp => self.check_request_tcp_firefox().await,\n            ServerType::Udp => self.check_request_udp().await,\n        }\n    }\n\n    async fn check_delay(&self) -> io::Result<u32> {\n        let start = Instant::now();\n\n        // Send HTTP GET and read the first byte\n        let res = time::timeout(self.max_server_rtt, self.check_request()).await;\n\n        let elapsed = Instant::now() - start;\n        let elapsed = elapsed.as_secs() as u32 * 1000 + elapsed.subsec_millis(); // Converted to ms\n        match res {\n            Ok(Ok(..)) => {\n                // Got the result ... record its time\n                trace!(\n                    \"checked remote {} server {} latency with {} ms\",\n                    self.server_type,\n                    ServerConfigFormatter::new(self.server.server_config()),\n                    elapsed\n                );\n                Ok(elapsed)\n            }\n            Ok(Err(err)) => {\n                debug!(\n                    \"failed to check {} server {}, error: {}\",\n                    self.server_type,\n                    ServerConfigFormatter::new(self.server.server_config()),\n                    err\n                );\n\n                // NOTE: connection / handshake error, server is down\n                Err(err)\n            }\n            Err(..) => {\n                use std::io::ErrorKind;\n\n                // Timeout\n                trace!(\n                    \"checked remote {} server {} latency timeout, elapsed {} ms\",\n                    self.server_type,\n                    ServerConfigFormatter::new(self.server.server_config()),\n                    elapsed\n                );\n\n                // NOTE: timeout exceeded. Count as error.\n                Err(ErrorKind::TimedOut.into())\n            }\n        }\n    }\n}\n\nstruct ServerConfigFormatter<'a> {\n    server_config: &'a ServerConfig,\n}\n\nimpl<'a> ServerConfigFormatter<'a> {\n    fn new(server_config: &'a ServerConfig) -> Self {\n        ServerConfigFormatter { server_config }\n    }\n}\n\nimpl Display for ServerConfigFormatter<'_> {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        match self.server_config.remarks() {\n            None => Display::fmt(self.server_config.addr(), f),\n            Some(remarks) => {\n                if remarks.is_empty() {\n                    Display::fmt(self.server_config.addr(), f)\n                } else {\n                    write!(f, \"{} ({})\", self.server_config.addr(), remarks)\n                }\n            }\n        }\n    }\n}\n\n/// Server Iterator\npub struct PingServerIter<'a> {\n    #[allow(dead_code)]\n    context: Arc<PingBalancerContext>,\n    iter: std::slice::Iter<'a, Arc<ServerIdent>>,\n}\n\nimpl<'a> Iterator for PingServerIter<'a> {\n    type Item = &'a ServerIdent;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        self.iter.next().map(AsRef::as_ref)\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/loadbalancing/server_data.rs",
    "content": "//! Identifier of server\n\nuse std::{\n    fmt::{self, Debug},\n    net::SocketAddr,\n    sync::{\n        Arc,\n        atomic::{AtomicU32, Ordering},\n    },\n    time::Duration,\n};\n\nuse shadowsocks::{ServerConfig, net::ConnectOpts};\nuse tokio::sync::Mutex;\n\nuse crate::{config::ServerInstanceConfig, local::context::ServiceContext};\n\nuse super::server_stat::{Score, ServerStat, ServerStatData};\n\n/// Server's statistic score\npub struct ServerScore {\n    stat_data: Mutex<ServerStat>,\n    score: AtomicU32,\n}\n\nimpl ServerScore {\n    /// Create a `ServerScore`\n    pub fn new(user_weight: f32, max_server_rtt: Duration, check_window: Duration) -> Self {\n        let max_server_rtt = max_server_rtt.as_millis() as u32;\n        assert!(max_server_rtt > 0);\n\n        Self {\n            stat_data: Mutex::new(ServerStat::new(user_weight, max_server_rtt, check_window)),\n            score: AtomicU32::new(u32::MAX),\n        }\n    }\n\n    /// Get server's current statistic scores\n    pub fn score(&self) -> u32 {\n        self.score.load(Ordering::Acquire)\n    }\n\n    /// Append a `Score` into statistic and recalculate score of the server\n    pub async fn push_score(&self, score: Score) -> u32 {\n        let updated_score = {\n            let mut stat = self.stat_data.lock().await;\n            stat.push_score(score)\n        };\n        self.score.store(updated_score, Ordering::Release);\n        updated_score\n    }\n\n    /// Append a `Score` into statistic and recalculate score of the server\n    pub async fn push_score_fetch_statistic(&self, score: Score) -> (u32, ServerStatData) {\n        let (updated_score, data) = {\n            let mut stat = self.stat_data.lock().await;\n            (stat.push_score(score), *stat.data())\n        };\n        self.score.store(updated_score, Ordering::Release);\n        (updated_score, data)\n    }\n\n    /// Report request failure of this server, which will eventually records an `Errored` score\n    pub async fn report_failure(&self) -> u32 {\n        self.push_score(Score::Errored).await\n    }\n\n    /// Get statistic data\n    pub async fn stat_data(&self) -> ServerStatData {\n        *self.stat_data.lock().await.data()\n    }\n}\n\nimpl Debug for ServerScore {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        f.debug_struct(\"ServerScore\").field(\"score\", &self.score()).finish()\n    }\n}\n\n/// Identifier for a server\n#[derive(Debug)]\npub struct ServerIdent {\n    tcp_score: ServerScore,\n    udp_score: ServerScore,\n    svr_cfg: ServerInstanceConfig,\n    connect_opts: ConnectOpts,\n}\n\nimpl ServerIdent {\n    /// Create a `ServerIdent`\n    pub fn new(\n        context: Arc<ServiceContext>,\n        svr_cfg: ServerInstanceConfig,\n        max_server_rtt: Duration,\n        check_window: Duration,\n    ) -> Self {\n        let mut connect_opts = context.connect_opts_ref().clone();\n\n        #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n        if let Some(fwmark) = svr_cfg.outbound_fwmark {\n            connect_opts.fwmark = Some(fwmark);\n        }\n\n        #[cfg(target_os = \"freebsd\")]\n        if let Some(user_cookie) = svr_cfg.outbound_user_cookie {\n            connect_opts.user_cookie = Some(user_cookie);\n        }\n\n        if let Some(bind_local_addr) = svr_cfg.outbound_bind_addr {\n            connect_opts.bind_local_addr = Some(SocketAddr::new(bind_local_addr, 0));\n        }\n\n        if let Some(ref bind_interface) = svr_cfg.outbound_bind_interface {\n            connect_opts.bind_interface = Some(bind_interface.clone());\n        }\n\n        Self {\n            tcp_score: ServerScore::new(svr_cfg.config.weight().tcp_weight(), max_server_rtt, check_window),\n            udp_score: ServerScore::new(svr_cfg.config.weight().udp_weight(), max_server_rtt, check_window),\n            svr_cfg,\n            connect_opts,\n        }\n    }\n\n    pub fn connect_opts_ref(&self) -> &ConnectOpts {\n        &self.connect_opts\n    }\n\n    pub fn server_config(&self) -> &ServerConfig {\n        &self.svr_cfg.config\n    }\n\n    pub fn server_config_mut(&mut self) -> &mut ServerConfig {\n        &mut self.svr_cfg.config\n    }\n\n    pub fn server_instance_config(&self) -> &ServerInstanceConfig {\n        &self.svr_cfg\n    }\n\n    pub fn tcp_score(&self) -> &ServerScore {\n        &self.tcp_score\n    }\n\n    pub fn udp_score(&self) -> &ServerScore {\n        &self.udp_score\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/loadbalancing/server_stat.rs",
    "content": "//! Server latency statistic\n\nuse std::{\n    collections::VecDeque,\n    time::{Duration, Instant},\n};\n\n/// Interval between each check\npub const DEFAULT_CHECK_INTERVAL_SEC: u64 = 10;\n/// Timeout of each check\npub const DEFAULT_CHECK_TIMEOUT_SEC: u64 = 5; // A common connection timeout of 5 seconds.\n\n/// Statistic score\n#[derive(Debug, Copy, Clone)]\npub enum Score {\n    /// Unified latency\n    Latency(u32),\n    /// Request error\n    Errored,\n}\n\n/// Server statistic data\n#[derive(Debug, Clone, Copy)]\npub struct ServerStatData {\n    /// Median of latency time (in millisec)\n    ///\n    /// Use median instead of average time,\n    /// because probing result may have some really bad cases\n    pub latency_median: u32,\n    /// Total_Fail / Total_Probe\n    pub fail_rate: f64,\n    /// Score's standard deviation\n    pub latency_stdev: f64,\n    /// Score's average\n    pub latency_mean: f64,\n    /// Score's median absolute deviation\n    pub latency_mad: u32,\n}\n\n/// Statistic of a remote server\n#[derive(Debug)]\npub struct ServerStat {\n    /// MAX server's RTT, normally the check timeout milliseconds\n    max_server_rtt: u32,\n    /// Recently probe data\n    latency_queue: VecDeque<(Score, Instant)>,\n    /// Score's standard deviation MAX\n    max_latency_stdev: f64,\n    /// User's customized weight\n    user_weight: f32,\n    /// Checking window size\n    check_window: Duration,\n    /// Statistic Data\n    data: ServerStatData,\n}\n\nfn max_latency_stdev(max_server_rtt: u32) -> f64 {\n    let mrtt = max_server_rtt as f64;\n    let avg = (0.0 + mrtt) / 2.0;\n    let diff1 = (0.0 - avg) * (0.0 - avg);\n    let diff2 = (mrtt - avg) * (mrtt - avg);\n    // (1.0 / (2.0 - 1.0)) * (diff1 + diff2).sqrt()\n    (diff1 + diff2).sqrt()\n}\n\nimpl ServerStat {\n    pub fn new(user_weight: f32, max_server_rtt: u32, check_window: Duration) -> Self {\n        assert!((0.0..=1.0).contains(&user_weight));\n\n        let max_latency_stdev = max_latency_stdev(max_server_rtt);\n        Self {\n            max_server_rtt,\n            latency_queue: VecDeque::new(),\n            max_latency_stdev,\n            user_weight,\n            check_window,\n            data: ServerStatData {\n                latency_median: max_server_rtt,\n                fail_rate: 1.0,\n                latency_stdev: max_latency_stdev,\n                latency_mean: max_server_rtt as f64,\n                latency_mad: max_server_rtt,\n            },\n        }\n    }\n\n    fn score(&self) -> u32 {\n        // Normalize rtt\n        let nrtt = self.data.latency_median as f64 / self.max_server_rtt as f64;\n\n        // Normalize stdev\n        // let nstdev = self.data.latency_stdev / self.max_latency_stdev;\n        // Normalize mad\n        let nmad = self.data.latency_mad as f64 / self.max_server_rtt as f64;\n\n        const SCORE_RTT_WEIGHT: f64 = 1.0;\n        const SCORE_FAIL_WEIGHT: f64 = 3.0;\n        // const SCORE_STDEV_WEIGHT: f64 = 0.0;\n        const SCORE_MAD_WEIGHT: f64 = 1.0;\n\n        // [EPSILON, 1]\n        // Just for avoiding divide by 0\n        let user_weight = self.user_weight.max(f32::EPSILON);\n\n        // Score = (norm_lat * 1.0 + prop_err * 3.0 + (stdev || mad) * 1.0) / 5.0 / user_weight\n        //\n        // 1. The lower latency, the better\n        // 2. The lower errored count, the better\n        // 3. The lower latency's stdev / mad, the better\n        // 4. The higher user's weight, the better\n        let score = (nrtt * SCORE_RTT_WEIGHT + self.data.fail_rate * SCORE_FAIL_WEIGHT + nmad * SCORE_MAD_WEIGHT)\n            / (SCORE_RTT_WEIGHT + SCORE_FAIL_WEIGHT + SCORE_MAD_WEIGHT)\n            / user_weight as f64;\n\n        // Times 10000 converts to u32, for 0.0001 precision\n        (score * 10000.0) as u32\n    }\n\n    pub fn push_score(&mut self, score: Score) -> u32 {\n        let now = Instant::now();\n\n        self.latency_queue.push_back((score, now));\n\n        // Removes stats that are not in the check window\n        while let Some((_, inst)) = self.latency_queue.front() {\n            if now - *inst > self.check_window {\n                self.latency_queue.pop_front();\n            } else {\n                break;\n            }\n        }\n\n        self.recalculate_score()\n    }\n\n    fn recalculate_score(&mut self) -> u32 {\n        if self.latency_queue.is_empty() {\n            return self.score();\n        }\n\n        let mut vlat = Vec::with_capacity(self.latency_queue.len());\n        let mut cerr = 0;\n        for (s, _) in &self.latency_queue {\n            match *s {\n                Score::Errored => cerr += 1,\n                Score::Latency(lat) => vlat.push(lat),\n            }\n        }\n\n        // Error rate\n        self.data.fail_rate = cerr as f64 / self.latency_queue.len() as f64;\n\n        self.data.latency_median = self.max_server_rtt;\n        self.data.latency_stdev = self.max_latency_stdev;\n        self.data.latency_mean = self.max_server_rtt as f64;\n        self.data.latency_mad = self.max_server_rtt;\n\n        if !vlat.is_empty() {\n            vlat.sort_unstable();\n\n            // Find median of latency\n            let mid = vlat.len() / 2;\n\n            self.data.latency_median = if vlat.len() % 2 == 0 {\n                (vlat[mid] + vlat[mid - 1]) / 2\n            } else {\n                vlat[mid]\n            };\n\n            if vlat.len() > 1 {\n                let n = vlat.len() as f64;\n\n                // mean\n                let total_lat: u32 = vlat.iter().sum();\n                self.data.latency_mean = total_lat as f64 / n;\n\n                // STDEV\n                let acc_mean_diff_square: f64 = vlat\n                    .iter()\n                    .map(|s| {\n                        let diff = *s as f64 - self.data.latency_mean;\n                        diff * diff\n                    })\n                    .sum();\n                // Corrected Sample Standard Deviation\n                self.data.latency_stdev = (acc_mean_diff_square / (n - 1.0)).sqrt();\n\n                // MAD\n                let mut vlat_abs_diff: Vec<u32> = vlat\n                    .iter()\n                    .map(|s| (*s as i32 - self.data.latency_median as i32).unsigned_abs())\n                    .collect();\n                vlat_abs_diff.sort_unstable();\n\n                let abs_diff_median_mid = vlat_abs_diff.len() / 2;\n                self.data.latency_mad = if vlat_abs_diff.len().is_multiple_of(2) {\n                    (vlat_abs_diff[abs_diff_median_mid] + vlat_abs_diff[abs_diff_median_mid - 1]) / 2\n                } else {\n                    vlat_abs_diff[abs_diff_median_mid]\n                };\n            } else {\n                self.data.latency_mean = vlat[0] as f64;\n                self.data.latency_mad = 0;\n            }\n        }\n\n        self.score()\n    }\n\n    pub fn data(&self) -> &ServerStatData {\n        &self.data\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/mod.rs",
    "content": "//! Shadowsocks Local Server\n\nuse std::{io, net::SocketAddr, sync::Arc, time::Duration};\n\nuse futures::future;\nuse log::trace;\nuse shadowsocks::{\n    config::Mode,\n    net::{AcceptOpts, ConnectOpts},\n};\n\n#[cfg(feature = \"local-flow-stat\")]\nuse crate::{config::LocalFlowStatAddress, net::FlowStat};\nuse crate::{\n    config::{Config, ConfigType, ProtocolType},\n    dns::build_dns_resolver,\n    utils::ServerHandle,\n};\n\nuse self::{\n    context::ServiceContext,\n    loadbalancing::{PingBalancer, PingBalancerBuilder},\n};\n\n#[cfg(feature = \"local-dns\")]\nuse self::dns::{Dns, DnsBuilder};\n#[cfg(feature = \"local-fake-dns\")]\nuse self::fake_dns::{FakeDns, FakeDnsBuilder};\n#[cfg(feature = \"local-http\")]\nuse self::http::{Http, HttpBuilder};\n#[cfg(feature = \"local-online-config\")]\nuse self::online_config::{OnlineConfigService, OnlineConfigServiceBuilder};\n#[cfg(feature = \"local-redir\")]\nuse self::redir::{Redir, RedirBuilder};\nuse self::socks::{Socks, SocksBuilder};\n#[cfg(feature = \"local-tun\")]\nuse self::tun::{Tun, TunBuilder};\n#[cfg(feature = \"local-tunnel\")]\nuse self::tunnel::{Tunnel, TunnelBuilder};\n\npub mod context;\n#[cfg(feature = \"local-dns\")]\npub mod dns;\n#[cfg(feature = \"local-fake-dns\")]\npub mod fake_dns;\n#[cfg(feature = \"local-http\")]\npub mod http;\npub mod loadbalancing;\npub mod net;\n#[cfg(feature = \"local-online-config\")]\npub mod online_config;\n#[cfg(feature = \"local-redir\")]\npub mod redir;\npub mod socks;\n#[cfg(feature = \"local-tun\")]\npub mod tun;\n#[cfg(feature = \"local-tunnel\")]\npub mod tunnel;\npub mod utils;\n\n/// Default TCP Keep Alive timeout\n///\n/// This is borrowed from Go's `net` library's default setting\npub(crate) const LOCAL_DEFAULT_KEEPALIVE_TIMEOUT: Duration = Duration::from_secs(15);\n\n/// Local Server instance\npub struct Server {\n    balancer: PingBalancer,\n    socks_servers: Vec<Socks>,\n    #[cfg(feature = \"local-tunnel\")]\n    tunnel_servers: Vec<Tunnel>,\n    #[cfg(feature = \"local-http\")]\n    http_servers: Vec<Http>,\n    #[cfg(feature = \"local-tun\")]\n    tun_servers: Vec<Tun>,\n    #[cfg(feature = \"local-dns\")]\n    dns_servers: Vec<Dns>,\n    #[cfg(feature = \"local-redir\")]\n    redir_servers: Vec<Redir>,\n    #[cfg(feature = \"local-fake-dns\")]\n    fake_dns_servers: Vec<FakeDns>,\n    #[cfg(feature = \"local-flow-stat\")]\n    local_stat_addr: Option<LocalFlowStatAddress>,\n    #[cfg(feature = \"local-flow-stat\")]\n    flow_stat: Arc<FlowStat>,\n    #[cfg(feature = \"local-online-config\")]\n    online_config: Option<OnlineConfigService>,\n}\n\nimpl Server {\n    /// Create a shadowsocks local server\n    pub async fn new(config: Config) -> io::Result<Self> {\n        assert!(config.config_type == ConfigType::Local && !config.local.is_empty());\n\n        trace!(\"{:?}\", config);\n\n        // Warning for Stream Ciphers\n        // NOTE: This will only check servers in config.\n        #[cfg(feature = \"stream-cipher\")]\n        for inst in config.server.iter() {\n            let server = &inst.config;\n\n            if server.method().is_stream() {\n                log::warn!(\n                    \"stream cipher {} for server {} have inherent weaknesses (see discussion in https://github.com/shadowsocks/shadowsocks-org/issues/36). \\\n                    DO NOT USE. It will be removed in the future.\",\n                    server.method(),\n                    server.addr()\n                );\n            }\n        }\n\n        #[cfg(all(unix, not(target_os = \"android\")))]\n        if let Some(nofile) = config.nofile {\n            use crate::sys::set_nofile;\n            if let Err(err) = set_nofile(nofile) {\n                log::warn!(\"set_nofile {} failed, error: {}\", nofile, err);\n            }\n        }\n\n        // Global ServiceContext template\n        // Each Local instance will hold a copy of its fields\n        let mut context = ServiceContext::new();\n\n        let mut connect_opts = ConnectOpts {\n            #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n            fwmark: config.outbound_fwmark,\n            #[cfg(target_os = \"freebsd\")]\n            user_cookie: config.outbound_user_cookie,\n\n            #[cfg(target_os = \"android\")]\n            vpn_protect_path: config.outbound_vpn_protect_path,\n\n            bind_interface: config.outbound_bind_interface,\n            bind_local_addr: config.outbound_bind_addr.map(|ip| SocketAddr::new(ip, 0)),\n\n            ..Default::default()\n        };\n        connect_opts.tcp.send_buffer_size = config.outbound_send_buffer_size;\n        connect_opts.tcp.recv_buffer_size = config.outbound_recv_buffer_size;\n        connect_opts.tcp.nodelay = config.no_delay;\n        connect_opts.tcp.fastopen = config.fast_open;\n        connect_opts.tcp.keepalive = config.keep_alive.or(Some(LOCAL_DEFAULT_KEEPALIVE_TIMEOUT));\n        connect_opts.tcp.mptcp = config.mptcp;\n        connect_opts.udp.mtu = config.udp_mtu;\n        connect_opts.udp.allow_fragmentation = config.outbound_udp_allow_fragmentation;\n        context.set_connect_opts(connect_opts);\n\n        let mut accept_opts = AcceptOpts {\n            ipv6_only: config.ipv6_only,\n            ..Default::default()\n        };\n        accept_opts.tcp.send_buffer_size = config.inbound_send_buffer_size;\n        accept_opts.tcp.recv_buffer_size = config.inbound_recv_buffer_size;\n        accept_opts.tcp.nodelay = config.no_delay;\n        accept_opts.tcp.fastopen = config.fast_open;\n        accept_opts.tcp.keepalive = config.keep_alive.or(Some(LOCAL_DEFAULT_KEEPALIVE_TIMEOUT));\n        accept_opts.tcp.mptcp = config.mptcp;\n        accept_opts.udp.mtu = config.udp_mtu;\n        context.set_accept_opts(accept_opts);\n\n        if let Some(resolver) = build_dns_resolver(\n            config.dns,\n            config.ipv6_first,\n            config.dns_cache_size,\n            context.connect_opts_ref(),\n        )\n        .await\n        {\n            context.set_dns_resolver(Arc::new(resolver));\n        }\n\n        if config.ipv6_first {\n            context.set_ipv6_first(config.ipv6_first);\n        }\n\n        if let Some(acl) = config.acl {\n            context.set_acl(Arc::new(acl));\n        }\n\n        context.set_security_config(&config.security);\n\n        assert!(!config.local.is_empty(), \"no valid local server configuration\");\n\n        // Create a service balancer for choosing between multiple servers\n        let balancer = {\n            let mut mode: Option<Mode> = None;\n\n            for local in &config.local {\n                mode = Some(match mode {\n                    None => local.config.mode,\n                    Some(m) => m.merge(local.config.mode),\n                });\n            }\n\n            let mode = mode.unwrap_or(Mode::TcpOnly);\n\n            // Load balancer will hold an individual ServiceContext\n            let mut balancer_builder = PingBalancerBuilder::new(Arc::new(context.clone()), mode);\n\n            // max_server_rtt have to be set before add_server\n            if let Some(rtt) = config.balancer.max_server_rtt {\n                balancer_builder.max_server_rtt(rtt);\n            }\n\n            if let Some(intv) = config.balancer.check_interval {\n                balancer_builder.check_interval(intv);\n            }\n\n            if let Some(intv) = config.balancer.check_best_interval {\n                balancer_builder.check_best_interval(intv);\n            }\n\n            for server in config.server {\n                balancer_builder.add_server(server);\n            }\n\n            balancer_builder.build().await?\n        };\n\n        let mut local_server = Self {\n            balancer: balancer.clone(),\n            socks_servers: Vec::new(),\n            #[cfg(feature = \"local-tunnel\")]\n            tunnel_servers: Vec::new(),\n            #[cfg(feature = \"local-http\")]\n            http_servers: Vec::new(),\n            #[cfg(feature = \"local-tun\")]\n            tun_servers: Vec::new(),\n            #[cfg(feature = \"local-dns\")]\n            dns_servers: Vec::new(),\n            #[cfg(feature = \"local-redir\")]\n            redir_servers: Vec::new(),\n            #[cfg(feature = \"local-fake-dns\")]\n            fake_dns_servers: Vec::new(),\n            #[cfg(feature = \"local-flow-stat\")]\n            local_stat_addr: config.local_stat_addr,\n            #[cfg(feature = \"local-flow-stat\")]\n            flow_stat: context.flow_stat(),\n            #[cfg(feature = \"local-online-config\")]\n            online_config: match config.online_config {\n                None => None,\n                Some(online_config) => {\n                    let mut builder = OnlineConfigServiceBuilder::new(\n                        Arc::new(context.clone()),\n                        online_config.config_url,\n                        balancer.clone(),\n                    );\n                    if let Some(update_interval) = online_config.update_interval {\n                        builder.set_update_interval(update_interval);\n                    }\n                    Some(builder.build().await?)\n                }\n            },\n        };\n\n        for local_instance in config.local {\n            let local_config = local_instance.config;\n\n            // Clone from global ServiceContext instance\n            // It will shares Shadowsocks' global context, and FlowStat, DNS reverse cache\n            let mut context = context.clone();\n\n            // Private ACL\n            if let Some(acl) = local_instance.acl {\n                context.set_acl(Arc::new(acl))\n            }\n\n            let context = Arc::new(context);\n            let balancer = balancer.clone();\n\n            match local_config.protocol {\n                ProtocolType::Socks => {\n                    let client_addr = match local_config.addr {\n                        Some(a) => a,\n                        None => return Err(io::Error::other(\"socks requires local address\")),\n                    };\n\n                    let mut server_builder = SocksBuilder::with_context(context.clone(), client_addr, balancer);\n                    server_builder.set_mode(local_config.mode);\n                    server_builder.set_socks5_auth(local_config.socks5_auth);\n                    #[cfg(feature = \"local-http\")]\n                    server_builder.set_http_auth(local_config.http_auth);\n\n                    if let Some(c) = config.udp_max_associations {\n                        server_builder.set_udp_capacity(c);\n                    }\n                    if let Some(d) = config.udp_timeout {\n                        server_builder.set_udp_expiry_duration(d);\n                    }\n                    if let Some(b) = local_config.udp_addr {\n                        server_builder.set_udp_bind_addr(b.clone());\n                    }\n                    if let Some(b) = local_config.udp_associate_addr {\n                        server_builder.set_udp_associate_addr(b.clone());\n                    }\n\n                    #[cfg(target_os = \"macos\")]\n                    if let Some(n) = local_config.launchd_tcp_socket_name {\n                        server_builder.set_launchd_tcp_socket_name(n);\n                    }\n                    #[cfg(target_os = \"macos\")]\n                    if let Some(n) = local_config.launchd_udp_socket_name {\n                        server_builder.set_launchd_udp_socket_name(n);\n                    }\n\n                    let server = server_builder.build().await?;\n                    local_server.socks_servers.push(server);\n                }\n                #[cfg(feature = \"local-tunnel\")]\n                ProtocolType::Tunnel => {\n                    let client_addr = match local_config.addr {\n                        Some(a) => a,\n                        None => return Err(io::Error::other(\"tunnel requires local address\")),\n                    };\n\n                    let forward_addr = local_config.forward_addr.expect(\"tunnel requires forward address\");\n\n                    let mut server_builder =\n                        TunnelBuilder::with_context(context.clone(), forward_addr.clone(), client_addr, balancer);\n\n                    if let Some(c) = config.udp_max_associations {\n                        server_builder.set_udp_capacity(c);\n                    }\n                    if let Some(d) = config.udp_timeout {\n                        server_builder.set_udp_expiry_duration(d);\n                    }\n                    server_builder.set_mode(local_config.mode);\n                    if let Some(udp_addr) = local_config.udp_addr {\n                        server_builder.set_udp_bind_addr(udp_addr);\n                    }\n\n                    #[cfg(target_os = \"macos\")]\n                    if let Some(n) = local_config.launchd_tcp_socket_name {\n                        server_builder.set_launchd_tcp_socket_name(n);\n                    }\n                    #[cfg(target_os = \"macos\")]\n                    if let Some(n) = local_config.launchd_udp_socket_name {\n                        server_builder.set_launchd_udp_socket_name(n);\n                    }\n\n                    let server = server_builder.build().await?;\n                    local_server.tunnel_servers.push(server);\n                }\n                #[cfg(feature = \"local-http\")]\n                ProtocolType::Http => {\n                    let client_addr = match local_config.addr {\n                        Some(a) => a,\n                        None => return Err(io::Error::other(\"http requires local address\")),\n                    };\n\n                    #[allow(unused_mut)]\n                    let mut builder = HttpBuilder::with_context(context.clone(), client_addr, balancer);\n                    builder.set_http_auth(local_config.http_auth);\n\n                    #[cfg(target_os = \"macos\")]\n                    if let Some(n) = local_config.launchd_tcp_socket_name {\n                        builder.set_launchd_tcp_socket_name(n);\n                    }\n\n                    let server = builder.build().await?;\n                    local_server.http_servers.push(server);\n                }\n                #[cfg(feature = \"local-redir\")]\n                ProtocolType::Redir => {\n                    let client_addr = match local_config.addr {\n                        Some(a) => a,\n                        None => return Err(io::Error::other(\"redir requires local address\")),\n                    };\n\n                    let mut server_builder = RedirBuilder::with_context(context.clone(), client_addr, balancer);\n                    if let Some(c) = config.udp_max_associations {\n                        server_builder.set_udp_capacity(c);\n                    }\n                    if let Some(d) = config.udp_timeout {\n                        server_builder.set_udp_expiry_duration(d);\n                    }\n                    server_builder.set_mode(local_config.mode);\n                    server_builder.set_tcp_redir(local_config.tcp_redir);\n                    server_builder.set_udp_redir(local_config.udp_redir);\n                    if let Some(udp_addr) = local_config.udp_addr {\n                        server_builder.set_udp_bind_addr(udp_addr);\n                    }\n\n                    let server = server_builder.build().await?;\n                    local_server.redir_servers.push(server);\n                }\n                #[cfg(feature = \"local-dns\")]\n                ProtocolType::Dns => {\n                    let client_addr = match local_config.addr {\n                        Some(a) => a,\n                        None => return Err(io::Error::other(\"dns requires local address\")),\n                    };\n\n                    let mut server_builder = {\n                        let local_addr = local_config.local_dns_addr.expect(\"missing local_dns_addr\");\n                        let remote_addr = local_config.remote_dns_addr.expect(\"missing remote_dns_addr\");\n                        let client_cache_size = local_config.client_cache_size.unwrap_or(5);\n\n                        DnsBuilder::with_context(\n                            context.clone(),\n                            client_addr,\n                            local_addr.clone(),\n                            remote_addr.clone(),\n                            balancer,\n                            client_cache_size,\n                        )\n                    };\n                    server_builder.set_mode(local_config.mode);\n\n                    #[cfg(target_os = \"macos\")]\n                    if let Some(n) = local_config.launchd_tcp_socket_name {\n                        server_builder.set_launchd_tcp_socket_name(n);\n                    }\n                    #[cfg(target_os = \"macos\")]\n                    if let Some(n) = local_config.launchd_udp_socket_name {\n                        server_builder.set_launchd_udp_socket_name(n);\n                    }\n\n                    let server = server_builder.build().await?;\n                    local_server.dns_servers.push(server);\n                }\n                #[cfg(feature = \"local-tun\")]\n                ProtocolType::Tun => {\n                    let mut builder = TunBuilder::new(context.clone(), balancer);\n                    if let Some(address) = local_config.tun_interface_address {\n                        builder.address(address);\n                    }\n                    if let Some(address) = local_config.tun_interface_destination {\n                        builder.destination(address);\n                    }\n                    if let Some(name) = local_config.tun_interface_name {\n                        builder.name(&name);\n                    }\n                    if let Some(c) = config.udp_max_associations {\n                        builder.udp_capacity(c);\n                    }\n                    if let Some(d) = config.udp_timeout {\n                        builder.udp_expiry_duration(d);\n                    }\n                    builder.mode(local_config.mode);\n                    #[cfg(unix)]\n                    if let Some(fd) = local_config.tun_device_fd {\n                        builder.file_descriptor(fd);\n                    } else if let Some(ref fd_path) = local_config.tun_device_fd_from_path {\n                        use std::fs;\n\n                        use log::info;\n                        use shadowsocks::net::UnixListener;\n\n                        let _ = fs::remove_file(fd_path);\n\n                        let listener = match UnixListener::bind(fd_path) {\n                            Ok(l) => l,\n                            Err(err) => {\n                                log::error!(\"failed to bind uds path \\\"{}\\\", error: {}\", fd_path.display(), err);\n                                return Err(err);\n                            }\n                        };\n\n                        info!(\"waiting tun's file descriptor from {}\", fd_path.display());\n\n                        loop {\n                            let (mut stream, peer_addr) = listener.accept().await?;\n                            trace!(\"accepted {:?} for receiving tun file descriptor\", peer_addr);\n\n                            let mut buffer = [0u8; 1024];\n                            let mut fd_buffer = [0];\n\n                            match stream.recv_with_fd(&mut buffer, &mut fd_buffer).await {\n                                Ok((n, fd_size)) => {\n                                    if fd_size == 0 {\n                                        log::error!(\n                                            \"client {:?} didn't send file descriptors with buffer.size {} bytes\",\n                                            peer_addr,\n                                            n\n                                        );\n                                        continue;\n                                    }\n\n                                    info!(\"got file descriptor {} for tun from {:?}\", fd_buffer[0], peer_addr);\n\n                                    builder.file_descriptor(fd_buffer[0]);\n                                    break;\n                                }\n                                Err(err) => {\n                                    log::error!(\n                                        \"failed to receive file descriptors from {:?}, error: {}\",\n                                        peer_addr,\n                                        err\n                                    );\n                                }\n                            }\n                        }\n                    }\n                    let server = builder.build().await?;\n                    local_server.tun_servers.push(server);\n                }\n                #[cfg(feature = \"local-fake-dns\")]\n                ProtocolType::FakeDns => {\n                    let client_addr = match local_config.addr {\n                        Some(a) => a,\n                        None => return Err(io::Error::other(\"dns requires local address\")),\n                    };\n\n                    let mut builder = FakeDnsBuilder::new(client_addr);\n                    if let Some(n) = local_config.fake_dns_ipv4_network {\n                        builder.set_ipv4_network(n);\n                    }\n                    if let Some(n) = local_config.fake_dns_ipv6_network {\n                        builder.set_ipv6_network(n);\n                    }\n                    if let Some(exp) = local_config.fake_dns_record_expire_duration {\n                        builder.set_expire_duration(exp);\n                    }\n                    if let Some(p) = local_config.fake_dns_database_path {\n                        builder.set_database_path(p);\n                    }\n                    let server = builder.build().await?;\n                    #[cfg(feature = \"local-fake-dns\")]\n                    context.add_fake_dns_manager(server.clone_manager()).await;\n\n                    local_server.fake_dns_servers.push(server);\n                }\n            }\n        }\n\n        Ok(local_server)\n    }\n\n    /// Run local server\n    pub async fn run(self) -> io::Result<()> {\n        let mut vfut = Vec::new();\n\n        for svr in self.socks_servers {\n            vfut.push(ServerHandle(tokio::spawn(svr.run())));\n        }\n\n        #[cfg(feature = \"local-tunnel\")]\n        for svr in self.tunnel_servers {\n            vfut.push(ServerHandle(tokio::spawn(svr.run())));\n        }\n\n        #[cfg(feature = \"local-http\")]\n        for svr in self.http_servers {\n            vfut.push(ServerHandle(tokio::spawn(svr.run())));\n        }\n\n        #[cfg(feature = \"local-tun\")]\n        for svr in self.tun_servers {\n            vfut.push(ServerHandle(tokio::spawn(svr.run())));\n        }\n\n        #[cfg(feature = \"local-dns\")]\n        for svr in self.dns_servers {\n            vfut.push(ServerHandle(tokio::spawn(svr.run())));\n        }\n\n        #[cfg(feature = \"local-redir\")]\n        for svr in self.redir_servers {\n            vfut.push(ServerHandle(tokio::spawn(svr.run())));\n        }\n\n        #[cfg(feature = \"local-fake-dns\")]\n        for svr in self.fake_dns_servers {\n            vfut.push(ServerHandle(tokio::spawn(svr.run())));\n        }\n\n        #[cfg(feature = \"local-flow-stat\")]\n        if let Some(stat_addr) = self.local_stat_addr {\n            // For Android's flow statistic\n\n            let report_fut = flow_report_task(stat_addr, self.flow_stat);\n            vfut.push(ServerHandle(tokio::spawn(report_fut)));\n        }\n\n        #[cfg(feature = \"local-online-config\")]\n        if let Some(online_config) = self.online_config {\n            vfut.push(ServerHandle(tokio::spawn(online_config.run())));\n        }\n\n        let (res, ..) = future::select_all(vfut).await;\n        res\n    }\n\n    /// Get the internal server balancer\n    pub fn server_balancer(&self) -> &PingBalancer {\n        &self.balancer\n    }\n\n    /// Get SOCKS server instances\n    pub fn socks_servers(&self) -> &[Socks] {\n        &self.socks_servers\n    }\n\n    /// Get Tunnel server instances\n    #[cfg(feature = \"local-tunnel\")]\n    pub fn tunnel_servers(&self) -> &[Tunnel] {\n        &self.tunnel_servers\n    }\n\n    /// Get HTTP server instances\n    #[cfg(feature = \"local-http\")]\n    pub fn http_servers(&self) -> &[Http] {\n        &self.http_servers\n    }\n\n    /// Get Tun server instances\n    #[cfg(feature = \"local-tun\")]\n    pub fn tun_servers(&self) -> &[Tun] {\n        &self.tun_servers\n    }\n\n    /// Get DNS server instances\n    #[cfg(feature = \"local-dns\")]\n    pub fn dns_servers(&self) -> &[Dns] {\n        &self.dns_servers\n    }\n\n    /// Get Redir server instances\n    #[cfg(feature = \"local-redir\")]\n    pub fn redir_servers(&self) -> &[Redir] {\n        &self.redir_servers\n    }\n\n    /// Get Fake DNS instances\n    #[cfg(feature = \"local-fake-dns\")]\n    pub fn fake_dns_servers(&self) -> &[FakeDns] {\n        &self.fake_dns_servers\n    }\n}\n\n#[cfg(feature = \"local-flow-stat\")]\nasync fn flow_report_task(stat_addr: LocalFlowStatAddress, flow_stat: Arc<FlowStat>) -> io::Result<()> {\n    use std::slice;\n\n    use log::debug;\n    use tokio::{io::AsyncWriteExt, time};\n\n    // Local flow statistic report RPC\n    let timeout = Duration::from_secs(1);\n\n    loop {\n        // keep it as libev's default, 0.5 seconds\n        time::sleep(Duration::from_millis(500)).await;\n\n        let tx = flow_stat.tx();\n        let rx = flow_stat.rx();\n\n        let buf: [u64; 2] = [tx, rx];\n        let buf = unsafe { slice::from_raw_parts(buf.as_ptr() as *const _, 16) };\n\n        match stat_addr {\n            #[cfg(unix)]\n            LocalFlowStatAddress::UnixStreamPath(ref stat_path) => {\n                use tokio::net::UnixStream;\n\n                let mut stream = match time::timeout(timeout, UnixStream::connect(stat_path)).await {\n                    Ok(Ok(s)) => s,\n                    Ok(Err(err)) => {\n                        debug!(\"send client flow statistic error: {}\", err);\n                        continue;\n                    }\n                    Err(..) => {\n                        debug!(\"send client flow statistic error: timeout\");\n                        continue;\n                    }\n                };\n\n                match time::timeout(timeout, stream.write_all(buf)).await {\n                    Ok(Ok(..)) => {}\n                    Ok(Err(err)) => {\n                        debug!(\"send client flow statistic error: {}\", err);\n                    }\n                    Err(..) => {\n                        debug!(\"send client flow statistic error: timeout\");\n                    }\n                }\n            }\n            LocalFlowStatAddress::TcpStreamAddr(stat_addr) => {\n                use tokio::net::TcpStream;\n\n                let mut stream = match time::timeout(timeout, TcpStream::connect(stat_addr)).await {\n                    Ok(Ok(s)) => s,\n                    Ok(Err(err)) => {\n                        debug!(\"send client flow statistic error: {}\", err);\n                        continue;\n                    }\n                    Err(..) => {\n                        debug!(\"send client flow statistic error: timeout\");\n                        continue;\n                    }\n                };\n\n                match time::timeout(timeout, stream.write_all(buf)).await {\n                    Ok(Ok(..)) => {}\n                    Ok(Err(err)) => {\n                        debug!(\"send client flow statistic error: {}\", err);\n                    }\n                    Err(..) => {\n                        debug!(\"send client flow statistic error: timeout\");\n                    }\n                }\n            }\n        }\n    }\n}\n\n/// Create then run a Local Server\npub async fn run(config: Config) -> io::Result<()> {\n    Server::new(config).await?.run().await\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/net/mod.rs",
    "content": "//! Shadowsocks Local Network Utilities\n\npub use self::{\n    tcp::{auto_proxy_io::AutoProxyIo, auto_proxy_stream::AutoProxyClientStream},\n    udp::{UdpAssociationManager, UdpInboundWrite},\n};\n\npub(crate) mod tcp;\npub(crate) mod udp;\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/net/tcp/auto_proxy_io.rs",
    "content": "//! Trait of auto-proxy I/O\n\n/// Proxy I/O chooses bypass or proxy automatically\npub trait AutoProxyIo {\n    /// Check if the current connection is proxied\n    fn is_proxied(&self) -> bool;\n\n    /// Check if the current connection is bypassed\n    fn is_bypassed(&self) -> bool {\n        !self.is_proxied()\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/net/tcp/auto_proxy_stream.rs",
    "content": "//! A `ProxyStream` that bypasses or proxies data through proxy server automatically\n\nuse std::{\n    io::{self, IoSlice},\n    net::SocketAddr,\n    pin::Pin,\n    sync::Arc,\n    task::{self, Poll},\n};\n\nuse log::trace;\nuse pin_project::pin_project;\nuse shadowsocks::{\n    net::{ConnectOpts, TcpStream},\n    relay::{socks5::Address, tcprelay::proxy_stream::ProxyClientStream},\n};\nuse tokio::io::{AsyncRead, AsyncWrite, ReadBuf};\n\nuse crate::{\n    local::{context::ServiceContext, loadbalancing::ServerIdent},\n    net::MonProxyStream,\n};\n\nuse super::auto_proxy_io::AutoProxyIo;\n\n/// Unified stream for bypassed and proxied connections\n#[allow(clippy::large_enum_variant)]\n#[pin_project(project = AutoProxyClientStreamProj)]\npub enum AutoProxyClientStream {\n    Proxied(#[pin] ProxyClientStream<MonProxyStream<TcpStream>>),\n    Bypassed(#[pin] TcpStream),\n}\n\nimpl AutoProxyClientStream {\n    /// Connect to target `addr` via shadowsocks' server configured by `svr_cfg`\n    pub async fn connect<A>(context: Arc<ServiceContext>, server: &ServerIdent, addr: A) -> io::Result<Self>\n    where\n        A: Into<Address>,\n    {\n        Self::connect_with_opts(context.clone(), server, addr, context.connect_opts_ref()).await\n    }\n\n    /// Connect to target `addr` via shadowsocks' server configured by `svr_cfg`\n    pub async fn connect_with_opts<A>(\n        context: Arc<ServiceContext>,\n        server: &ServerIdent,\n        addr: A,\n        opts: &ConnectOpts,\n    ) -> io::Result<Self>\n    where\n        A: Into<Address>,\n    {\n        #[cfg_attr(not(feature = \"local-fake-dns\"), allow(unused_mut))]\n        let mut addr = addr.into();\n        #[cfg(feature = \"local-fake-dns\")]\n        if let Some(mapped_addr) = context.try_map_fake_address(&addr).await {\n            addr = mapped_addr;\n        }\n        if context.check_target_bypassed(&addr).await {\n            trace!(\"Bypassing target address {addr}\");\n            Self::connect_bypassed_with_opts_inner(context, addr, opts).await\n        } else {\n            trace!(\"Proxying target address {addr}\");\n            Self::connect_proxied_with_opts_inner(context, server, addr, opts).await\n        }\n    }\n\n    /// Connect directly to target `addr`\n    pub async fn connect_bypassed<A>(context: Arc<ServiceContext>, addr: A) -> io::Result<Self>\n    where\n        A: Into<Address>,\n    {\n        Self::connect_bypassed_with_opts(context.clone(), addr, context.connect_opts_ref()).await\n    }\n\n    /// Connect directly to target `addr`\n    pub async fn connect_bypassed_with_opts<A>(\n        context: Arc<ServiceContext>,\n        addr: A,\n        connect_opts: &ConnectOpts,\n    ) -> io::Result<Self>\n    where\n        A: Into<Address>,\n    {\n        // Connect directly.\n        #[cfg_attr(not(feature = \"local-fake-dns\"), allow(unused_mut))]\n        let mut addr = addr.into();\n        #[cfg(feature = \"local-fake-dns\")]\n        if let Some(mapped_addr) = context.try_map_fake_address(&addr).await {\n            addr = mapped_addr;\n        }\n        Self::connect_bypassed_with_opts_inner(context, addr, connect_opts).await\n    }\n\n    async fn connect_bypassed_with_opts_inner<A>(\n        context: Arc<ServiceContext>,\n        addr: A,\n        connect_opts: &ConnectOpts,\n    ) -> io::Result<Self>\n    where\n        A: Into<Address>,\n    {\n        let addr = addr.into();\n        let stream = TcpStream::connect_remote_with_opts(context.context_ref(), &addr, connect_opts).await?;\n        Ok(Self::Bypassed(stream))\n    }\n\n    /// Connect to target `addr` via shadowsocks' server configured by `svr_cfg`\n    pub async fn connect_proxied<A>(context: Arc<ServiceContext>, server: &ServerIdent, addr: A) -> io::Result<Self>\n    where\n        A: Into<Address>,\n    {\n        Self::connect_proxied_with_opts(context.clone(), server, addr, context.connect_opts_ref()).await\n    }\n\n    /// Connect to target `addr` via shadowsocks' server configured by `svr_cfg`\n    pub async fn connect_proxied_with_opts<A>(\n        context: Arc<ServiceContext>,\n        server: &ServerIdent,\n        addr: A,\n        connect_opts: &ConnectOpts,\n    ) -> io::Result<Self>\n    where\n        A: Into<Address>,\n    {\n        #[cfg_attr(not(feature = \"local-fake-dns\"), allow(unused_mut))]\n        let mut addr = addr.into();\n        #[cfg(feature = \"local-fake-dns\")]\n        if let Some(mapped_addr) = context.try_map_fake_address(&addr).await {\n            addr = mapped_addr;\n        }\n        Self::connect_proxied_with_opts_inner(context, server, addr, connect_opts).await\n    }\n\n    async fn connect_proxied_with_opts_inner<A>(\n        context: Arc<ServiceContext>,\n        server: &ServerIdent,\n        addr: A,\n        connect_opts: &ConnectOpts,\n    ) -> io::Result<Self>\n    where\n        A: Into<Address>,\n    {\n        let flow_stat = context.flow_stat();\n        let stream = match ProxyClientStream::connect_with_opts_map(\n            context.context(),\n            server.server_config(),\n            addr,\n            connect_opts,\n            |stream| MonProxyStream::from_stream(stream, flow_stat),\n        )\n        .await\n        {\n            Ok(s) => s,\n            Err(err) => {\n                server.tcp_score().report_failure().await;\n                return Err(err);\n            }\n        };\n        Ok(Self::Proxied(stream))\n    }\n\n    pub fn local_addr(&self) -> io::Result<SocketAddr> {\n        match *self {\n            Self::Proxied(ref s) => s.get_ref().get_ref().local_addr(),\n            Self::Bypassed(ref s) => s.local_addr(),\n        }\n    }\n\n    pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {\n        match *self {\n            Self::Proxied(ref s) => s.get_ref().get_ref().set_nodelay(nodelay),\n            Self::Bypassed(ref s) => s.set_nodelay(nodelay),\n        }\n    }\n}\n\nimpl AutoProxyIo for AutoProxyClientStream {\n    fn is_proxied(&self) -> bool {\n        matches!(*self, Self::Proxied(..))\n    }\n}\n\nimpl AsyncRead for AutoProxyClientStream {\n    fn poll_read(self: Pin<&mut Self>, cx: &mut task::Context<'_>, buf: &mut ReadBuf<'_>) -> Poll<io::Result<()>> {\n        match self.project() {\n            AutoProxyClientStreamProj::Proxied(s) => s.poll_read(cx, buf),\n            AutoProxyClientStreamProj::Bypassed(s) => s.poll_read(cx, buf),\n        }\n    }\n}\n\nimpl AsyncWrite for AutoProxyClientStream {\n    fn poll_write(self: Pin<&mut Self>, cx: &mut task::Context<'_>, buf: &[u8]) -> Poll<io::Result<usize>> {\n        match self.project() {\n            AutoProxyClientStreamProj::Proxied(s) => s.poll_write(cx, buf),\n            AutoProxyClientStreamProj::Bypassed(s) => s.poll_write(cx, buf),\n        }\n    }\n\n    fn poll_flush(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<io::Result<()>> {\n        match self.project() {\n            AutoProxyClientStreamProj::Proxied(s) => s.poll_flush(cx),\n            AutoProxyClientStreamProj::Bypassed(s) => s.poll_flush(cx),\n        }\n    }\n\n    fn poll_shutdown(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<io::Result<()>> {\n        match self.project() {\n            AutoProxyClientStreamProj::Proxied(s) => s.poll_shutdown(cx),\n            AutoProxyClientStreamProj::Bypassed(s) => s.poll_shutdown(cx),\n        }\n    }\n\n    fn poll_write_vectored(\n        self: Pin<&mut Self>,\n        cx: &mut task::Context<'_>,\n        bufs: &[IoSlice<'_>],\n    ) -> Poll<io::Result<usize>> {\n        match self.project() {\n            AutoProxyClientStreamProj::Proxied(s) => s.poll_write_vectored(cx, bufs),\n            AutoProxyClientStreamProj::Bypassed(s) => s.poll_write_vectored(cx, bufs),\n        }\n    }\n}\n\nimpl From<ProxyClientStream<MonProxyStream<TcpStream>>> for AutoProxyClientStream {\n    fn from(s: ProxyClientStream<MonProxyStream<TcpStream>>) -> Self {\n        Self::Proxied(s)\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/net/tcp/listener.rs",
    "content": "//! Local instance listener helpers\n\nuse std::io;\n\nuse shadowsocks::{config::ServerAddr, lookup_then, net::TcpListener};\n\nuse crate::local::context::ServiceContext;\n\n/// Create a standard TCP listener listening on `client_config`\npub async fn create_standard_tcp_listener(\n    context: &ServiceContext,\n    client_config: &ServerAddr,\n) -> io::Result<TcpListener> {\n    match client_config {\n        ServerAddr::SocketAddr(saddr) => TcpListener::bind_with_opts(saddr, context.accept_opts()).await,\n        ServerAddr::DomainName(dname, port) => lookup_then!(context.context_ref(), dname, *port, |addr| {\n            TcpListener::bind_with_opts(&addr, context.accept_opts()).await\n        })\n        .map(|(_, l)| l),\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/net/tcp/mod.rs",
    "content": "pub mod auto_proxy_io;\npub mod auto_proxy_stream;\npub mod listener;\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/net/udp/association.rs",
    "content": "//! UDP Association Managing\n\nuse std::{\n    cell::RefCell,\n    io,\n    marker::PhantomData,\n    net::{SocketAddr, SocketAddrV6},\n    sync::Arc,\n    time::Duration,\n};\n\nuse bytes::Bytes;\nuse futures::future;\nuse log::{debug, error, trace, warn};\nuse lru_time_cache::LruCache;\nuse rand::{RngExt, rngs::SmallRng};\nuse tokio::{sync::mpsc, task::JoinHandle, time};\n\nuse shadowsocks::{\n    lookup_then,\n    net::{AddrFamily, UdpSocket as ShadowUdpSocket},\n    relay::{\n        Address,\n        udprelay::{MAXIMUM_UDP_PAYLOAD_SIZE, ProxySocket, options::UdpSocketControlData},\n    },\n};\n\nuse crate::{\n    local::{context::ServiceContext, loadbalancing::PingBalancer},\n    net::{\n        MonProxySocket, UDP_ASSOCIATION_KEEP_ALIVE_CHANNEL_SIZE, UDP_ASSOCIATION_SEND_CHANNEL_SIZE,\n        packet_window::PacketWindowFilter,\n    },\n};\n\n/// Writer for sending packets back to client\n#[trait_variant::make(Send)]\npub trait UdpInboundWrite {\n    /// Sends packet `data` received from `remote_addr` back to `peer_addr`\n    async fn send_to(&self, peer_addr: SocketAddr, remote_addr: &Address, data: &[u8]) -> io::Result<()>;\n}\n\ntype AssociationMap<W> = LruCache<SocketAddr, UdpAssociation<W>>;\n\n/// UDP association manager\npub struct UdpAssociationManager<W>\nwhere\n    W: UdpInboundWrite + Clone + Send + Sync + Unpin + 'static,\n{\n    respond_writer: W,\n    context: Arc<ServiceContext>,\n    assoc_map: AssociationMap<W>,\n    keepalive_tx: mpsc::Sender<SocketAddr>,\n    balancer: PingBalancer,\n    server_session_expire_duration: Duration,\n}\n\nimpl<W> UdpAssociationManager<W>\nwhere\n    W: UdpInboundWrite + Clone + Send + Sync + Unpin + 'static,\n{\n    /// Create a new `UdpAssociationManager`\n    ///\n    /// Returns (`UdpAssociationManager`, Cleanup Interval, Keep-alive Receiver<SocketAddr>)\n    pub fn new(\n        context: Arc<ServiceContext>,\n        respond_writer: W,\n        time_to_live: Option<Duration>,\n        capacity: Option<usize>,\n        balancer: PingBalancer,\n    ) -> (Self, Duration, mpsc::Receiver<SocketAddr>) {\n        let time_to_live = time_to_live.unwrap_or(crate::DEFAULT_UDP_EXPIRY_DURATION);\n        let assoc_map = match capacity {\n            Some(capacity) => LruCache::with_expiry_duration_and_capacity(time_to_live, capacity),\n            None => LruCache::with_expiry_duration(time_to_live),\n        };\n\n        let (keepalive_tx, keepalive_rx) = mpsc::channel(UDP_ASSOCIATION_KEEP_ALIVE_CHANNEL_SIZE);\n\n        (\n            Self {\n                respond_writer,\n                context,\n                assoc_map,\n                keepalive_tx,\n                balancer,\n                server_session_expire_duration: time_to_live,\n            },\n            time_to_live,\n            keepalive_rx,\n        )\n    }\n\n    /// Sends `data` from `peer_addr` to `target_addr`\n    #[cfg_attr(not(feature = \"local-fake-dns\"), allow(unused_mut))]\n    pub async fn send_to(&mut self, peer_addr: SocketAddr, mut target_addr: Address, data: &[u8]) -> io::Result<()> {\n        #[cfg(feature = \"local-fake-dns\")]\n        if let Some(mapped_addr) = self.context.try_map_fake_address(&target_addr).await {\n            target_addr = mapped_addr;\n        }\n\n        // Check or (re)create an association\n\n        if let Some(assoc) = self.assoc_map.get(&peer_addr) {\n            return assoc.try_send((target_addr, Bytes::copy_from_slice(data)));\n        }\n\n        let assoc = UdpAssociation::new(\n            self.context.clone(),\n            peer_addr,\n            self.keepalive_tx.clone(),\n            self.balancer.clone(),\n            self.respond_writer.clone(),\n            self.server_session_expire_duration,\n        );\n\n        debug!(\"created udp association for {}\", peer_addr);\n\n        assoc.try_send((target_addr, Bytes::copy_from_slice(data)))?;\n        self.assoc_map.insert(peer_addr, assoc);\n\n        Ok(())\n    }\n\n    /// Cleanup expired associations\n    pub async fn cleanup_expired(&mut self) {\n        self.assoc_map.iter();\n    }\n\n    /// Keep-alive association\n    pub async fn keep_alive(&mut self, peer_addr: &SocketAddr) {\n        self.assoc_map.get(peer_addr);\n    }\n}\n\nstruct UdpAssociation<W>\nwhere\n    W: UdpInboundWrite + Send + Sync + Unpin + 'static,\n{\n    assoc_handle: JoinHandle<()>,\n    sender: mpsc::Sender<(Address, Bytes)>,\n    writer: PhantomData<W>,\n}\n\nimpl<W> Drop for UdpAssociation<W>\nwhere\n    W: UdpInboundWrite + Send + Sync + Unpin + 'static,\n{\n    fn drop(&mut self) {\n        self.assoc_handle.abort();\n    }\n}\n\nimpl<W> UdpAssociation<W>\nwhere\n    W: UdpInboundWrite + Send + Sync + Unpin + 'static,\n{\n    fn new(\n        context: Arc<ServiceContext>,\n        peer_addr: SocketAddr,\n        keepalive_tx: mpsc::Sender<SocketAddr>,\n        balancer: PingBalancer,\n        respond_writer: W,\n        server_session_expire_duration: Duration,\n    ) -> Self {\n        let (assoc_handle, sender) = UdpAssociationContext::create(\n            context,\n            peer_addr,\n            keepalive_tx,\n            balancer,\n            respond_writer,\n            server_session_expire_duration,\n        );\n        Self {\n            assoc_handle,\n            sender,\n            writer: PhantomData,\n        }\n    }\n\n    fn try_send(&self, data: (Address, Bytes)) -> io::Result<()> {\n        if self.sender.try_send(data).is_err() {\n            let err = io::Error::other(\"udp relay channel full\");\n            return Err(err);\n        }\n        Ok(())\n    }\n}\n\n#[derive(Debug, Clone)]\nstruct ServerContext {\n    packet_window_filter: PacketWindowFilter,\n}\n\n#[derive(Clone)]\nstruct ServerSessionContext {\n    server_session_map: LruCache<u64, ServerContext>,\n}\n\nimpl ServerSessionContext {\n    fn new(session_expire_duration: Duration) -> Self {\n        Self {\n            server_session_map: LruCache::with_expiry_duration(session_expire_duration),\n        }\n    }\n}\n\nstruct UdpAssociationContext<W>\nwhere\n    W: UdpInboundWrite + Send + Sync + Unpin + 'static,\n{\n    context: Arc<ServiceContext>,\n    peer_addr: SocketAddr,\n    bypassed_ipv4_socket: Option<ShadowUdpSocket>,\n    bypassed_ipv6_socket: Option<ShadowUdpSocket>,\n    proxied_socket: Option<MonProxySocket<ShadowUdpSocket>>,\n    keepalive_tx: mpsc::Sender<SocketAddr>,\n    keepalive_flag: bool,\n    balancer: PingBalancer,\n    respond_writer: W,\n    client_session_id: u64,\n    client_packet_id: u64,\n    server_session: Option<ServerSessionContext>,\n    server_session_expire_duration: Duration,\n}\n\nimpl<W> Drop for UdpAssociationContext<W>\nwhere\n    W: UdpInboundWrite + Send + Sync + Unpin + 'static,\n{\n    fn drop(&mut self) {\n        debug!(\"udp association for {} is closed\", self.peer_addr);\n    }\n}\n\nthread_local! {\n    static CLIENT_SESSION_RNG: RefCell<SmallRng> = RefCell::new(rand::make_rng());\n}\n\n/// Generate an AEAD-2022 Client SessionID\n#[inline]\npub fn generate_client_session_id() -> u64 {\n    loop {\n        let id = CLIENT_SESSION_RNG.with(|rng| rng.borrow_mut().random());\n        if id != 0 {\n            break id;\n        }\n    }\n}\n\nimpl<W> UdpAssociationContext<W>\nwhere\n    W: UdpInboundWrite + Send + Sync + Unpin + 'static,\n{\n    fn create(\n        context: Arc<ServiceContext>,\n        peer_addr: SocketAddr,\n        keepalive_tx: mpsc::Sender<SocketAddr>,\n        balancer: PingBalancer,\n        respond_writer: W,\n        server_session_expire_duration: Duration,\n    ) -> (JoinHandle<()>, mpsc::Sender<(Address, Bytes)>) {\n        // Pending packets UDP_ASSOCIATION_SEND_CHANNEL_SIZE for each association should be good enough for a server.\n        // If there are plenty of packets stuck in the channel, dropping excessive packets is a good way to protect the server from\n        // being OOM.\n        let (sender, receiver) = mpsc::channel(UDP_ASSOCIATION_SEND_CHANNEL_SIZE);\n\n        let mut assoc = Self {\n            context,\n            peer_addr,\n            bypassed_ipv4_socket: None,\n            bypassed_ipv6_socket: None,\n            proxied_socket: None,\n            keepalive_tx,\n            keepalive_flag: false,\n            balancer,\n            respond_writer,\n            // client_session_id must be random generated,\n            // server use this ID to identify every independent clients.\n            client_session_id: generate_client_session_id(),\n            client_packet_id: 0,\n            server_session: None,\n            server_session_expire_duration,\n        };\n        let handle = tokio::spawn(async move { assoc.dispatch_packet(receiver).await });\n\n        (handle, sender)\n    }\n\n    async fn dispatch_packet(&mut self, mut receiver: mpsc::Receiver<(Address, Bytes)>) {\n        let mut bypassed_ipv4_buffer = Vec::new();\n        let mut bypassed_ipv6_buffer = Vec::new();\n        let mut proxied_buffer = Vec::new();\n        let mut keepalive_interval = time::interval(Duration::from_secs(1));\n\n        loop {\n            tokio::select! {\n                packet_received_opt = receiver.recv() => {\n                    let (target_addr, data) = match packet_received_opt {\n                        Some(d) => d,\n                        None => {\n                            trace!(\"udp association for {} -> ... channel closed\", self.peer_addr);\n                            break;\n                        }\n                    };\n\n                    self.dispatch_received_packet(&target_addr, &data).await;\n                }\n\n                received_opt = receive_from_bypassed_opt(&self.bypassed_ipv4_socket, &mut bypassed_ipv4_buffer), if self.bypassed_ipv4_socket.is_some() => {\n                    let (n, addr) = match received_opt {\n                        Ok(r) => r,\n                        Err(err) => {\n                            error!(\"udp relay {} <- ... (bypassed) failed, error: {}\", self.peer_addr, err);\n                            // Socket failure. Reset for recreation.\n                            self.bypassed_ipv4_socket = None;\n                            continue;\n                        }\n                    };\n\n                    let addr = Address::from(addr);\n                    self.send_received_respond_packet(&addr, &bypassed_ipv4_buffer[..n], true).await;\n                }\n\n                received_opt = receive_from_bypassed_opt(&self.bypassed_ipv6_socket, &mut bypassed_ipv6_buffer), if self.bypassed_ipv6_socket.is_some() => {\n                    let (n, addr) = match received_opt {\n                        Ok(r) => r,\n                        Err(err) => {\n                            error!(\"udp relay {} <- ... (bypassed) failed, error: {}\", self.peer_addr, err);\n                            // Socket failure. Reset for recreation.\n                            self.bypassed_ipv6_socket = None;\n                            continue;\n                        }\n                    };\n\n                    let addr = Address::from(addr);\n                    self.send_received_respond_packet(&addr, &bypassed_ipv6_buffer[..n], true).await;\n                }\n\n                received_opt = receive_from_proxied_opt(&self.proxied_socket, &mut proxied_buffer), if self.proxied_socket.is_some() => {\n                    let (n, addr, control_opt) = match received_opt {\n                        Ok(r) => r,\n                        Err(err) => {\n                            error!(\"udp relay {} <- ... (proxied) failed, error: {}\", self.peer_addr, err);\n                            // Socket failure. Reset for recreation.\n                            self.proxied_socket = None;\n                            continue;\n                        }\n                    };\n\n                    if let Some(control) = control_opt {\n                        // Check if Packet ID is in the window\n\n                        let session = self.server_session.get_or_insert_with(|| {\n                            ServerSessionContext::new(self.server_session_expire_duration)\n                        });\n\n                        let packet_id = control.packet_id;\n                        let session_context = session\n                            .server_session_map\n                            .entry(control.server_session_id)\n                            .or_insert_with(|| {\n                                trace!(\n                                    \"udp server with session {} for {} created\",\n                                    control.client_session_id,\n                                    self.peer_addr,\n                                );\n\n                                ServerContext {\n                                    packet_window_filter: PacketWindowFilter::new()\n                                }\n                            });\n\n                        if !session_context.packet_window_filter.validate_packet_id(packet_id, u64::MAX) {\n                            error!(\"udp {} packet_id {} out of window\", self.peer_addr, packet_id);\n                            continue;\n                        }\n                    }\n\n                    self.send_received_respond_packet(&addr, &proxied_buffer[..n], false).await;\n                }\n\n                _ = keepalive_interval.tick() => {\n                    if self.keepalive_flag {\n                        if self.keepalive_tx.try_send(self.peer_addr).is_err() {\n                            debug!(\"udp relay {} keep-alive failed, channel full or closed\", self.peer_addr);\n                        } else {\n                            self.keepalive_flag = false;\n                        }\n                    }\n                }\n            }\n        }\n\n        #[inline]\n        async fn receive_from_bypassed_opt(\n            socket: &Option<ShadowUdpSocket>,\n            buf: &mut Vec<u8>,\n        ) -> io::Result<(usize, SocketAddr)> {\n            match *socket {\n                None => future::pending().await,\n                Some(ref s) => {\n                    if buf.is_empty() {\n                        buf.resize(MAXIMUM_UDP_PAYLOAD_SIZE, 0);\n                    }\n                    s.recv_from(buf).await\n                }\n            }\n        }\n\n        #[inline]\n        async fn receive_from_proxied_opt(\n            socket: &Option<MonProxySocket<ShadowUdpSocket>>,\n            buf: &mut Vec<u8>,\n        ) -> io::Result<(usize, Address, Option<UdpSocketControlData>)> {\n            match *socket {\n                None => future::pending().await,\n                Some(ref s) => {\n                    if buf.is_empty() {\n                        buf.resize(MAXIMUM_UDP_PAYLOAD_SIZE, 0);\n                    }\n                    s.recv_with_ctrl(buf).await\n                }\n            }\n        }\n    }\n\n    async fn dispatch_received_packet(&mut self, target_addr: &Address, data: &[u8]) {\n        // Check if target should be bypassed. If so, send packets directly.\n        let bypassed = self.balancer.is_empty() || self.context.check_target_bypassed(target_addr).await;\n\n        trace!(\n            \"udp relay {} -> {} ({}) with {} bytes\",\n            self.peer_addr,\n            target_addr,\n            if bypassed { \"bypassed\" } else { \"proxied\" },\n            data.len()\n        );\n\n        if bypassed {\n            if let Err(err) = self.dispatch_received_bypassed_packet(target_addr, data).await {\n                error!(\n                    \"udp relay {} -> {} (bypassed) with {} bytes, error: {}\",\n                    self.peer_addr,\n                    target_addr,\n                    data.len(),\n                    err\n                );\n            }\n        } else if let Err(err) = self.dispatch_received_proxied_packet(target_addr, data).await {\n            error!(\n                \"udp relay {} -> {} (proxied) with {} bytes, error: {}\",\n                self.peer_addr,\n                target_addr,\n                data.len(),\n                err\n            );\n        }\n    }\n\n    async fn dispatch_received_bypassed_packet(&mut self, target_addr: &Address, data: &[u8]) -> io::Result<()> {\n        match *target_addr {\n            Address::SocketAddress(sa) => self.send_received_bypassed_packet(sa, data).await,\n            Address::DomainNameAddress(ref dname, port) => {\n                lookup_then!(self.context.context_ref(), dname, port, |sa| {\n                    self.send_received_bypassed_packet(sa, data).await\n                })\n                .map(|_| ())\n            }\n        }\n    }\n\n    async fn send_received_bypassed_packet(&mut self, mut target_addr: SocketAddr, data: &[u8]) -> io::Result<()> {\n        const UDP_SOCKET_SUPPORT_DUAL_STACK: bool = cfg!(any(\n            target_os = \"linux\",\n            target_os = \"android\",\n            target_os = \"macos\",\n            target_os = \"ios\",\n            target_os = \"watchos\",\n            target_os = \"tvos\",\n            target_os = \"freebsd\",\n            target_os = \"windows\",\n        ));\n\n        let socket = if UDP_SOCKET_SUPPORT_DUAL_STACK {\n            match self.bypassed_ipv6_socket {\n                Some(ref mut socket) => socket,\n                None => {\n                    let socket =\n                        ShadowUdpSocket::connect_any_with_opts(AddrFamily::Ipv6, self.context.connect_opts_ref())\n                            .await?;\n                    self.bypassed_ipv6_socket.insert(socket)\n                }\n            }\n        } else {\n            match target_addr {\n                SocketAddr::V4(..) => match self.bypassed_ipv4_socket {\n                    Some(ref mut socket) => socket,\n                    None => {\n                        let socket =\n                            ShadowUdpSocket::connect_any_with_opts(&target_addr, self.context.connect_opts_ref())\n                                .await?;\n                        self.bypassed_ipv4_socket.insert(socket)\n                    }\n                },\n                SocketAddr::V6(..) => match self.bypassed_ipv6_socket {\n                    Some(ref mut socket) => socket,\n                    None => {\n                        let socket =\n                            ShadowUdpSocket::connect_any_with_opts(&target_addr, self.context.connect_opts_ref())\n                                .await?;\n                        self.bypassed_ipv6_socket.insert(socket)\n                    }\n                },\n            }\n        };\n\n        if UDP_SOCKET_SUPPORT_DUAL_STACK && let SocketAddr::V4(saddr) = target_addr {\n            let mapped_ip = saddr.ip().to_ipv6_mapped();\n            target_addr = SocketAddr::V6(SocketAddrV6::new(mapped_ip, saddr.port(), 0, 0));\n        }\n\n        let n = socket.send_to(data, target_addr).await?;\n        if n != data.len() {\n            warn!(\n                \"{} -> {} sent {} bytes != expected {} bytes\",\n                self.peer_addr,\n                target_addr,\n                n,\n                data.len()\n            );\n        }\n\n        Ok(())\n    }\n\n    async fn dispatch_received_proxied_packet(&mut self, target_addr: &Address, data: &[u8]) -> io::Result<()> {\n        // Increase Packet ID before send\n        self.client_packet_id = match self.client_packet_id.checked_add(1) {\n            Some(i) => i,\n            None => {\n                // FIXME: client_packet_id overflowed. What's the proper way to handle this?\n                //\n                // Reopen a new session is not perfect, because the remote target will receive packets from a different address.\n                // For most application protocol, like QUIC, it is fine to change client address.\n                //\n                // But it will happen only when a client continuously send 18446744073709551616 packets without renewing the socket.\n\n                let new_session_id = generate_client_session_id();\n\n                warn!(\n                    \"{} -> {} (proxied) packet id overflowed. socket reset and session renewed ({} -> {})\",\n                    self.peer_addr, target_addr, self.client_session_id, new_session_id\n                );\n\n                self.proxied_socket.take();\n                self.client_packet_id = 1;\n                self.client_session_id = new_session_id;\n\n                self.client_packet_id\n            }\n        };\n\n        let socket = match self.proxied_socket {\n            Some(ref mut socket) => socket,\n            None => {\n                // Create a new connection to proxy server\n\n                let server = self.balancer.best_udp_server();\n                let svr_cfg = server.server_config();\n\n                let socket =\n                    ProxySocket::connect_with_opts(self.context.context(), svr_cfg, server.connect_opts_ref()).await?;\n                let socket = MonProxySocket::from_socket(socket, self.context.flow_stat());\n\n                self.proxied_socket.insert(socket)\n            }\n        };\n\n        let mut control = UdpSocketControlData::default();\n        control.client_session_id = self.client_session_id;\n        control.packet_id = self.client_packet_id;\n\n        match socket.send_with_ctrl(target_addr, &control, data).await {\n            Ok(..) => return Ok(()),\n            Err(err) => {\n                debug!(\n                    \"{} -> {} (proxied) sending {} bytes failed, error: {}\",\n                    self.peer_addr,\n                    target_addr,\n                    data.len(),\n                    err\n                );\n\n                // Drop the socket and reconnect to another server.\n                self.proxied_socket = None;\n            }\n        }\n\n        Ok(())\n    }\n\n    async fn send_received_respond_packet(&mut self, addr: &Address, data: &[u8], bypassed: bool) {\n        trace!(\n            \"udp relay {} <- {} ({}) received {} bytes\",\n            self.peer_addr,\n            addr,\n            if bypassed { \"bypassed\" } else { \"proxied\" },\n            data.len(),\n        );\n\n        // Keep association alive in map\n        self.keepalive_flag = true;\n\n        // Send back to client\n        match self.respond_writer.send_to(self.peer_addr, addr, data).await {\n            Err(err) => {\n                warn!(\n                    \"udp failed to send back {} bytes to client {}, from target {} ({}), error: {}\",\n                    data.len(),\n                    self.peer_addr,\n                    addr,\n                    if bypassed { \"bypassed\" } else { \"proxied\" },\n                    err\n                );\n            }\n            Ok(..) => {\n                trace!(\n                    \"udp relay {} <- {} ({}) with {} bytes\",\n                    self.peer_addr,\n                    addr,\n                    if bypassed { \"bypassed\" } else { \"proxied\" },\n                    data.len()\n                );\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/net/udp/listener.rs",
    "content": "//! Local instance listener helpers\n\nuse std::io;\n\nuse shadowsocks::{config::ServerAddr, lookup_then, net::UdpSocket};\n\nuse crate::local::context::ServiceContext;\n\n/// Create a standard UDP listener listening on `client_config`\npub async fn create_standard_udp_listener(\n    context: &ServiceContext,\n    client_config: &ServerAddr,\n) -> io::Result<UdpSocket> {\n    match client_config {\n        ServerAddr::SocketAddr(saddr) => UdpSocket::listen_with_opts(saddr, context.accept_opts()).await,\n        ServerAddr::DomainName(dname, port) => lookup_then!(context.context_ref(), dname, *port, |addr| {\n            UdpSocket::listen_with_opts(&addr, context.accept_opts()).await\n        })\n        .map(|(_, s)| s),\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/net/udp/mod.rs",
    "content": "#[allow(unused_imports)]\npub use self::association::{UdpAssociationManager, UdpInboundWrite, generate_client_session_id};\n\npub mod association;\npub mod listener;\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/online_config/content_encoding.rs",
    "content": "//! HTTP Body Content-Encoding\n\nuse std::io::{self, Cursor, Read};\n\nuse futures::StreamExt;\nuse http::HeaderValue;\nuse http_body_util::BodyExt;\nuse hyper::body::Body;\n\n/// HTTP Content-Encoding\n#[derive(Debug, Clone, Copy, Default)]\npub enum ContentEncoding {\n    #[default]\n    Identity,\n    Deflate,\n    Gzip,\n    Br,\n    Zstd,\n}\n\n#[derive(Debug, Clone, Copy)]\npub struct ContentEncodingError;\n\nimpl<'a> TryFrom<&'a HeaderValue> for ContentEncoding {\n    type Error = ContentEncodingError;\n\n    fn try_from(value: &'a HeaderValue) -> Result<Self, Self::Error> {\n        if value == HeaderValue::from_static(\"identity\") {\n            Ok(Self::Identity)\n        } else if value == HeaderValue::from_static(\"deflate\") {\n            Ok(Self::Deflate)\n        } else if value == HeaderValue::from_static(\"gzip\") {\n            Ok(Self::Gzip)\n        } else if value == HeaderValue::from_static(\"br\") {\n            Ok(Self::Br)\n        } else if value == HeaderValue::from_static(\"zstd\") {\n            Ok(Self::Zstd)\n        } else {\n            Err(ContentEncodingError)\n        }\n    }\n}\n\n/// Read data from body, decode automatically with specific Content-Encoding\npub async fn read_body<B>(encoding: ContentEncoding, body: &mut B) -> io::Result<Vec<u8>>\nwhere\n    B: Body + Sized + Unpin + 'static,\n    B::Data: AsRef<[u8]>,\n    B::Error: Into<Box<dyn ::std::error::Error + Send + Sync + 'static>>,\n{\n    let mut raw_body = Vec::new();\n\n    let mut body_stream = body.into_data_stream();\n    while let Some(data) = body_stream.next().await {\n        match data {\n            Ok(data) => raw_body.extend_from_slice(data.as_ref()),\n            Err(err) => return Err(io::Error::other(err)),\n        }\n    }\n\n    match encoding {\n        ContentEncoding::Identity => Ok(raw_body),\n\n        ContentEncoding::Deflate => {\n            use flate2::read::DeflateDecoder;\n\n            let mut decoder = DeflateDecoder::new(&raw_body[..]);\n            let mut decoded_body = Vec::new();\n            decoder.read_to_end(&mut decoded_body)?;\n\n            Ok(decoded_body)\n        }\n\n        ContentEncoding::Gzip => {\n            use flate2::read::GzDecoder;\n\n            let mut decoder = GzDecoder::new(&raw_body[..]);\n            let mut decoded_body = Vec::new();\n            decoder.read_to_end(&mut decoded_body)?;\n\n            Ok(decoded_body)\n        }\n\n        ContentEncoding::Br => {\n            let mut decoded_body = Vec::new();\n            brotli::BrotliDecompress(&mut Cursor::new(&raw_body[..]), &mut decoded_body)?;\n            Ok(decoded_body)\n        }\n\n        ContentEncoding::Zstd => zstd::decode_all(Cursor::new(&raw_body[..])),\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/online_config/mod.rs",
    "content": "//! Online Config (SIP008)\n//!\n//! Online Configuration Delivery URL (https://shadowsocks.org/doc/sip008.html)\n\nuse std::{\n    collections::HashSet,\n    io,\n    sync::Arc,\n    time::{Duration, Instant},\n};\n\nuse crate::{\n    config::{Config, ConfigType},\n    local::{context::ServiceContext, http::HttpClient, loadbalancing::PingBalancer},\n};\n\nuse http::StatusCode;\nuse log::{debug, error, trace, warn};\nuse mime::Mime;\nuse shadowsocks::config::ServerSource;\nuse tokio::time;\n\nuse self::content_encoding::{ContentEncoding, read_body};\n\nmod content_encoding;\n\n/// OnlineConfigService builder pattern\npub struct OnlineConfigServiceBuilder {\n    context: Arc<ServiceContext>,\n    config_url: String,\n    balancer: PingBalancer,\n    config_update_interval: Duration,\n    allowed_plugins: Option<HashSet<String>>,\n}\n\nimpl OnlineConfigServiceBuilder {\n    /// Create a Builder\n    pub fn new(context: Arc<ServiceContext>, config_url: String, balancer: PingBalancer) -> Self {\n        Self {\n            context,\n            config_url,\n            balancer,\n            config_update_interval: Duration::from_secs(3600),\n            allowed_plugins: None,\n        }\n    }\n\n    /// Set update interval. Default is 3600s\n    pub fn set_update_interval(&mut self, update_interval: Duration) {\n        self.config_update_interval = update_interval;\n    }\n\n    /// Allowed plugins (whitelist) from SIP008 server\n    pub fn set_allowed_plugins<V, S>(&mut self, allowed_plugins: V)\n    where\n        V: Iterator<Item = S>,\n        S: Into<String>,\n    {\n        let mut allowed_plugins_set = HashSet::new();\n        for plugin in allowed_plugins {\n            allowed_plugins_set.insert(plugin.into());\n        }\n        self.allowed_plugins = Some(allowed_plugins_set);\n    }\n\n    /// Build OnlineConfigService\n    pub async fn build(self) -> io::Result<OnlineConfigService> {\n        let mut service = OnlineConfigService {\n            context: self.context,\n            http_client: HttpClient::new(),\n            config_url: self.config_url,\n            config_update_interval: self.config_update_interval,\n            balancer: self.balancer,\n            allowed_plugins: self.allowed_plugins,\n        };\n\n        // Run once after creation.\n        service.run_once().await?;\n\n        Ok(service)\n    }\n}\n\npub struct OnlineConfigService {\n    context: Arc<ServiceContext>,\n    http_client: HttpClient<String>,\n    config_url: String,\n    config_update_interval: Duration,\n    balancer: PingBalancer,\n    allowed_plugins: Option<HashSet<String>>,\n}\n\nimpl OnlineConfigService {\n    async fn run_once(&mut self) -> io::Result<()> {\n        match time::timeout(Duration::from_secs(30), self.run_once_impl()).await {\n            Ok(o) => o,\n            Err(..) => {\n                error!(\"server-loader task timeout, url: {}\", self.config_url);\n                Err(io::ErrorKind::TimedOut.into())\n            }\n        }\n    }\n\n    async fn run_once_impl(&mut self) -> io::Result<()> {\n        const SHADOWSOCKS_USER_AGENT: &str = concat!(env!(\"CARGO_PKG_NAME\"), \"/\", env!(\"CARGO_PKG_VERSION\"));\n\n        let start_time = Instant::now();\n\n        let req = match hyper::Request::builder()\n            .header(\"User-Agent\", SHADOWSOCKS_USER_AGENT)\n            .header(\"Accept-Encoding\", \"deflate, gzip, br, zstd\")\n            .method(\"GET\")\n            .uri(&self.config_url)\n            .body(String::new())\n        {\n            Ok(r) => r,\n            Err(err) => {\n                error!(\"server-loader task failed to make hyper::Request, error: {}\", err);\n                return Err(io::Error::other(err));\n            }\n        };\n\n        let mut rsp = match self.http_client.send_request(self.context.clone(), req, None).await {\n            Ok(r) => r,\n            Err(err) => {\n                error!(\"server-loader task failed to get {}, error: {}\", self.config_url, err);\n                return Err(io::Error::other(err));\n            }\n        };\n\n        trace!(\"server-loader task fetch response: {:?}\", rsp);\n\n        let fetch_time = Instant::now();\n\n        // Check status=200\n        if rsp.status() != StatusCode::OK {\n            error!(\n                \"server-loader task failed to get {}, status: {}\",\n                self.config_url,\n                rsp.status()\n            );\n            return Err(io::Error::other(format!(\"status: {}\", rsp.status())));\n        }\n\n        // Content-Type: application/json; charset=utf-8\n        // mandatory in standard SIP008\n        match rsp.headers().get(\"Content-Type\") {\n            Some(h) => match h.to_str() {\n                Ok(hstr) => match hstr.parse::<Mime>() {\n                    Ok(content_type) => {\n                        if content_type.type_() == mime::APPLICATION\n                            && content_type.subtype() == mime::JSON\n                            && content_type.get_param(mime::CHARSET) == Some(mime::UTF_8)\n                        {\n                            trace!(\"checked Content-Type: {:?}\", h);\n                        } else {\n                            warn!(\n                                \"Content-Type is not \\\"application/json; charset=utf-8\\\", which is mandatory in standard SIP008. found {:?}\",\n                                h\n                            );\n                        }\n                    }\n                    Err(err) => {\n                        warn!(\"Content-Type parse failed, value: {:?}, error: {}\", h, err);\n                    }\n                },\n                Err(..) => {\n                    warn!(\"Content-Type is not a UTF-8 string: {:?}\", h);\n                }\n            },\n            None => {\n                warn!(\"missing Content-Type in SIP008 response from {}\", self.config_url);\n            }\n        }\n\n        let content_encoding = match rsp.headers().get(http::header::CONTENT_ENCODING) {\n            None => ContentEncoding::Identity,\n            Some(ce) => match ContentEncoding::try_from(ce) {\n                Ok(ce) => ce,\n                Err(..) => {\n                    error!(\"unrecognized Content-Encoding: {:?}\", ce);\n                    return Err(io::Error::other(\"unrecognized Content-Encoding\"));\n                }\n            },\n        };\n\n        let body = read_body(content_encoding, &mut rsp).await?;\n        let parsed_body = match String::from_utf8(body) {\n            Ok(b) => b,\n            Err(..) => return Err(io::Error::other(\"body contains non-utf8 bytes\")),\n        };\n\n        let online_config = match Config::load_from_json_str(&parsed_body, ConfigType::OnlineConfig) {\n            Ok(c) => c,\n            Err(err) => {\n                error!(\n                    \"server-loader task failed to load from url: {}, error: {}\",\n                    self.config_url, err\n                );\n                return Err(io::Error::other(err));\n            }\n        };\n\n        if let Err(err) = online_config.check_integrity() {\n            error!(\n                \"server-loader task failed to load from url: {}, error: {}\",\n                self.config_url, err\n            );\n            return Err(io::Error::other(err));\n        }\n\n        let after_read_time = Instant::now();\n\n        // Check plugin whitelist\n        if let Some(ref allowed_plugins) = self.allowed_plugins {\n            for server in &online_config.server {\n                if let Some(plugin) = server.config.plugin()\n                    && !allowed_plugins.contains(&plugin.plugin)\n                {\n                    error!(\n                        \"server-loader task found not allowed plugin: {}, url: {}\",\n                        plugin.plugin, self.config_url\n                    );\n                    return Err(io::Error::other(format!(\"not allowed plugin: {}\", plugin.plugin)));\n                }\n            }\n        }\n\n        // Merge with static servers\n        let server_len = online_config.server.len();\n\n        // Update into ping balancers\n        if let Err(err) = self\n            .balancer\n            .reset_servers(online_config.server, &[ServerSource::OnlineConfig])\n            .await\n        {\n            error!(\n                \"server-loader task failed to reset balancer, url: {}, error: {}\",\n                self.config_url, err\n            );\n            return Err(err);\n        };\n\n        let finish_time = Instant::now();\n\n        debug!(\n            \"server-loader task finished loading {} servers from url: {}, fetch time: {:?}, read time: {:?}, load time: {:?}, total time: {:?}\",\n            server_len,\n            self.config_url,\n            fetch_time - start_time,\n            after_read_time - fetch_time,\n            finish_time - after_read_time,\n            finish_time - start_time,\n        );\n\n        Ok(())\n    }\n\n    /// Start service loop\n    pub async fn run(mut self) -> io::Result<()> {\n        debug!(\n            \"server-loader task started, url: {}, update interval: {:?}\",\n            self.config_url, self.config_update_interval\n        );\n\n        loop {\n            time::sleep(self.config_update_interval).await;\n            let _ = self.run_once().await;\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/redir/mod.rs",
    "content": "//! Shadowsocks Local Transparent Proxy\n\npub use self::server::{Redir, RedirBuilder};\n\nmod redir_ext;\nmod server;\nmod sys;\nmod tcprelay;\nmod udprelay;\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/redir/redir_ext.rs",
    "content": "//! Extension trait for `TcpListener` and `UdpSocket`\n\nuse std::{\n    future::Future,\n    io,\n    net::SocketAddr,\n    pin::Pin,\n    task::{Context, Poll},\n};\n\nuse shadowsocks::net::AcceptOpts;\nuse tokio::net::TcpListener;\n\nuse crate::config::RedirType;\n\n/// Extension function for `TcpListener` for setting extra options before `bind()`\npub trait TcpListenerRedirExt {\n    // Create a TcpListener for transparent proxy\n    //\n    // Implementation is platform dependent\n    async fn bind_redir(ty: RedirType, addr: SocketAddr, accept_opts: AcceptOpts) -> io::Result<TcpListener>;\n}\n\n/// Extension function for `TcpStream` for reading original destination address\npub trait TcpStreamRedirExt {\n    // Read destination address for TcpStream\n    //\n    // Implementation is platform dependent\n    fn destination_addr(&self, ty: RedirType) -> io::Result<SocketAddr>;\n}\n\n/// `UdpSocket` that support transparent proxy\npub trait UdpSocketRedir {\n    /// Receive a single datagram from the socket.\n    ///\n    /// On success, the future resolves to the number of bytes read and the source, target address\n    ///\n    /// `(bytes read, source address, target address)`\n    fn poll_recv_dest_from(\n        &self,\n        cx: &mut Context<'_>,\n        buf: &mut [u8],\n    ) -> Poll<io::Result<(usize, SocketAddr, SocketAddr)>>;\n}\n\n/// Extension functions for `UdpSocket` to receive data with original destination address\npub trait UdpSocketRedirExt {\n    fn recv_dest_from<'a>(&'a self, buf: &'a mut [u8]) -> RecvDestFrom<'a, Self>\n    where\n        Self: Sized,\n    {\n        RecvDestFrom { socket: self, buf }\n    }\n}\n\nimpl<S> UdpSocketRedirExt for S where S: UdpSocketRedir {}\n\n/// Future for `recv_dest_from`\npub struct RecvDestFrom<'a, S: 'a> {\n    socket: &'a S,\n    buf: &'a mut [u8],\n}\n\nimpl<'a, S: 'a> Future for RecvDestFrom<'a, S>\nwhere\n    S: UdpSocketRedir,\n{\n    type Output = io::Result<(usize, SocketAddr, SocketAddr)>;\n\n    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {\n        self.socket.poll_recv_dest_from(cx, self.buf)\n    }\n}\n\n// sockopts for send-back sockets\n#[derive(Debug, Clone, Default)]\npub struct RedirSocketOpts {\n    /// Linux mark based routing, going to set by `setsockopt` with `SO_MARK` option\n    #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n    pub fwmark: Option<u32>,\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/redir/server.rs",
    "content": "//! Shadowsocks Transparent Proxy Local Server\n\nuse std::{io, sync::Arc, time::Duration};\n\nuse futures::{FutureExt, future};\nuse shadowsocks::{ServerAddr, config::Mode};\n\nuse crate::{\n    config::RedirType,\n    local::{context::ServiceContext, loadbalancing::PingBalancer},\n};\n\nuse super::{tcprelay::RedirTcpServer, udprelay::RedirUdpServer};\n\n/// Transparent Proxy builder\npub struct RedirBuilder {\n    context: Arc<ServiceContext>,\n    mode: Mode,\n    udp_expiry_duration: Option<Duration>,\n    udp_capacity: Option<usize>,\n    tcp_redir: RedirType,\n    udp_redir: RedirType,\n    client_addr: ServerAddr,\n    udp_bind_addr: Option<ServerAddr>,\n    balancer: PingBalancer,\n}\n\nimpl RedirBuilder {\n    /// Create a new transparent proxy server with default configuration\n    pub fn new(client_addr: ServerAddr, balancer: PingBalancer) -> Self {\n        let context = ServiceContext::new();\n        Self::with_context(Arc::new(context), client_addr, balancer)\n    }\n\n    /// Create a new transparent proxy server with context\n    pub fn with_context(context: Arc<ServiceContext>, client_addr: ServerAddr, balancer: PingBalancer) -> Self {\n        Self {\n            context,\n            mode: Mode::TcpOnly,\n            udp_expiry_duration: None,\n            udp_capacity: None,\n            tcp_redir: RedirType::tcp_default(),\n            udp_redir: RedirType::udp_default(),\n            client_addr,\n            udp_bind_addr: None,\n            balancer,\n        }\n    }\n\n    /// Set UDP association's expiry duration\n    pub fn set_udp_expiry_duration(&mut self, d: Duration) {\n        self.udp_expiry_duration = Some(d);\n    }\n\n    /// Set total UDP association to be kept simultaneously in server\n    pub fn set_udp_capacity(&mut self, c: usize) {\n        self.udp_capacity = Some(c);\n    }\n\n    /// Set server mode\n    pub fn set_mode(&mut self, mode: Mode) {\n        self.mode = mode;\n    }\n\n    /// Set transparent proxy type of TCP relay, which is platform dependent\n    pub fn set_tcp_redir(&mut self, ty: RedirType) {\n        self.tcp_redir = ty;\n    }\n\n    /// Set transparent proxy type of UDP relay, which is platform dependent\n    pub fn set_udp_redir(&mut self, ty: RedirType) {\n        self.udp_redir = ty;\n    }\n\n    /// Set UDP bind address\n    pub fn set_udp_bind_addr(&mut self, addr: ServerAddr) {\n        self.udp_bind_addr = Some(addr);\n    }\n\n    pub async fn build(self) -> io::Result<Redir> {\n        let mut tcp_server = None;\n        if self.mode.enable_tcp() {\n            let server = RedirTcpServer::new(\n                self.context.clone(),\n                &self.client_addr,\n                self.balancer.clone(),\n                self.tcp_redir,\n            )\n            .await?;\n            tcp_server = Some(server);\n        }\n\n        let mut udp_server = None;\n        if self.mode.enable_udp() {\n            let udp_addr = self.udp_bind_addr.as_ref().unwrap_or(&self.client_addr);\n\n            let server = RedirUdpServer::new(\n                self.context,\n                self.udp_redir,\n                udp_addr,\n                self.udp_expiry_duration,\n                self.udp_capacity,\n                self.balancer,\n            )\n            .await?;\n            udp_server = Some(server);\n        }\n\n        Ok(Redir { tcp_server, udp_server })\n    }\n}\n\n/// Transparent Proxy\npub struct Redir {\n    tcp_server: Option<RedirTcpServer>,\n    udp_server: Option<RedirUdpServer>,\n}\n\nimpl Redir {\n    /// TCP server instance\n    pub fn tcp_server(&self) -> Option<&RedirTcpServer> {\n        self.tcp_server.as_ref()\n    }\n\n    /// UDP server instance\n    pub fn udp_server(&self) -> Option<&RedirUdpServer> {\n        self.udp_server.as_ref()\n    }\n\n    /// Start serving\n    pub async fn run(self) -> io::Result<()> {\n        let mut vfut = Vec::new();\n\n        if let Some(tcp_server) = self.tcp_server {\n            vfut.push(tcp_server.run().boxed());\n        }\n\n        if let Some(udp_server) = self.udp_server {\n            vfut.push(udp_server.run().boxed());\n        }\n\n        let (res, ..) = future::select_all(vfut).await;\n        res\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/redir/sys/mod.rs",
    "content": "use std::io;\n\nuse cfg_if::cfg_if;\nuse socket2::SockRef;\n\ncfg_if! {\n    if #[cfg(unix)] {\n        mod unix;\n        #[allow(unused_imports)]\n        pub use self::unix::*;\n    }\n}\n\n#[cfg(unix)]\n#[allow(dead_code)]\npub fn set_ipv6_only<S>(socket: &S, ipv6_only: bool) -> io::Result<()>\nwhere\n    S: std::os::unix::io::AsFd,\n{\n    let sock = SockRef::from(socket);\n    sock.set_only_v6(ipv6_only)\n}\n\n#[cfg(windows)]\n#[allow(dead_code)]\npub fn set_ipv6_only<S>(socket: &S, ipv6_only: bool) -> io::Result<()>\nwhere\n    S: std::os::windows::io::AsSocket,\n{\n    let sock = SockRef::from(socket);\n    sock.set_only_v6(ipv6_only)\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/redir/sys/unix/bsd_pf.rs",
    "content": "//! PacketFilter implementation for *BSD\n\nuse std::{\n    io::{self, Error, ErrorKind},\n    mem,\n    net::SocketAddr,\n    ptr,\n    sync::LazyLock,\n};\n\nuse cfg_if::cfg_if;\nuse log::trace;\nuse nix::ioctl_readwrite;\nuse socket2::{Protocol, SockAddr};\n\nuse super::pfvar::{PF_OUT, in_addr, in6_addr, pfioc_natlook, sockaddr_in, sockaddr_in6};\n#[cfg(any(target_os = \"macos\", target_os = \"ios\"))]\nuse super::pfvar::{pf_addr, pfioc_states, pfsync_state};\n\nioctl_readwrite!(ioc_natlook, 'D', 23, pfioc_natlook);\n#[cfg(any(target_os = \"macos\", target_os = \"ios\"))]\nioctl_readwrite!(ioc_getstates, 'D', 25, pfioc_states);\n\npub struct PacketFilter {\n    fd: libc::c_int,\n}\n\nimpl PacketFilter {\n    fn open() -> io::Result<PacketFilter> {\n        unsafe {\n            let dev_path = b\"/dev/pf\\0\";\n\n            // According to FreeBSD's doc\n            // https://www.freebsd.org/cgi/man.cgi?query=pf&sektion=4&apropos=0&manpath=FreeBSD+12.1-RELEASE+and+Ports\n            let fd = libc::open(dev_path.as_ptr() as *const _, libc::O_RDONLY);\n            if fd < 0 {\n                let err = Error::last_os_error();\n                return Err(err);\n            }\n\n            // Set CLOEXEC\n            let ret = libc::fcntl(fd, libc::F_SETFD, libc::fcntl(fd, libc::F_GETFD) | libc::FD_CLOEXEC);\n            if ret != 0 {\n                let err = Error::last_os_error();\n                let _ = libc::close(fd);\n                return Err(err);\n            }\n\n            Ok(PacketFilter { fd })\n        }\n    }\n\n    pub fn natlook(&self, bind_addr: &SocketAddr, peer_addr: &SocketAddr, proto: Protocol) -> io::Result<SocketAddr> {\n        match proto {\n            Protocol::TCP => self.tcp_natlook(bind_addr, peer_addr, proto),\n            #[cfg(any(target_os = \"macos\", target_os = \"ios\"))]\n            Protocol::UDP => self.udp_natlook(bind_addr, peer_addr, proto),\n            _ => Err(io::ErrorKind::InvalidInput.into()),\n        }\n    }\n\n    fn tcp_natlook(&self, bind_addr: &SocketAddr, peer_addr: &SocketAddr, proto: Protocol) -> io::Result<SocketAddr> {\n        trace!(\"PF natlook peer: {}, bind: {}\", peer_addr, bind_addr);\n\n        unsafe {\n            let mut pnl: pfioc_natlook = mem::zeroed();\n\n            match *bind_addr {\n                SocketAddr::V4(ref v4) => {\n                    pnl.af = libc::AF_INET as libc::sa_family_t;\n\n                    let sockaddr = SockAddr::from(*v4);\n                    let sockaddr = sockaddr.as_ptr() as *const sockaddr_in;\n\n                    let addr: *const in_addr = ptr::addr_of!((*sockaddr).sin_addr) as *const _;\n                    let port: libc::in_port_t = (*sockaddr).sin_port;\n\n                    ptr::write_unaligned::<in_addr>(ptr::addr_of_mut!(pnl.daddr.pfa) as *mut _, *addr);\n\n                    cfg_if! {\n                        if #[cfg(any(target_os = \"macos\", target_os = \"ios\"))] {\n                            pnl.dxport.port = port;\n                        } else {\n                            pnl.dport = port;\n                        }\n                    }\n                }\n                SocketAddr::V6(ref v6) => {\n                    pnl.af = libc::AF_INET6 as libc::sa_family_t;\n\n                    let sockaddr = SockAddr::from(*v6);\n                    let sockaddr = sockaddr.as_ptr() as *const sockaddr_in6;\n\n                    let addr: *const in6_addr = ptr::addr_of!((*sockaddr).sin6_addr) as *const _;\n                    let port: libc::in_port_t = (*sockaddr).sin6_port;\n\n                    ptr::write_unaligned::<in6_addr>(ptr::addr_of_mut!(pnl.daddr.pfa) as *mut _, *addr);\n\n                    cfg_if! {\n                        if #[cfg(any(target_os = \"macos\", target_os = \"ios\"))] {\n                            pnl.dxport.port = port;\n                        } else {\n                            pnl.dport = port;\n                        }\n                    }\n                }\n            }\n\n            match *peer_addr {\n                SocketAddr::V4(ref v4) => {\n                    if pnl.af != libc::AF_INET as libc::sa_family_t {\n                        return Err(Error::new(ErrorKind::InvalidInput, \"client addr must be ipv4\"));\n                    }\n\n                    let sockaddr = SockAddr::from(*v4);\n                    let sockaddr = sockaddr.as_ptr() as *const sockaddr_in;\n\n                    let addr: *const in_addr = ptr::addr_of!((*sockaddr).sin_addr) as *const _;\n                    let port: libc::in_port_t = (*sockaddr).sin_port;\n\n                    ptr::write_unaligned::<in_addr>(ptr::addr_of_mut!(pnl.saddr.pfa) as *mut _, *addr);\n\n                    cfg_if! {\n                        if #[cfg(any(target_os = \"macos\", target_os = \"ios\"))] {\n                            pnl.sxport.port = port;\n                        } else {\n                            pnl.sport = port;\n                        }\n                    }\n                }\n                SocketAddr::V6(ref v6) => {\n                    if pnl.af != libc::AF_INET6 as libc::sa_family_t {\n                        return Err(Error::new(ErrorKind::InvalidInput, \"client addr must be ipv6\"));\n                    }\n\n                    let sockaddr = SockAddr::from(*v6);\n                    let sockaddr = sockaddr.as_ptr() as *const sockaddr_in6;\n\n                    let addr: *const in6_addr = ptr::addr_of!((*sockaddr).sin6_addr) as *const _;\n                    let port: libc::in_port_t = (*sockaddr).sin6_port;\n\n                    ptr::write_unaligned::<in6_addr>(ptr::addr_of_mut!(pnl.saddr.pfa) as *mut _, *addr);\n\n                    cfg_if! {\n                        if #[cfg(any(target_os = \"macos\", target_os = \"ios\"))] {\n                            pnl.sxport.port = port;\n                        } else {\n                            pnl.sport = port;\n                        }\n                    }\n                }\n            }\n\n            pnl.proto = i32::from(proto) as u8;\n            pnl.direction = PF_OUT as u8;\n\n            if let Err(err) = ioc_natlook(self.fd, &mut pnl) {\n                return Err(Error::from_raw_os_error(err as i32));\n            }\n\n            let (_, dst_addr) = SockAddr::try_init(|dst_addr, addr_len| {\n                if pnl.af == libc::AF_INET as libc::sa_family_t {\n                    let dst_addr: &mut sockaddr_in = &mut *(dst_addr as *mut _);\n                    dst_addr.sin_family = pnl.af;\n\n                    cfg_if! {\n                        if #[cfg(any(target_os = \"macos\", target_os = \"ios\"))] {\n                            dst_addr.sin_port = pnl.rdxport.port;\n                        } else {\n                            dst_addr.sin_port = pnl.rdport;\n                        }\n                    }\n\n                    ptr::write_unaligned::<in_addr>(\n                        ptr::addr_of_mut!(dst_addr.sin_addr),\n                        ptr::read::<in_addr>(ptr::addr_of!(pnl.rdaddr.pfa) as *const _),\n                    );\n                    *addr_len = mem::size_of_val(&dst_addr.sin_addr) as libc::socklen_t;\n                } else if pnl.af == libc::AF_INET6 as libc::sa_family_t {\n                    let dst_addr: &mut sockaddr_in6 = &mut *(dst_addr as *mut _);\n                    dst_addr.sin6_family = pnl.af;\n\n                    cfg_if! {\n                        if #[cfg(any(target_os = \"macos\", target_os = \"ios\"))] {\n                            dst_addr.sin6_port = pnl.rdxport.port;\n                        } else {\n                            dst_addr.sin6_port = pnl.rdport;\n                        }\n                    }\n\n                    ptr::write_unaligned::<in6_addr>(\n                        ptr::addr_of_mut!(dst_addr.sin6_addr),\n                        ptr::read::<in6_addr>(ptr::addr_of!(pnl.rdaddr.pfa) as *const _),\n                    );\n                    *addr_len = mem::size_of_val(&dst_addr.sin6_addr) as libc::socklen_t;\n                } else {\n                    unreachable!(\"sockaddr should be either ipv4 or ipv6\");\n                }\n\n                Ok(())\n            })?;\n\n            Ok(dst_addr.as_socket().expect(\"SocketAddr\"))\n        }\n    }\n\n    #[cfg(any(target_os = \"macos\", target_os = \"ios\"))]\n    fn udp_natlook(&self, bind_addr: &SocketAddr, peer_addr: &SocketAddr, _proto: Protocol) -> io::Result<SocketAddr> {\n        unsafe {\n            // Get all states\n            // https://man.freebsd.org/cgi/man.cgi?query=pf&sektion=4&manpath=OpenBSD\n            // DIOCGETSTATES\n\n            let mut states: pfioc_states = mem::zeroed();\n            let mut states_buffer = vec![0u8; 8192];\n\n            loop {\n                states.ps_len = states_buffer.len() as _;\n                states.ps_u.psu_buf = states_buffer.as_mut_ptr() as *mut _;\n\n                if let Err(err) = ioc_getstates(self.fd, &mut states) {\n                    return Err(Error::from_raw_os_error(err as i32));\n                }\n\n                if states.ps_len as usize <= states_buffer.len() {\n                    break;\n                }\n\n                // Resize to fit all states\n                // > On exit, ps_len is always set to the total size re-\n                // > quired to hold all state table entries\n                states_buffer.resize(states.ps_len as usize, 0);\n            }\n\n            let bind_addr_sockaddr = SockAddr::from(*bind_addr);\n            let peer_addr_sockaddr = SockAddr::from(*peer_addr);\n\n            let mut bind_addr_pfaddr: pf_addr = mem::zeroed();\n            let mut peer_addr_pfaddr: pf_addr = mem::zeroed();\n\n            match bind_addr_sockaddr.family() as libc::c_int {\n                libc::AF_INET => {\n                    let sockaddr: *const sockaddr_in = bind_addr_sockaddr.as_ptr() as *const _;\n                    ptr::write_unaligned::<in_addr>(\n                        ptr::addr_of_mut!(bind_addr_pfaddr.pfa) as *mut _,\n                        (*sockaddr).sin_addr,\n                    );\n                }\n                libc::AF_INET6 => {\n                    let sockaddr: *const sockaddr_in6 = bind_addr_sockaddr.as_ptr() as *const _;\n                    ptr::write_unaligned::<in6_addr>(\n                        ptr::addr_of_mut!(bind_addr_pfaddr.pfa) as *mut _,\n                        (*sockaddr).sin6_addr,\n                    );\n                }\n                _ => unreachable!(\"bind_addr family = {}\", bind_addr_sockaddr.family()),\n            }\n\n            match peer_addr_sockaddr.family() as libc::c_int {\n                libc::AF_INET => {\n                    let sockaddr: *const sockaddr_in = peer_addr_sockaddr.as_ptr() as *const _;\n                    ptr::write_unaligned::<in_addr>(\n                        ptr::addr_of_mut!(peer_addr_pfaddr.pfa) as *mut _,\n                        (*sockaddr).sin_addr,\n                    );\n                }\n                libc::AF_INET6 => {\n                    let sockaddr: *const sockaddr_in6 = peer_addr_sockaddr.as_ptr() as *const _;\n                    ptr::write_unaligned::<in6_addr>(\n                        ptr::addr_of_mut!(peer_addr_pfaddr.pfa) as *mut _,\n                        (*sockaddr).sin6_addr,\n                    );\n                }\n                _ => unreachable!(\"peer_addr family = {}\", peer_addr_sockaddr.family()),\n            }\n\n            let states_count = states.ps_len as usize / mem::size_of::<pfsync_state>();\n            for i in 0..states_count {\n                let state = &*(states.ps_u.psu_states.add(i));\n\n                if state.proto == libc::IPPROTO_UDP as u8 {\n                    cfg_if! {\n                        if #[cfg(any(target_os = \"macos\", target_os = \"ios\"))] {\n                            let dst_port = state.lan.xport.port;\n                            let src_port = state.ext_gwy.xport.port;\n                            let actual_dst_port = state.gwy.xport.port;\n                        } else {\n                            let dst_port = state.lan.port;\n                            let src_port = state.ext_gwy.port;\n                            let actual_dst_port = state.gwy.port;\n                        }\n                    }\n\n                    let dst_addr_eq = libc::memcmp(\n                        &bind_addr_pfaddr as *const _ as *const _,\n                        ptr::addr_of!(state.lan.addr.pfa) as *const _,\n                        mem::size_of::<pf_addr>(),\n                    ) == 0;\n                    let src_addr_eq = libc::memcmp(\n                        &peer_addr_pfaddr as *const _ as *const _,\n                        ptr::addr_of!(state.ext_gwy.addr.pfa) as *const _,\n                        mem::size_of::<pf_addr>(),\n                    ) == 0;\n\n                    if src_addr_eq && src_port == peer_addr.port() && dst_addr_eq && dst_port == bind_addr.port() {\n                        let actual_dst_addr = match state.af_gwy as libc::c_int {\n                            libc::AF_INET => {\n                                let (_, actual_dst_addr) = SockAddr::try_init(|sockaddr, len| {\n                                    let addr = &mut *(sockaddr as *mut sockaddr_in);\n                                    addr.sin_family = libc::AF_INET as libc::sa_family_t;\n                                    ptr::write_unaligned::<in_addr>(\n                                        ptr::addr_of_mut!(addr.sin_addr),\n                                        ptr::read_unaligned::<in_addr>(ptr::addr_of!(state.gwy.addr.pfa) as *const _),\n                                    );\n                                    addr.sin_port = actual_dst_port as libc::in_port_t;\n\n                                    ptr::write(len, mem::size_of::<sockaddr_in>() as libc::socklen_t);\n                                    Ok(())\n                                })\n                                .unwrap();\n\n                                actual_dst_addr\n                            }\n                            libc::AF_INET6 => {\n                                let (_, actual_dst_addr) = SockAddr::try_init(|sockaddr, len| {\n                                    let addr = &mut *(sockaddr as *mut sockaddr_in6);\n                                    addr.sin6_family = libc::AF_INET6 as libc::sa_family_t;\n                                    ptr::write_unaligned::<in6_addr>(\n                                        ptr::addr_of_mut!(addr.sin6_addr),\n                                        ptr::read_unaligned::<in6_addr>(ptr::addr_of!(state.gwy.addr.pfa) as *const _),\n                                    );\n                                    addr.sin6_port = actual_dst_port as libc::in_port_t;\n\n                                    ptr::write(len, mem::size_of::<sockaddr_in6>() as libc::socklen_t);\n                                    Ok(())\n                                })\n                                .unwrap();\n\n                                actual_dst_addr\n                            }\n                            _ => {\n                                return Err(io::Error::other(format!(\n                                    \"state.af_gwy {} is not a valid address family\",\n                                    state.af_gwy\n                                )));\n                            }\n                        };\n\n                        return Ok(actual_dst_addr.as_socket().expect(\"SocketAddr\"));\n                    }\n                }\n            }\n        }\n\n        Err(io::Error::other(format!(\n            \"natlook UDP binding {}, {} not found\",\n            bind_addr, peer_addr\n        )))\n    }\n}\n\nimpl Drop for PacketFilter {\n    fn drop(&mut self) {\n        unsafe {\n            libc::close(self.fd);\n        }\n    }\n}\n\npub static PF: LazyLock<PacketFilter> = LazyLock::new(|| match PacketFilter::open() {\n    Ok(pf) => pf,\n    Err(err) if err.kind() == ErrorKind::PermissionDenied => {\n        panic!(\"open /dev/pf permission denied, consider restart with root user\");\n    }\n    Err(err) => {\n        panic!(\"open /dev/pf {err}\");\n    }\n});\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/redir/sys/unix/mod.rs",
    "content": "use cfg_if::cfg_if;\n\ncfg_if! {\n    if #[cfg(any(target_os = \"macos\",\n                 target_os = \"ios\",\n                 target_os = \"freebsd\"))] {\n        pub mod bsd_pf;\n    }\n}\n\ncfg_if! {\n    if #[cfg(any(target_os = \"macos\",\n                 target_os = \"ios\"))] {\n        #[path = \"pfvar_bindgen_macos.rs\"]\n        #[allow(dead_code, non_upper_case_globals, non_snake_case, non_camel_case_types)]\n        #[allow(clippy::useless_transmute, clippy::too_many_arguments, clippy::unnecessary_cast)]\n        mod pfvar;\n    } else if #[cfg(target_os = \"freebsd\")] {\n        #[path = \"pfvar_bindgen_freebsd.rs\"]\n        #[allow(dead_code, non_upper_case_globals, non_snake_case, non_camel_case_types)]\n        #[allow(clippy::useless_transmute, clippy::too_many_arguments, clippy::unnecessary_cast)]\n        mod pfvar;\n    } else if #[cfg(target_os = \"openbsd\")] {\n        #[path = \"pfvar_bindgen_openbsd.rs\"]\n        #[allow(dead_code, non_upper_case_globals, non_snake_case, non_camel_case_types)]\n        #[allow(clippy::useless_transmute, clippy::too_many_arguments, clippy::unnecessary_cast)]\n        mod pfvar;\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/redir/sys/unix/pfvar_bindgen_freebsd.rs",
    "content": "// automatically generated by rust-bindgen 0.69.2\n\npub const BSD: u32 = 199506;\npub const BSD4_3: u32 = 1;\npub const BSD4_4: u32 = 1;\npub const __FreeBSD_version: u32 = 1400097;\npub const __GNUCLIKE_ASM: u32 = 3;\npub const __GNUCLIKE___TYPEOF: u32 = 1;\npub const __GNUCLIKE___SECTION: u32 = 1;\npub const __GNUCLIKE_CTOR_SECTION_HANDLING: u32 = 1;\npub const __GNUCLIKE_BUILTIN_CONSTANT_P: u32 = 1;\npub const __GNUCLIKE_BUILTIN_VARARGS: u32 = 1;\npub const __GNUCLIKE_BUILTIN_STDARG: u32 = 1;\npub const __GNUCLIKE_BUILTIN_VAALIST: u32 = 1;\npub const __GNUC_VA_LIST_COMPATIBILITY: u32 = 1;\npub const __GNUCLIKE_BUILTIN_NEXT_ARG: u32 = 1;\npub const __GNUCLIKE_BUILTIN_MEMCPY: u32 = 1;\npub const __CC_SUPPORTS_INLINE: u32 = 1;\npub const __CC_SUPPORTS___INLINE: u32 = 1;\npub const __CC_SUPPORTS___INLINE__: u32 = 1;\npub const __CC_SUPPORTS___FUNC__: u32 = 1;\npub const __CC_SUPPORTS_WARNING: u32 = 1;\npub const __CC_SUPPORTS_VARADIC_XXX: u32 = 1;\npub const __CC_SUPPORTS_DYNAMIC_ARRAY_INIT: u32 = 1;\npub const __POSIX_VISIBLE: u32 = 200809;\npub const __XSI_VISIBLE: u32 = 700;\npub const __BSD_VISIBLE: u32 = 1;\npub const __ISO_C_VISIBLE: u32 = 2011;\npub const __EXT1_VISIBLE: u32 = 1;\npub const __CHAR_BIT: u32 = 8;\npub const __SCHAR_MAX: u32 = 127;\npub const __SCHAR_MIN: i32 = -128;\npub const __UCHAR_MAX: u32 = 255;\npub const __USHRT_MAX: u32 = 65535;\npub const __SHRT_MAX: u32 = 32767;\npub const __SHRT_MIN: i32 = -32768;\npub const __UINT_MAX: u32 = 4294967295;\npub const __INT_MAX: u32 = 2147483647;\npub const __INT_MIN: i32 = -2147483648;\npub const __ULONG_MAX: i32 = -1;\npub const __LONG_MAX: u64 = 9223372036854775807;\npub const __LONG_MIN: i64 = -9223372036854775808;\npub const __ULLONG_MAX: i32 = -1;\npub const __LLONG_MAX: u64 = 9223372036854775807;\npub const __LLONG_MIN: i64 = -9223372036854775808;\npub const __SSIZE_MAX: u64 = 9223372036854775807;\npub const __SIZE_T_MAX: i32 = -1;\npub const __OFF_MAX: u64 = 9223372036854775807;\npub const __OFF_MIN: i64 = -9223372036854775808;\npub const __UQUAD_MAX: i32 = -1;\npub const __QUAD_MAX: u64 = 9223372036854775807;\npub const __QUAD_MIN: i64 = -9223372036854775808;\npub const __LONG_BIT: u32 = 64;\npub const __WORD_BIT: u32 = 32;\npub const __MINSIGSTKSZ: u32 = 2048;\npub const __WCHAR_MIN: i32 = -2147483648;\npub const __WCHAR_MAX: u32 = 2147483647;\npub const _QUAD_HIGHWORD: u32 = 1;\npub const _QUAD_LOWWORD: u32 = 0;\npub const _SIG_WORDS: u32 = 4;\npub const _SIG_MAXSIG: u32 = 128;\npub const FD_SETSIZE: u32 = 1024;\npub const ARG_MAX: u32 = 524288;\npub const CHILD_MAX: u32 = 40;\npub const MAX_CANON: u32 = 255;\npub const MAX_INPUT: u32 = 255;\npub const NAME_MAX: u32 = 255;\npub const NGROUPS_MAX: u32 = 1023;\npub const OPEN_MAX: u32 = 64;\npub const PATH_MAX: u32 = 1024;\npub const PIPE_BUF: u32 = 512;\npub const IOV_MAX: u32 = 1024;\npub const MAXCOMLEN: u32 = 19;\npub const MAXINTERP: u32 = 1024;\npub const MAXLOGNAME: u32 = 33;\npub const MAXUPRC: u32 = 40;\npub const NCARGS: u32 = 524288;\npub const NGROUPS: u32 = 1024;\npub const NOFILE: u32 = 64;\npub const NOGROUP: u32 = 65535;\npub const MAXHOSTNAMELEN: u32 = 256;\npub const SPECNAMELEN: u32 = 255;\npub const _X86_SIGNAL_H: u32 = 1;\npub const SIGHUP: u32 = 1;\npub const SIGINT: u32 = 2;\npub const SIGQUIT: u32 = 3;\npub const SIGILL: u32 = 4;\npub const SIGTRAP: u32 = 5;\npub const SIGABRT: u32 = 6;\npub const SIGIOT: u32 = 6;\npub const SIGEMT: u32 = 7;\npub const SIGFPE: u32 = 8;\npub const SIGKILL: u32 = 9;\npub const SIGBUS: u32 = 10;\npub const SIGSEGV: u32 = 11;\npub const SIGSYS: u32 = 12;\npub const SIGPIPE: u32 = 13;\npub const SIGALRM: u32 = 14;\npub const SIGTERM: u32 = 15;\npub const SIGURG: u32 = 16;\npub const SIGSTOP: u32 = 17;\npub const SIGTSTP: u32 = 18;\npub const SIGCONT: u32 = 19;\npub const SIGCHLD: u32 = 20;\npub const SIGTTIN: u32 = 21;\npub const SIGTTOU: u32 = 22;\npub const SIGIO: u32 = 23;\npub const SIGXCPU: u32 = 24;\npub const SIGXFSZ: u32 = 25;\npub const SIGVTALRM: u32 = 26;\npub const SIGPROF: u32 = 27;\npub const SIGWINCH: u32 = 28;\npub const SIGINFO: u32 = 29;\npub const SIGUSR1: u32 = 30;\npub const SIGUSR2: u32 = 31;\npub const SIGTHR: u32 = 32;\npub const SIGLWP: u32 = 32;\npub const SIGLIBRT: u32 = 33;\npub const SIGRTMIN: u32 = 65;\npub const SIGRTMAX: u32 = 126;\npub const SIGEV_NONE: u32 = 0;\npub const SIGEV_SIGNAL: u32 = 1;\npub const SIGEV_THREAD: u32 = 2;\npub const SIGEV_KEVENT: u32 = 3;\npub const SIGEV_THREAD_ID: u32 = 4;\npub const ILL_ILLOPC: u32 = 1;\npub const ILL_ILLOPN: u32 = 2;\npub const ILL_ILLADR: u32 = 3;\npub const ILL_ILLTRP: u32 = 4;\npub const ILL_PRVOPC: u32 = 5;\npub const ILL_PRVREG: u32 = 6;\npub const ILL_COPROC: u32 = 7;\npub const ILL_BADSTK: u32 = 8;\npub const BUS_ADRALN: u32 = 1;\npub const BUS_ADRERR: u32 = 2;\npub const BUS_OBJERR: u32 = 3;\npub const BUS_OOMERR: u32 = 100;\npub const SEGV_MAPERR: u32 = 1;\npub const SEGV_ACCERR: u32 = 2;\npub const SEGV_PKUERR: u32 = 100;\npub const FPE_INTOVF: u32 = 1;\npub const FPE_INTDIV: u32 = 2;\npub const FPE_FLTDIV: u32 = 3;\npub const FPE_FLTOVF: u32 = 4;\npub const FPE_FLTUND: u32 = 5;\npub const FPE_FLTRES: u32 = 6;\npub const FPE_FLTINV: u32 = 7;\npub const FPE_FLTSUB: u32 = 8;\npub const FPE_FLTIDO: u32 = 9;\npub const TRAP_BRKPT: u32 = 1;\npub const TRAP_TRACE: u32 = 2;\npub const TRAP_DTRACE: u32 = 3;\npub const TRAP_CAP: u32 = 4;\npub const CLD_EXITED: u32 = 1;\npub const CLD_KILLED: u32 = 2;\npub const CLD_DUMPED: u32 = 3;\npub const CLD_TRAPPED: u32 = 4;\npub const CLD_STOPPED: u32 = 5;\npub const CLD_CONTINUED: u32 = 6;\npub const POLL_IN: u32 = 1;\npub const POLL_OUT: u32 = 2;\npub const POLL_MSG: u32 = 3;\npub const POLL_ERR: u32 = 4;\npub const POLL_PRI: u32 = 5;\npub const POLL_HUP: u32 = 6;\npub const SA_NOCLDSTOP: u32 = 8;\npub const SA_ONSTACK: u32 = 1;\npub const SA_RESTART: u32 = 2;\npub const SA_RESETHAND: u32 = 4;\npub const SA_NODEFER: u32 = 16;\npub const SA_NOCLDWAIT: u32 = 32;\npub const SA_SIGINFO: u32 = 64;\npub const NSIG: u32 = 32;\npub const SI_NOINFO: u32 = 0;\npub const SI_USER: u32 = 65537;\npub const SI_QUEUE: u32 = 65538;\npub const SI_TIMER: u32 = 65539;\npub const SI_ASYNCIO: u32 = 65540;\npub const SI_MESGQ: u32 = 65541;\npub const SI_KERNEL: u32 = 65542;\npub const SI_LWP: u32 = 65543;\npub const SI_UNDEFINED: u32 = 0;\npub const SS_ONSTACK: u32 = 1;\npub const SS_DISABLE: u32 = 4;\npub const MINSIGSTKSZ: u32 = 2048;\npub const SIGSTKSZ: u32 = 34816;\npub const SV_ONSTACK: u32 = 1;\npub const SV_INTERRUPT: u32 = 2;\npub const SV_RESETHAND: u32 = 4;\npub const SV_NODEFER: u32 = 16;\npub const SV_NOCLDSTOP: u32 = 8;\npub const SV_SIGINFO: u32 = 64;\npub const SIG_BLOCK: u32 = 1;\npub const SIG_UNBLOCK: u32 = 2;\npub const SIG_SETMASK: u32 = 3;\npub const MACHINE: &[u8; 6] = b\"amd64\\0\";\npub const MACHINE_ARCH: &[u8; 6] = b\"amd64\\0\";\npub const MACHINE_ARCH32: &[u8; 5] = b\"i386\\0\";\npub const MAXCPU: u32 = 1;\npub const MAXMEMDOM: u32 = 8;\npub const CACHE_LINE_SHIFT: u32 = 6;\npub const CACHE_LINE_SIZE: u32 = 64;\npub const NPTEPGSHIFT: u32 = 9;\npub const PAGE_SHIFT: u32 = 12;\npub const PAGE_SIZE: u32 = 4096;\npub const PAGE_MASK: u32 = 4095;\npub const NPDEPGSHIFT: u32 = 9;\npub const PDRSHIFT: u32 = 21;\npub const NBPDR: u32 = 2097152;\npub const PDRMASK: u32 = 2097151;\npub const NPDPEPGSHIFT: u32 = 9;\npub const PDPSHIFT: u32 = 30;\npub const NBPDP: u32 = 1073741824;\npub const PDPMASK: u32 = 1073741823;\npub const NPML4EPGSHIFT: u32 = 9;\npub const PML4SHIFT: u32 = 39;\npub const NBPML4: u64 = 549755813888;\npub const PML4MASK: u64 = 549755813887;\npub const NPML5EPGSHIFT: u32 = 9;\npub const PML5SHIFT: u32 = 48;\npub const NBPML5: u64 = 281474976710656;\npub const PML5MASK: u64 = 281474976710655;\npub const MAXPAGESIZES: u32 = 3;\npub const IOPAGES: u32 = 2;\npub const IOPERM_BITMAP_SIZE: u32 = 8193;\npub const KSTACK_PAGES: u32 = 4;\npub const KSTACK_GUARD_PAGES: u32 = 1;\npub const CHAR_BIT: u32 = 8;\npub const SCHAR_MAX: u32 = 127;\npub const SCHAR_MIN: i32 = -128;\npub const UCHAR_MAX: u32 = 255;\npub const CHAR_MAX: u32 = 127;\npub const CHAR_MIN: i32 = -128;\npub const USHRT_MAX: u32 = 65535;\npub const SHRT_MAX: u32 = 32767;\npub const SHRT_MIN: i32 = -32768;\npub const UINT_MAX: u32 = 4294967295;\npub const INT_MAX: u32 = 2147483647;\npub const INT_MIN: i32 = -2147483648;\npub const ULONG_MAX: i32 = -1;\npub const LONG_MAX: u64 = 9223372036854775807;\npub const LONG_MIN: i64 = -9223372036854775808;\npub const ULLONG_MAX: i32 = -1;\npub const LLONG_MAX: u64 = 9223372036854775807;\npub const LLONG_MIN: i64 = -9223372036854775808;\npub const SSIZE_MAX: u64 = 9223372036854775807;\npub const SIZE_T_MAX: i32 = -1;\npub const OFF_MAX: u64 = 9223372036854775807;\npub const OFF_MIN: i64 = -9223372036854775808;\npub const GID_MAX: u32 = 4294967295;\npub const UID_MAX: u32 = 4294967295;\npub const UQUAD_MAX: i32 = -1;\npub const QUAD_MAX: u64 = 9223372036854775807;\npub const QUAD_MIN: i64 = -9223372036854775808;\npub const LONG_BIT: u32 = 64;\npub const WORD_BIT: u32 = 32;\npub const MQ_PRIO_MAX: u32 = 64;\npub const DEV_BSHIFT: u32 = 9;\npub const DEV_BSIZE: u32 = 512;\npub const BLKDEV_IOSIZE: u32 = 4096;\npub const DFLTPHYS: u32 = 65536;\npub const MAXPHYS: u32 = 1048576;\npub const MAXDUMPPGS: u32 = 16;\npub const MSIZE: u32 = 256;\npub const MCLSHIFT: u32 = 11;\npub const MCLBYTES: u32 = 2048;\npub const MJUMPAGESIZE: u32 = 4096;\npub const MJUM9BYTES: u32 = 9216;\npub const MJUM16BYTES: u32 = 16384;\npub const PRIMASK: u32 = 255;\npub const PCATCH: u32 = 256;\npub const PDROP: u32 = 512;\npub const PNOLOCK: u32 = 1024;\npub const PRILASTFLAG: u32 = 1024;\npub const NZERO: u32 = 0;\npub const NBBY: u32 = 8;\npub const CMASK: u32 = 18;\npub const MAXBSIZE: u32 = 65536;\npub const MAXBCACHEBUF: u32 = 65536;\npub const BKVASIZE: u32 = 16384;\npub const BKVAMASK: u32 = 16383;\npub const MAXPATHLEN: u32 = 1024;\npub const MAXSYMLINKS: u32 = 32;\npub const FSHIFT: u32 = 11;\npub const FSCALE: u32 = 2048;\npub const CPU_MAXSIZE: u32 = 1024;\npub const CPU_SETSIZE: u32 = 1024;\npub const CPU_LEVEL_ROOT: u32 = 1;\npub const CPU_LEVEL_CPUSET: u32 = 2;\npub const CPU_LEVEL_WHICH: u32 = 3;\npub const CPU_WHICH_TID: u32 = 1;\npub const CPU_WHICH_PID: u32 = 2;\npub const CPU_WHICH_CPUSET: u32 = 3;\npub const CPU_WHICH_IRQ: u32 = 4;\npub const CPU_WHICH_JAIL: u32 = 5;\npub const CPU_WHICH_DOMAIN: u32 = 6;\npub const CPU_WHICH_INTRHANDLER: u32 = 7;\npub const CPU_WHICH_ITHREAD: u32 = 8;\npub const CPU_WHICH_TIDPID: u32 = 9;\npub const CPUSET_INVALID: i32 = -1;\npub const CPUSET_DEFAULT: u32 = 0;\npub const M_NOWAIT: u32 = 1;\npub const M_WAITOK: u32 = 2;\npub const M_NORECLAIM: u32 = 128;\npub const M_ZERO: u32 = 256;\npub const M_NOVM: u32 = 512;\npub const M_USE_RESERVE: u32 = 1024;\npub const M_NODUMP: u32 = 2048;\npub const M_FIRSTFIT: u32 = 4096;\npub const M_BESTFIT: u32 = 8192;\npub const M_EXEC: u32 = 16384;\npub const M_NEXTFIT: u32 = 32768;\npub const M_VERSION: u32 = 2020110501;\npub const DTMALLOC_PROBE_MALLOC: u32 = 0;\npub const DTMALLOC_PROBE_FREE: u32 = 1;\npub const DTMALLOC_PROBE_MAX: u32 = 2;\npub const MALLOC_TYPE_STREAM_VERSION: u32 = 1;\npub const MALLOC_MAX_NAME: u32 = 32;\npub const __bool_true_false_are_defined: u32 = 1;\npub const false_: u32 = 0;\npub const true_: u32 = 1;\npub const INT8_MIN: i32 = -128;\npub const INT16_MIN: i32 = -32768;\npub const INT32_MIN: i32 = -2147483648;\npub const INT8_MAX: u32 = 127;\npub const INT16_MAX: u32 = 32767;\npub const INT32_MAX: u32 = 2147483647;\npub const UINT8_MAX: u32 = 255;\npub const UINT16_MAX: u32 = 65535;\npub const UINT32_MAX: u32 = 4294967295;\npub const INT64_MIN: i64 = -9223372036854775808;\npub const INT64_MAX: u64 = 9223372036854775807;\npub const UINT64_MAX: i32 = -1;\npub const INT_LEAST8_MIN: i32 = -128;\npub const INT_LEAST16_MIN: i32 = -32768;\npub const INT_LEAST32_MIN: i32 = -2147483648;\npub const INT_LEAST64_MIN: i64 = -9223372036854775808;\npub const INT_LEAST8_MAX: u32 = 127;\npub const INT_LEAST16_MAX: u32 = 32767;\npub const INT_LEAST32_MAX: u32 = 2147483647;\npub const INT_LEAST64_MAX: u64 = 9223372036854775807;\npub const UINT_LEAST8_MAX: u32 = 255;\npub const UINT_LEAST16_MAX: u32 = 65535;\npub const UINT_LEAST32_MAX: u32 = 4294967295;\npub const UINT_LEAST64_MAX: i32 = -1;\npub const INT_FAST8_MIN: i32 = -2147483648;\npub const INT_FAST16_MIN: i32 = -2147483648;\npub const INT_FAST32_MIN: i32 = -2147483648;\npub const INT_FAST64_MIN: i64 = -9223372036854775808;\npub const INT_FAST8_MAX: u32 = 2147483647;\npub const INT_FAST16_MAX: u32 = 2147483647;\npub const INT_FAST32_MAX: u32 = 2147483647;\npub const INT_FAST64_MAX: u64 = 9223372036854775807;\npub const UINT_FAST8_MAX: u32 = 4294967295;\npub const UINT_FAST16_MAX: u32 = 4294967295;\npub const UINT_FAST32_MAX: u32 = 4294967295;\npub const UINT_FAST64_MAX: i32 = -1;\npub const INTPTR_MIN: i64 = -9223372036854775808;\npub const INTPTR_MAX: u64 = 9223372036854775807;\npub const UINTPTR_MAX: i32 = -1;\npub const INTMAX_MIN: i64 = -9223372036854775808;\npub const INTMAX_MAX: u64 = 9223372036854775807;\npub const UINTMAX_MAX: i32 = -1;\npub const PTRDIFF_MIN: i64 = -9223372036854775808;\npub const PTRDIFF_MAX: u64 = 9223372036854775807;\npub const SIG_ATOMIC_MIN: i64 = -9223372036854775808;\npub const SIG_ATOMIC_MAX: u64 = 9223372036854775807;\npub const SIZE_MAX: i32 = -1;\npub const WINT_MIN: i32 = -2147483648;\npub const WINT_MAX: u32 = 2147483647;\npub const __WORDSIZE: u32 = 64;\npub const WCHAR_MIN: i32 = -2147483648;\npub const WCHAR_MAX: u32 = 2147483647;\npub const RSIZE_MAX: i32 = -1;\npub const __SLBF: u32 = 1;\npub const __SNBF: u32 = 2;\npub const __SRD: u32 = 4;\npub const __SWR: u32 = 8;\npub const __SRW: u32 = 16;\npub const __SEOF: u32 = 32;\npub const __SERR: u32 = 64;\npub const __SMBF: u32 = 128;\npub const __SAPP: u32 = 256;\npub const __SSTR: u32 = 512;\npub const __SOPT: u32 = 1024;\npub const __SNPT: u32 = 2048;\npub const __SOFF: u32 = 4096;\npub const __SMOD: u32 = 8192;\npub const __SALC: u32 = 16384;\npub const __SIGN: u32 = 32768;\npub const __S2OAP: u32 = 1;\npub const _IOFBF: u32 = 0;\npub const _IOLBF: u32 = 1;\npub const _IONBF: u32 = 2;\npub const BUFSIZ: u32 = 1024;\npub const EOF: i32 = -1;\npub const FOPEN_MAX: u32 = 20;\npub const FILENAME_MAX: u32 = 1024;\npub const P_tmpdir: &[u8; 6] = b\"/tmp/\\0\";\npub const L_tmpnam: u32 = 1024;\npub const TMP_MAX: u32 = 308915776;\npub const SEEK_SET: u32 = 0;\npub const SEEK_CUR: u32 = 1;\npub const SEEK_END: u32 = 2;\npub const L_cuserid: u32 = 17;\npub const L_ctermid: u32 = 1024;\npub const NV_NAME_MAX: u32 = 2048;\npub const NV_TYPE_NONE: u32 = 0;\npub const NV_TYPE_NULL: u32 = 1;\npub const NV_TYPE_BOOL: u32 = 2;\npub const NV_TYPE_NUMBER: u32 = 3;\npub const NV_TYPE_STRING: u32 = 4;\npub const NV_TYPE_NVLIST: u32 = 5;\npub const NV_TYPE_DESCRIPTOR: u32 = 6;\npub const NV_TYPE_BINARY: u32 = 7;\npub const NV_TYPE_BOOL_ARRAY: u32 = 8;\npub const NV_TYPE_NUMBER_ARRAY: u32 = 9;\npub const NV_TYPE_STRING_ARRAY: u32 = 10;\npub const NV_TYPE_NVLIST_ARRAY: u32 = 11;\npub const NV_TYPE_DESCRIPTOR_ARRAY: u32 = 12;\npub const NV_FLAG_IGNORE_CASE: u32 = 1;\npub const NV_FLAG_NO_UNIQUE: u32 = 2;\npub const REFCOUNT_SATURATION_VALUE: u32 = 3221225472;\npub const _DTRACE_VERSION: u32 = 1;\npub const CTL_MAXNAME: u32 = 24;\npub const CTLTYPE: u32 = 15;\npub const CTLTYPE_NODE: u32 = 1;\npub const CTLTYPE_INT: u32 = 2;\npub const CTLTYPE_STRING: u32 = 3;\npub const CTLTYPE_S64: u32 = 4;\npub const CTLTYPE_OPAQUE: u32 = 5;\npub const CTLTYPE_STRUCT: u32 = 5;\npub const CTLTYPE_UINT: u32 = 6;\npub const CTLTYPE_LONG: u32 = 7;\npub const CTLTYPE_ULONG: u32 = 8;\npub const CTLTYPE_U64: u32 = 9;\npub const CTLTYPE_U8: u32 = 10;\npub const CTLTYPE_U16: u32 = 11;\npub const CTLTYPE_S8: u32 = 12;\npub const CTLTYPE_S16: u32 = 13;\npub const CTLTYPE_S32: u32 = 14;\npub const CTLTYPE_U32: u32 = 15;\npub const CTLFLAG_RD: u32 = 2147483648;\npub const CTLFLAG_WR: u32 = 1073741824;\npub const CTLFLAG_RW: u32 = 3221225472;\npub const CTLFLAG_DORMANT: u32 = 536870912;\npub const CTLFLAG_ANYBODY: u32 = 268435456;\npub const CTLFLAG_SECURE: u32 = 134217728;\npub const CTLFLAG_PRISON: u32 = 67108864;\npub const CTLFLAG_DYN: u32 = 33554432;\npub const CTLFLAG_SKIP: u32 = 16777216;\npub const CTLMASK_SECURE: u32 = 15728640;\npub const CTLFLAG_TUN: u32 = 524288;\npub const CTLFLAG_RDTUN: u32 = 2148007936;\npub const CTLFLAG_RWTUN: u32 = 3221749760;\npub const CTLFLAG_MPSAFE: u32 = 262144;\npub const CTLFLAG_VNET: u32 = 131072;\npub const CTLFLAG_DYING: u32 = 65536;\npub const CTLFLAG_CAPRD: u32 = 32768;\npub const CTLFLAG_CAPWR: u32 = 16384;\npub const CTLFLAG_STATS: u32 = 8192;\npub const CTLFLAG_NOFETCH: u32 = 4096;\npub const CTLFLAG_CAPRW: u32 = 49152;\npub const CTLFLAG_NEEDGIANT: u32 = 2048;\npub const CTLSHIFT_SECURE: u32 = 20;\npub const CTLFLAG_SECURE1: u32 = 134217728;\npub const CTLFLAG_SECURE2: u32 = 135266304;\npub const CTLFLAG_SECURE3: u32 = 136314880;\npub const OID_AUTO: i32 = -1;\npub const CTL_AUTO_START: u32 = 256;\npub const CTL_SYSCTL: u32 = 0;\npub const CTL_KERN: u32 = 1;\npub const CTL_VM: u32 = 2;\npub const CTL_VFS: u32 = 3;\npub const CTL_NET: u32 = 4;\npub const CTL_DEBUG: u32 = 5;\npub const CTL_HW: u32 = 6;\npub const CTL_MACHDEP: u32 = 7;\npub const CTL_USER: u32 = 8;\npub const CTL_P1003_1B: u32 = 9;\npub const CTL_SYSCTL_DEBUG: u32 = 0;\npub const CTL_SYSCTL_NAME: u32 = 1;\npub const CTL_SYSCTL_NEXT: u32 = 2;\npub const CTL_SYSCTL_NAME2OID: u32 = 3;\npub const CTL_SYSCTL_OIDFMT: u32 = 4;\npub const CTL_SYSCTL_OIDDESCR: u32 = 5;\npub const CTL_SYSCTL_OIDLABEL: u32 = 6;\npub const CTL_SYSCTL_NEXTNOSKIP: u32 = 7;\npub const KERN_OSTYPE: u32 = 1;\npub const KERN_OSRELEASE: u32 = 2;\npub const KERN_OSREV: u32 = 3;\npub const KERN_VERSION: u32 = 4;\npub const KERN_MAXVNODES: u32 = 5;\npub const KERN_MAXPROC: u32 = 6;\npub const KERN_MAXFILES: u32 = 7;\npub const KERN_ARGMAX: u32 = 8;\npub const KERN_SECURELVL: u32 = 9;\npub const KERN_HOSTNAME: u32 = 10;\npub const KERN_HOSTID: u32 = 11;\npub const KERN_CLOCKRATE: u32 = 12;\npub const KERN_PROC: u32 = 14;\npub const KERN_FILE: u32 = 15;\npub const KERN_PROF: u32 = 16;\npub const KERN_POSIX1: u32 = 17;\npub const KERN_NGROUPS: u32 = 18;\npub const KERN_JOB_CONTROL: u32 = 19;\npub const KERN_SAVED_IDS: u32 = 20;\npub const KERN_BOOTTIME: u32 = 21;\npub const KERN_NISDOMAINNAME: u32 = 22;\npub const KERN_UPDATEINTERVAL: u32 = 23;\npub const KERN_OSRELDATE: u32 = 24;\npub const KERN_NTP_PLL: u32 = 25;\npub const KERN_BOOTFILE: u32 = 26;\npub const KERN_MAXFILESPERPROC: u32 = 27;\npub const KERN_MAXPROCPERUID: u32 = 28;\npub const KERN_DUMPDEV: u32 = 29;\npub const KERN_IPC: u32 = 30;\npub const KERN_DUMMY: u32 = 31;\npub const KERN_PS_STRINGS: u32 = 32;\npub const KERN_USRSTACK: u32 = 33;\npub const KERN_LOGSIGEXIT: u32 = 34;\npub const KERN_IOV_MAX: u32 = 35;\npub const KERN_HOSTUUID: u32 = 36;\npub const KERN_ARND: u32 = 37;\npub const KERN_MAXPHYS: u32 = 38;\npub const KERN_LOCKF: u32 = 39;\npub const KERN_PROC_ALL: u32 = 0;\npub const KERN_PROC_PID: u32 = 1;\npub const KERN_PROC_PGRP: u32 = 2;\npub const KERN_PROC_SESSION: u32 = 3;\npub const KERN_PROC_TTY: u32 = 4;\npub const KERN_PROC_UID: u32 = 5;\npub const KERN_PROC_RUID: u32 = 6;\npub const KERN_PROC_ARGS: u32 = 7;\npub const KERN_PROC_PROC: u32 = 8;\npub const KERN_PROC_SV_NAME: u32 = 9;\npub const KERN_PROC_RGID: u32 = 10;\npub const KERN_PROC_GID: u32 = 11;\npub const KERN_PROC_PATHNAME: u32 = 12;\npub const KERN_PROC_OVMMAP: u32 = 13;\npub const KERN_PROC_OFILEDESC: u32 = 14;\npub const KERN_PROC_KSTACK: u32 = 15;\npub const KERN_PROC_INC_THREAD: u32 = 16;\npub const KERN_PROC_VMMAP: u32 = 32;\npub const KERN_PROC_FILEDESC: u32 = 33;\npub const KERN_PROC_GROUPS: u32 = 34;\npub const KERN_PROC_ENV: u32 = 35;\npub const KERN_PROC_AUXV: u32 = 36;\npub const KERN_PROC_RLIMIT: u32 = 37;\npub const KERN_PROC_PS_STRINGS: u32 = 38;\npub const KERN_PROC_UMASK: u32 = 39;\npub const KERN_PROC_OSREL: u32 = 40;\npub const KERN_PROC_SIGTRAMP: u32 = 41;\npub const KERN_PROC_CWD: u32 = 42;\npub const KERN_PROC_NFDS: u32 = 43;\npub const KERN_PROC_SIGFASTBLK: u32 = 44;\npub const KERN_PROC_VM_LAYOUT: u32 = 45;\npub const KIPC_MAXSOCKBUF: u32 = 1;\npub const KIPC_SOCKBUF_WASTE: u32 = 2;\npub const KIPC_SOMAXCONN: u32 = 3;\npub const KIPC_MAX_LINKHDR: u32 = 4;\npub const KIPC_MAX_PROTOHDR: u32 = 5;\npub const KIPC_MAX_HDR: u32 = 6;\npub const KIPC_MAX_DATALEN: u32 = 7;\npub const HW_MACHINE: u32 = 1;\npub const HW_MODEL: u32 = 2;\npub const HW_NCPU: u32 = 3;\npub const HW_BYTEORDER: u32 = 4;\npub const HW_PHYSMEM: u32 = 5;\npub const HW_USERMEM: u32 = 6;\npub const HW_PAGESIZE: u32 = 7;\npub const HW_DISKNAMES: u32 = 8;\npub const HW_DISKSTATS: u32 = 9;\npub const HW_FLOATINGPT: u32 = 10;\npub const HW_MACHINE_ARCH: u32 = 11;\npub const HW_REALMEM: u32 = 12;\npub const USER_CS_PATH: u32 = 1;\npub const USER_BC_BASE_MAX: u32 = 2;\npub const USER_BC_DIM_MAX: u32 = 3;\npub const USER_BC_SCALE_MAX: u32 = 4;\npub const USER_BC_STRING_MAX: u32 = 5;\npub const USER_COLL_WEIGHTS_MAX: u32 = 6;\npub const USER_EXPR_NEST_MAX: u32 = 7;\npub const USER_LINE_MAX: u32 = 8;\npub const USER_RE_DUP_MAX: u32 = 9;\npub const USER_POSIX2_VERSION: u32 = 10;\npub const USER_POSIX2_C_BIND: u32 = 11;\npub const USER_POSIX2_C_DEV: u32 = 12;\npub const USER_POSIX2_CHAR_TERM: u32 = 13;\npub const USER_POSIX2_FORT_DEV: u32 = 14;\npub const USER_POSIX2_FORT_RUN: u32 = 15;\npub const USER_POSIX2_LOCALEDEF: u32 = 16;\npub const USER_POSIX2_SW_DEV: u32 = 17;\npub const USER_POSIX2_UPE: u32 = 18;\npub const USER_STREAM_MAX: u32 = 19;\npub const USER_TZNAME_MAX: u32 = 20;\npub const USER_LOCALBASE: u32 = 21;\npub const CTL_P1003_1B_ASYNCHRONOUS_IO: u32 = 1;\npub const CTL_P1003_1B_MAPPED_FILES: u32 = 2;\npub const CTL_P1003_1B_MEMLOCK: u32 = 3;\npub const CTL_P1003_1B_MEMLOCK_RANGE: u32 = 4;\npub const CTL_P1003_1B_MEMORY_PROTECTION: u32 = 5;\npub const CTL_P1003_1B_MESSAGE_PASSING: u32 = 6;\npub const CTL_P1003_1B_PRIORITIZED_IO: u32 = 7;\npub const CTL_P1003_1B_PRIORITY_SCHEDULING: u32 = 8;\npub const CTL_P1003_1B_REALTIME_SIGNALS: u32 = 9;\npub const CTL_P1003_1B_SEMAPHORES: u32 = 10;\npub const CTL_P1003_1B_FSYNC: u32 = 11;\npub const CTL_P1003_1B_SHARED_MEMORY_OBJECTS: u32 = 12;\npub const CTL_P1003_1B_SYNCHRONIZED_IO: u32 = 13;\npub const CTL_P1003_1B_TIMERS: u32 = 14;\npub const CTL_P1003_1B_AIO_LISTIO_MAX: u32 = 15;\npub const CTL_P1003_1B_AIO_MAX: u32 = 16;\npub const CTL_P1003_1B_AIO_PRIO_DELTA_MAX: u32 = 17;\npub const CTL_P1003_1B_DELAYTIMER_MAX: u32 = 18;\npub const CTL_P1003_1B_MQ_OPEN_MAX: u32 = 19;\npub const CTL_P1003_1B_PAGESIZE: u32 = 20;\npub const CTL_P1003_1B_RTSIG_MAX: u32 = 21;\npub const CTL_P1003_1B_SEM_NSEMS_MAX: u32 = 22;\npub const CTL_P1003_1B_SEM_VALUE_MAX: u32 = 23;\npub const CTL_P1003_1B_SIGQUEUE_MAX: u32 = 24;\npub const CTL_P1003_1B_TIMER_MAX: u32 = 25;\npub const KTR_GEN: u32 = 1;\npub const KTR_NET: u32 = 2;\npub const KTR_DEV: u32 = 4;\npub const KTR_LOCK: u32 = 8;\npub const KTR_SMP: u32 = 16;\npub const KTR_SUBSYS: u32 = 32;\npub const KTR_PMAP: u32 = 64;\npub const KTR_MALLOC: u32 = 128;\npub const KTR_TRAP: u32 = 256;\npub const KTR_INTR: u32 = 512;\npub const KTR_SIG: u32 = 1024;\npub const KTR_SPARE2: u32 = 2048;\npub const KTR_PROC: u32 = 4096;\npub const KTR_SYSC: u32 = 8192;\npub const KTR_INIT: u32 = 16384;\npub const KTR_SPARE3: u32 = 32768;\npub const KTR_SPARE4: u32 = 65536;\npub const KTR_EVH: u32 = 131072;\npub const KTR_VFS: u32 = 262144;\npub const KTR_VOP: u32 = 524288;\npub const KTR_VM: u32 = 1048576;\npub const KTR_INET: u32 = 2097152;\npub const KTR_RUNQ: u32 = 4194304;\npub const KTR_SPARE5: u32 = 8388608;\npub const KTR_UMA: u32 = 16777216;\npub const KTR_CALLOUT: u32 = 33554432;\npub const KTR_GEOM: u32 = 67108864;\npub const KTR_BUSDMA: u32 = 134217728;\npub const KTR_INET6: u32 = 268435456;\npub const KTR_SCHED: u32 = 536870912;\npub const KTR_BUF: u32 = 1073741824;\npub const KTR_PTRACE: u32 = 2147483648;\npub const KTR_ALL: u32 = 4294967295;\npub const KTR_COMPILE: u32 = 0;\npub const LC_SLEEPLOCK: u32 = 1;\npub const LC_SPINLOCK: u32 = 2;\npub const LC_SLEEPABLE: u32 = 4;\npub const LC_RECURSABLE: u32 = 8;\npub const LC_UPGRADABLE: u32 = 16;\npub const LO_CLASSFLAGS: u32 = 65535;\npub const LO_INITIALIZED: u32 = 65536;\npub const LO_WITNESS: u32 = 131072;\npub const LO_QUIET: u32 = 262144;\npub const LO_RECURSABLE: u32 = 524288;\npub const LO_SLEEPABLE: u32 = 1048576;\npub const LO_UPGRADABLE: u32 = 2097152;\npub const LO_DUPOK: u32 = 4194304;\npub const LO_IS_VNODE: u32 = 8388608;\npub const LO_CLASSMASK: u32 = 251658240;\npub const LO_NOPROFILE: u32 = 268435456;\npub const LO_NEW: u32 = 536870912;\npub const LO_CLASSSHIFT: u32 = 24;\npub const LOCK_CLASS_MAX: u32 = 15;\npub const LOP_NEWORDER: u32 = 1;\npub const LOP_QUIET: u32 = 2;\npub const LOP_TRYLOCK: u32 = 4;\npub const LOP_EXCLUSIVE: u32 = 8;\npub const LOP_DUPOK: u32 = 16;\npub const LOP_NOSLEEP: u32 = 32;\npub const LA_MASKASSERT: u32 = 255;\npub const LA_UNLOCKED: u32 = 0;\npub const LA_LOCKED: u32 = 1;\npub const LA_SLOCKED: u32 = 2;\npub const LA_XLOCKED: u32 = 4;\npub const LA_RECURSED: u32 = 8;\npub const LA_NOTRECURSED: u32 = 16;\npub const SX_LOCK_SHARED: u32 = 1;\npub const SX_LOCK_SHARED_WAITERS: u32 = 2;\npub const SX_LOCK_EXCLUSIVE_WAITERS: u32 = 4;\npub const SX_LOCK_WRITE_SPINNER: u32 = 8;\npub const SX_LOCK_RECURSED: u32 = 16;\npub const SX_LOCK_FLAGMASK: u32 = 31;\npub const SX_LOCK_WAITERS: u32 = 6;\npub const SX_SHARERS_SHIFT: u32 = 5;\npub const SX_ONE_SHARER: u32 = 32;\npub const SX_LOCK_DESTROYED: u32 = 6;\npub const SPLAY_NEGINF: i32 = -1;\npub const SPLAY_INF: u32 = 1;\npub const RB_STRICT_HST: u32 = 0;\npub const RB_NEGINF: i32 = -1;\npub const RB_INF: u32 = 1;\npub const UMA_SMALLEST_UNIT: u32 = 8;\npub const UMA_ZONE_UNMANAGED: u32 = 1;\npub const UMA_ZONE_ZINIT: u32 = 2;\npub const UMA_ZONE_CONTIG: u32 = 4;\npub const UMA_ZONE_NOTOUCH: u32 = 8;\npub const UMA_ZONE_MALLOC: u32 = 16;\npub const UMA_ZONE_NOFREE: u32 = 32;\npub const UMA_ZONE_MTXCLASS: u32 = 64;\npub const UMA_ZONE_VM: u32 = 128;\npub const UMA_ZONE_NOTPAGE: u32 = 256;\npub const UMA_ZONE_SECONDARY: u32 = 512;\npub const UMA_ZONE_NOBUCKET: u32 = 1024;\npub const UMA_ZONE_MAXBUCKET: u32 = 2048;\npub const UMA_ZONE_CACHESPREAD: u32 = 8192;\npub const UMA_ZONE_NODUMP: u32 = 16384;\npub const UMA_ZONE_PCPU: u32 = 32768;\npub const UMA_ZONE_FIRSTTOUCH: u32 = 65536;\npub const UMA_ZONE_ROUNDROBIN: u32 = 131072;\npub const UMA_ZONE_SMR: u32 = 262144;\npub const UMA_ZONE_NOKASAN: u32 = 524288;\npub const UMA_ZONE_INHERIT: u32 = 754104;\npub const UMA_ALIGN_CACHE: i32 = -1;\npub const UMA_ANYDOMAIN: i32 = -1;\npub const UMA_RECLAIM_DRAIN: u32 = 1;\npub const UMA_RECLAIM_DRAIN_CPU: u32 = 2;\npub const UMA_RECLAIM_TRIM: u32 = 3;\npub const UMA_SLAB_BOOT: u32 = 1;\npub const UMA_SLAB_KERNEL: u32 = 4;\npub const UMA_SLAB_PRIV: u32 = 8;\npub const UMA_STREAM_VERSION: u32 = 1;\npub const UTH_MAX_NAME: u32 = 32;\npub const UTH_ZONE_SECONDARY: u32 = 1;\npub const CLOCK_REALTIME: u32 = 0;\npub const CLOCK_VIRTUAL: u32 = 1;\npub const CLOCK_PROF: u32 = 2;\npub const CLOCK_MONOTONIC: u32 = 4;\npub const CLOCK_UPTIME_FAST: u32 = 8;\npub const CLOCK_UPTIME: u32 = 5;\npub const CLOCK_UPTIME_PRECISE: u32 = 7;\npub const CLOCK_REALTIME_PRECISE: u32 = 9;\npub const CLOCK_REALTIME_FAST: u32 = 10;\npub const CLOCK_MONOTONIC_PRECISE: u32 = 11;\npub const CLOCK_MONOTONIC_FAST: u32 = 12;\npub const CLOCK_SECOND: u32 = 13;\npub const CLOCK_THREAD_CPUTIME_ID: u32 = 14;\npub const CLOCK_PROCESS_CPUTIME_ID: u32 = 15;\npub const CLOCK_BOOTTIME: u32 = 5;\npub const CLOCK_REALTIME_COARSE: u32 = 10;\npub const CLOCK_MONOTONIC_COARSE: u32 = 12;\npub const TIMER_RELTIME: u32 = 0;\npub const TIMER_ABSTIME: u32 = 1;\npub const DST_NONE: u32 = 0;\npub const DST_USA: u32 = 1;\npub const DST_AUST: u32 = 2;\npub const DST_WET: u32 = 3;\npub const DST_MET: u32 = 4;\npub const DST_EET: u32 = 5;\npub const DST_CAN: u32 = 6;\npub const SBT_MAX: u64 = 9223372036854775807;\npub const ITIMER_REAL: u32 = 0;\npub const ITIMER_VIRTUAL: u32 = 1;\npub const ITIMER_PROF: u32 = 2;\npub const CPUCLOCK_WHICH_PID: u32 = 0;\npub const CPUCLOCK_WHICH_TID: u32 = 1;\npub const CLK_TCK: u32 = 128;\npub const CLOCKS_PER_SEC: u32 = 128;\npub const TIME_UTC: u32 = 1;\npub const TIME_MONOTONIC: u32 = 2;\npub const SOCK_STREAM: u32 = 1;\npub const SOCK_DGRAM: u32 = 2;\npub const SOCK_RAW: u32 = 3;\npub const SOCK_RDM: u32 = 4;\npub const SOCK_SEQPACKET: u32 = 5;\npub const SOCK_CLOEXEC: u32 = 268435456;\npub const SOCK_NONBLOCK: u32 = 536870912;\npub const SO_DEBUG: u32 = 1;\npub const SO_ACCEPTCONN: u32 = 2;\npub const SO_REUSEADDR: u32 = 4;\npub const SO_KEEPALIVE: u32 = 8;\npub const SO_DONTROUTE: u32 = 16;\npub const SO_BROADCAST: u32 = 32;\npub const SO_USELOOPBACK: u32 = 64;\npub const SO_LINGER: u32 = 128;\npub const SO_OOBINLINE: u32 = 256;\npub const SO_REUSEPORT: u32 = 512;\npub const SO_TIMESTAMP: u32 = 1024;\npub const SO_NOSIGPIPE: u32 = 2048;\npub const SO_ACCEPTFILTER: u32 = 4096;\npub const SO_BINTIME: u32 = 8192;\npub const SO_NO_OFFLOAD: u32 = 16384;\npub const SO_NO_DDP: u32 = 32768;\npub const SO_REUSEPORT_LB: u32 = 65536;\npub const SO_RERROR: u32 = 131072;\npub const SO_SNDBUF: u32 = 4097;\npub const SO_RCVBUF: u32 = 4098;\npub const SO_SNDLOWAT: u32 = 4099;\npub const SO_RCVLOWAT: u32 = 4100;\npub const SO_SNDTIMEO: u32 = 4101;\npub const SO_RCVTIMEO: u32 = 4102;\npub const SO_ERROR: u32 = 4103;\npub const SO_TYPE: u32 = 4104;\npub const SO_LABEL: u32 = 4105;\npub const SO_PEERLABEL: u32 = 4112;\npub const SO_LISTENQLIMIT: u32 = 4113;\npub const SO_LISTENQLEN: u32 = 4114;\npub const SO_LISTENINCQLEN: u32 = 4115;\npub const SO_SETFIB: u32 = 4116;\npub const SO_USER_COOKIE: u32 = 4117;\npub const SO_PROTOCOL: u32 = 4118;\npub const SO_PROTOTYPE: u32 = 4118;\npub const SO_TS_CLOCK: u32 = 4119;\npub const SO_MAX_PACING_RATE: u32 = 4120;\npub const SO_DOMAIN: u32 = 4121;\npub const SO_TS_REALTIME_MICRO: u32 = 0;\npub const SO_TS_BINTIME: u32 = 1;\npub const SO_TS_REALTIME: u32 = 2;\npub const SO_TS_MONOTONIC: u32 = 3;\npub const SO_TS_DEFAULT: u32 = 0;\npub const SO_TS_CLOCK_MAX: u32 = 3;\npub const SO_VENDOR: u32 = 2147483648;\npub const SOL_SOCKET: u32 = 65535;\npub const AF_UNSPEC: u32 = 0;\npub const AF_UNIX: u32 = 1;\npub const AF_INET: u32 = 2;\npub const AF_IMPLINK: u32 = 3;\npub const AF_PUP: u32 = 4;\npub const AF_CHAOS: u32 = 5;\npub const AF_NETBIOS: u32 = 6;\npub const AF_ISO: u32 = 7;\npub const AF_OSI: u32 = 7;\npub const AF_ECMA: u32 = 8;\npub const AF_DATAKIT: u32 = 9;\npub const AF_CCITT: u32 = 10;\npub const AF_SNA: u32 = 11;\npub const AF_DECnet: u32 = 12;\npub const AF_DLI: u32 = 13;\npub const AF_LAT: u32 = 14;\npub const AF_HYLINK: u32 = 15;\npub const AF_APPLETALK: u32 = 16;\npub const AF_ROUTE: u32 = 17;\npub const AF_LINK: u32 = 18;\npub const pseudo_AF_XTP: u32 = 19;\npub const AF_COIP: u32 = 20;\npub const AF_CNT: u32 = 21;\npub const pseudo_AF_RTIP: u32 = 22;\npub const AF_IPX: u32 = 23;\npub const AF_SIP: u32 = 24;\npub const pseudo_AF_PIP: u32 = 25;\npub const AF_ISDN: u32 = 26;\npub const AF_E164: u32 = 26;\npub const pseudo_AF_KEY: u32 = 27;\npub const AF_INET6: u32 = 28;\npub const AF_NATM: u32 = 29;\npub const AF_ATM: u32 = 30;\npub const pseudo_AF_HDRCMPLT: u32 = 31;\npub const AF_NETGRAPH: u32 = 32;\npub const AF_SLOW: u32 = 33;\npub const AF_SCLUSTER: u32 = 34;\npub const AF_ARP: u32 = 35;\npub const AF_BLUETOOTH: u32 = 36;\npub const AF_IEEE80211: u32 = 37;\npub const AF_NETLINK: u32 = 38;\npub const AF_INET_SDP: u32 = 40;\npub const AF_INET6_SDP: u32 = 42;\npub const AF_HYPERV: u32 = 43;\npub const AF_DIVERT: u32 = 44;\npub const AF_MAX: u32 = 44;\npub const AF_VENDOR00: u32 = 39;\npub const AF_VENDOR01: u32 = 41;\npub const AF_VENDOR03: u32 = 45;\npub const AF_VENDOR04: u32 = 47;\npub const AF_VENDOR05: u32 = 49;\npub const AF_VENDOR06: u32 = 51;\npub const AF_VENDOR07: u32 = 53;\npub const AF_VENDOR08: u32 = 55;\npub const AF_VENDOR09: u32 = 57;\npub const AF_VENDOR10: u32 = 59;\npub const AF_VENDOR11: u32 = 61;\npub const AF_VENDOR12: u32 = 63;\npub const AF_VENDOR13: u32 = 65;\npub const AF_VENDOR14: u32 = 67;\npub const AF_VENDOR15: u32 = 69;\npub const AF_VENDOR16: u32 = 71;\npub const AF_VENDOR17: u32 = 73;\npub const AF_VENDOR18: u32 = 75;\npub const AF_VENDOR19: u32 = 77;\npub const AF_VENDOR20: u32 = 79;\npub const AF_VENDOR21: u32 = 81;\npub const AF_VENDOR22: u32 = 83;\npub const AF_VENDOR23: u32 = 85;\npub const AF_VENDOR24: u32 = 87;\npub const AF_VENDOR25: u32 = 89;\npub const AF_VENDOR26: u32 = 91;\npub const AF_VENDOR27: u32 = 93;\npub const AF_VENDOR28: u32 = 95;\npub const AF_VENDOR29: u32 = 97;\npub const AF_VENDOR30: u32 = 99;\npub const AF_VENDOR31: u32 = 101;\npub const AF_VENDOR32: u32 = 103;\npub const AF_VENDOR33: u32 = 105;\npub const AF_VENDOR34: u32 = 107;\npub const AF_VENDOR35: u32 = 109;\npub const AF_VENDOR36: u32 = 111;\npub const AF_VENDOR37: u32 = 113;\npub const AF_VENDOR38: u32 = 115;\npub const AF_VENDOR39: u32 = 117;\npub const AF_VENDOR40: u32 = 119;\npub const AF_VENDOR41: u32 = 121;\npub const AF_VENDOR42: u32 = 123;\npub const AF_VENDOR43: u32 = 125;\npub const AF_VENDOR44: u32 = 127;\npub const AF_VENDOR45: u32 = 129;\npub const AF_VENDOR46: u32 = 131;\npub const AF_VENDOR47: u32 = 133;\npub const SOCK_MAXADDRLEN: u32 = 255;\npub const _SS_MAXSIZE: u32 = 128;\npub const PF_UNSPEC: u32 = 0;\npub const PF_INET: u32 = 2;\npub const PF_IMPLINK: u32 = 3;\npub const PF_PUP: u32 = 4;\npub const PF_CHAOS: u32 = 5;\npub const PF_NETBIOS: u32 = 6;\npub const PF_ISO: u32 = 7;\npub const PF_OSI: u32 = 7;\npub const PF_ECMA: u32 = 8;\npub const PF_DATAKIT: u32 = 9;\npub const PF_CCITT: u32 = 10;\npub const PF_SNA: u32 = 11;\npub const PF_DECnet: u32 = 12;\npub const PF_DLI: u32 = 13;\npub const PF_LAT: u32 = 14;\npub const PF_HYLINK: u32 = 15;\npub const PF_APPLETALK: u32 = 16;\npub const PF_ROUTE: u32 = 17;\npub const PF_LINK: u32 = 18;\npub const PF_XTP: u32 = 19;\npub const PF_COIP: u32 = 20;\npub const PF_CNT: u32 = 21;\npub const PF_SIP: u32 = 24;\npub const PF_IPX: u32 = 23;\npub const PF_RTIP: u32 = 22;\npub const PF_PIP: u32 = 25;\npub const PF_ISDN: u32 = 26;\npub const PF_KEY: u32 = 27;\npub const PF_INET6: u32 = 28;\npub const PF_NATM: u32 = 29;\npub const PF_ATM: u32 = 30;\npub const PF_NETGRAPH: u32 = 32;\npub const PF_SLOW: u32 = 33;\npub const PF_SCLUSTER: u32 = 34;\npub const PF_ARP: u32 = 35;\npub const PF_BLUETOOTH: u32 = 36;\npub const PF_IEEE80211: u32 = 37;\npub const PF_NETLINK: u32 = 38;\npub const PF_INET_SDP: u32 = 40;\npub const PF_INET6_SDP: u32 = 42;\npub const PF_DIVERT: u32 = 44;\npub const PF_MAX: u32 = 44;\npub const NET_RT_DUMP: u32 = 1;\npub const NET_RT_FLAGS: u32 = 2;\npub const NET_RT_IFLIST: u32 = 3;\npub const NET_RT_IFMALIST: u32 = 4;\npub const NET_RT_IFLISTL: u32 = 5;\npub const NET_RT_NHOP: u32 = 6;\npub const NET_RT_NHGRP: u32 = 7;\npub const SOMAXCONN: u32 = 128;\npub const MSG_OOB: u32 = 1;\npub const MSG_PEEK: u32 = 2;\npub const MSG_DONTROUTE: u32 = 4;\npub const MSG_EOR: u32 = 8;\npub const MSG_TRUNC: u32 = 16;\npub const MSG_CTRUNC: u32 = 32;\npub const MSG_WAITALL: u32 = 64;\npub const MSG_DONTWAIT: u32 = 128;\npub const MSG_EOF: u32 = 256;\npub const MSG_NOTIFICATION: u32 = 8192;\npub const MSG_NBIO: u32 = 16384;\npub const MSG_COMPAT: u32 = 32768;\npub const MSG_NOSIGNAL: u32 = 131072;\npub const MSG_CMSG_CLOEXEC: u32 = 262144;\npub const MSG_WAITFORONE: u32 = 524288;\npub const CMGROUP_MAX: u32 = 16;\npub const SCM_RIGHTS: u32 = 1;\npub const SCM_TIMESTAMP: u32 = 2;\npub const SCM_CREDS: u32 = 3;\npub const SCM_BINTIME: u32 = 4;\npub const SCM_REALTIME: u32 = 5;\npub const SCM_MONOTONIC: u32 = 6;\npub const SCM_TIME_INFO: u32 = 7;\npub const SCM_CREDS2: u32 = 8;\npub const ST_INFO_HW: u32 = 1;\npub const ST_INFO_HW_HPREC: u32 = 2;\npub const SHUT_RD: u32 = 0;\npub const SHUT_WR: u32 = 1;\npub const SHUT_RDWR: u32 = 2;\npub const PRU_FLUSH_RD: u32 = 0;\npub const PRU_FLUSH_WR: u32 = 1;\npub const PRU_FLUSH_RDWR: u32 = 2;\npub const SF_NODISKIO: u32 = 1;\npub const SF_MNOWAIT: u32 = 2;\npub const SF_SYNC: u32 = 4;\npub const SF_USER_READAHEAD: u32 = 8;\npub const SF_NOCACHE: u32 = 16;\npub const IF_NAMESIZE: u32 = 16;\npub const IFNAMSIZ: u32 = 16;\npub const IF_MAXUNIT: u32 = 32767;\npub const IFF_UP: u32 = 1;\npub const IFF_BROADCAST: u32 = 2;\npub const IFF_DEBUG: u32 = 4;\npub const IFF_LOOPBACK: u32 = 8;\npub const IFF_POINTOPOINT: u32 = 16;\npub const IFF_NEEDSEPOCH: u32 = 32;\npub const IFF_DRV_RUNNING: u32 = 64;\npub const IFF_NOARP: u32 = 128;\npub const IFF_PROMISC: u32 = 256;\npub const IFF_ALLMULTI: u32 = 512;\npub const IFF_DRV_OACTIVE: u32 = 1024;\npub const IFF_SIMPLEX: u32 = 2048;\npub const IFF_LINK0: u32 = 4096;\npub const IFF_LINK1: u32 = 8192;\npub const IFF_LINK2: u32 = 16384;\npub const IFF_ALTPHYS: u32 = 16384;\npub const IFF_MULTICAST: u32 = 32768;\npub const IFF_CANTCONFIG: u32 = 65536;\npub const IFF_PPROMISC: u32 = 131072;\npub const IFF_MONITOR: u32 = 262144;\npub const IFF_STATICARP: u32 = 524288;\npub const IFF_STICKYARP: u32 = 1048576;\npub const IFF_DYING: u32 = 2097152;\npub const IFF_RENAMING: u32 = 4194304;\npub const IFF_SPARE: u32 = 8388608;\npub const IFF_NETLINK_1: u32 = 16777216;\npub const IFF_RUNNING: u32 = 64;\npub const IFF_OACTIVE: u32 = 1024;\npub const IFF_CANTCHANGE: u32 = 2199410;\npub const LINK_STATE_UNKNOWN: u32 = 0;\npub const LINK_STATE_DOWN: u32 = 1;\npub const LINK_STATE_UP: u32 = 2;\npub const IFCAP_B_RXCSUM: u32 = 0;\npub const IFCAP_B_TXCSUM: u32 = 1;\npub const IFCAP_B_NETCONS: u32 = 2;\npub const IFCAP_B_VLAN_MTU: u32 = 3;\npub const IFCAP_B_VLAN_HWTAGGING: u32 = 4;\npub const IFCAP_B_JUMBO_MTU: u32 = 5;\npub const IFCAP_B_POLLING: u32 = 6;\npub const IFCAP_B_VLAN_HWCSUM: u32 = 7;\npub const IFCAP_B_TSO4: u32 = 8;\npub const IFCAP_B_TSO6: u32 = 9;\npub const IFCAP_B_LRO: u32 = 10;\npub const IFCAP_B_WOL_UCAST: u32 = 11;\npub const IFCAP_B_WOL_MCAST: u32 = 12;\npub const IFCAP_B_WOL_MAGIC: u32 = 13;\npub const IFCAP_B_TOE4: u32 = 14;\npub const IFCAP_B_TOE6: u32 = 15;\npub const IFCAP_B_VLAN_HWFILTER: u32 = 16;\npub const IFCAP_B_NV: u32 = 17;\npub const IFCAP_B_VLAN_HWTSO: u32 = 18;\npub const IFCAP_B_LINKSTATE: u32 = 19;\npub const IFCAP_B_NETMAP: u32 = 20;\npub const IFCAP_B_RXCSUM_IPV6: u32 = 21;\npub const IFCAP_B_TXCSUM_IPV6: u32 = 22;\npub const IFCAP_B_HWSTATS: u32 = 23;\npub const IFCAP_B_TXRTLMT: u32 = 24;\npub const IFCAP_B_HWRXTSTMP: u32 = 25;\npub const IFCAP_B_MEXTPG: u32 = 26;\npub const IFCAP_B_TXTLS4: u32 = 27;\npub const IFCAP_B_TXTLS6: u32 = 28;\npub const IFCAP_B_VXLAN_HWCSUM: u32 = 29;\npub const IFCAP_B_VXLAN_HWTSO: u32 = 30;\npub const IFCAP_B_TXTLS_RTLMT: u32 = 31;\npub const IFCAP_B_RXTLS4: u32 = 32;\npub const IFCAP_B_RXTLS6: u32 = 33;\npub const __IFCAP_B_SIZE: u32 = 34;\npub const IFCAP_B_SIZE: u32 = 34;\npub const IFCAP2_RXTLS4: u32 = 0;\npub const IFCAP2_RXTLS6: u32 = 1;\npub const IFCAP_ALLCAPS: u32 = 4294967295;\npub const IFQ_MAXLEN: u32 = 50;\npub const IFNET_SLOWHZ: u32 = 1;\npub const IFAN_ARRIVAL: u32 = 0;\npub const IFAN_DEPARTURE: u32 = 1;\npub const IFR_CAP_NV_MAXBUFSIZE: u32 = 2097152;\npub const IFSTATMAX: u32 = 800;\npub const IFG_ALL: &[u8; 4] = b\"all\\0\";\npub const IFG_EGRESS: &[u8; 7] = b\"egress\\0\";\npub const RSS_FUNC_NONE: u32 = 0;\npub const RSS_FUNC_PRIVATE: u32 = 1;\npub const RSS_FUNC_TOEPLITZ: u32 = 2;\npub const RSS_TYPE_IPV4: u32 = 1;\npub const RSS_TYPE_TCP_IPV4: u32 = 2;\npub const RSS_TYPE_IPV6: u32 = 4;\npub const RSS_TYPE_IPV6_EX: u32 = 8;\npub const RSS_TYPE_TCP_IPV6: u32 = 16;\npub const RSS_TYPE_TCP_IPV6_EX: u32 = 32;\npub const RSS_TYPE_UDP_IPV4: u32 = 64;\npub const RSS_TYPE_UDP_IPV6: u32 = 128;\npub const RSS_TYPE_UDP_IPV6_EX: u32 = 256;\npub const RSS_KEYLEN: u32 = 128;\npub const IFNET_PCP_NONE: u32 = 255;\npub const IFDR_MSG_SIZE: u32 = 64;\npub const IFDR_REASON_MSG: u32 = 1;\npub const IFDR_REASON_VENDOR: u32 = 2;\npub const ETHER_ADDR_LEN: u32 = 6;\npub const ETHER_TYPE_LEN: u32 = 2;\npub const ETHER_CRC_LEN: u32 = 4;\npub const ETHER_HDR_LEN: u32 = 14;\npub const ETHER_MIN_LEN: u32 = 64;\npub const ETHER_MAX_LEN: u32 = 1518;\npub const ETHER_MAX_LEN_JUMBO: u32 = 9018;\npub const ETHER_VLAN_ENCAP_LEN: u32 = 4;\npub const ETHER_ALIGN: u32 = 2;\npub const ETHER_CRC_POLY_LE: u32 = 3988292384;\npub const ETHER_CRC_POLY_BE: u32 = 79764918;\npub const EVL_VLID_MASK: u32 = 4095;\npub const EVL_PRI_MASK: u32 = 57344;\npub const ETHERTYPE_8023: u32 = 4;\npub const ETHERTYPE_PUP: u32 = 512;\npub const ETHERTYPE_PUPAT: u32 = 512;\npub const ETHERTYPE_SPRITE: u32 = 1280;\npub const ETHERTYPE_NS: u32 = 1536;\npub const ETHERTYPE_NSAT: u32 = 1537;\npub const ETHERTYPE_DLOG1: u32 = 1632;\npub const ETHERTYPE_DLOG2: u32 = 1633;\npub const ETHERTYPE_IP: u32 = 2048;\npub const ETHERTYPE_X75: u32 = 2049;\npub const ETHERTYPE_NBS: u32 = 2050;\npub const ETHERTYPE_ECMA: u32 = 2051;\npub const ETHERTYPE_CHAOS: u32 = 2052;\npub const ETHERTYPE_X25: u32 = 2053;\npub const ETHERTYPE_ARP: u32 = 2054;\npub const ETHERTYPE_NSCOMPAT: u32 = 2055;\npub const ETHERTYPE_FRARP: u32 = 2056;\npub const ETHERTYPE_UBDEBUG: u32 = 2304;\npub const ETHERTYPE_IEEEPUP: u32 = 2560;\npub const ETHERTYPE_IEEEPUPAT: u32 = 2561;\npub const ETHERTYPE_VINES: u32 = 2989;\npub const ETHERTYPE_VINESLOOP: u32 = 2990;\npub const ETHERTYPE_VINESECHO: u32 = 2991;\npub const ETHERTYPE_TRAIL: u32 = 4096;\npub const ETHERTYPE_NTRAILER: u32 = 16;\npub const ETHERTYPE_DCA: u32 = 4660;\npub const ETHERTYPE_VALID: u32 = 5632;\npub const ETHERTYPE_DOGFIGHT: u32 = 6537;\npub const ETHERTYPE_RCL: u32 = 6549;\npub const ETHERTYPE_NBPVCD: u32 = 15360;\npub const ETHERTYPE_NBPSCD: u32 = 15361;\npub const ETHERTYPE_NBPCREQ: u32 = 15362;\npub const ETHERTYPE_NBPCRSP: u32 = 15363;\npub const ETHERTYPE_NBPCC: u32 = 15364;\npub const ETHERTYPE_NBPCLREQ: u32 = 15365;\npub const ETHERTYPE_NBPCLRSP: u32 = 15366;\npub const ETHERTYPE_NBPDG: u32 = 15367;\npub const ETHERTYPE_NBPDGB: u32 = 15368;\npub const ETHERTYPE_NBPCLAIM: u32 = 15369;\npub const ETHERTYPE_NBPDLTE: u32 = 15370;\npub const ETHERTYPE_NBPRAS: u32 = 15371;\npub const ETHERTYPE_NBPRAR: u32 = 15372;\npub const ETHERTYPE_NBPRST: u32 = 15373;\npub const ETHERTYPE_PCS: u32 = 16962;\npub const ETHERTYPE_IMLBLDIAG: u32 = 16972;\npub const ETHERTYPE_DIDDLE: u32 = 17185;\npub const ETHERTYPE_IMLBL: u32 = 19522;\npub const ETHERTYPE_SIMNET: u32 = 21000;\npub const ETHERTYPE_DECEXPER: u32 = 24576;\npub const ETHERTYPE_MOPDL: u32 = 24577;\npub const ETHERTYPE_MOPRC: u32 = 24578;\npub const ETHERTYPE_DECnet: u32 = 24579;\npub const ETHERTYPE_DN: u32 = 24579;\npub const ETHERTYPE_LAT: u32 = 24580;\npub const ETHERTYPE_DECDIAG: u32 = 24581;\npub const ETHERTYPE_DECCUST: u32 = 24582;\npub const ETHERTYPE_SCA: u32 = 24583;\npub const ETHERTYPE_AMBER: u32 = 24584;\npub const ETHERTYPE_DECMUMPS: u32 = 24585;\npub const ETHERTYPE_TRANSETHER: u32 = 25944;\npub const ETHERTYPE_RAWFR: u32 = 25945;\npub const ETHERTYPE_UBDL: u32 = 28672;\npub const ETHERTYPE_UBNIU: u32 = 28673;\npub const ETHERTYPE_UBDIAGLOOP: u32 = 28674;\npub const ETHERTYPE_UBNMC: u32 = 28675;\npub const ETHERTYPE_UBBST: u32 = 28677;\npub const ETHERTYPE_OS9: u32 = 28679;\npub const ETHERTYPE_OS9NET: u32 = 28681;\npub const ETHERTYPE_RACAL: u32 = 28720;\npub const ETHERTYPE_PRIMENTS: u32 = 28721;\npub const ETHERTYPE_CABLETRON: u32 = 28724;\npub const ETHERTYPE_CRONUSVLN: u32 = 32771;\npub const ETHERTYPE_CRONUS: u32 = 32772;\npub const ETHERTYPE_HP: u32 = 32773;\npub const ETHERTYPE_NESTAR: u32 = 32774;\npub const ETHERTYPE_ATTSTANFORD: u32 = 32776;\npub const ETHERTYPE_EXCELAN: u32 = 32784;\npub const ETHERTYPE_SG_DIAG: u32 = 32787;\npub const ETHERTYPE_SG_NETGAMES: u32 = 32788;\npub const ETHERTYPE_SG_RESV: u32 = 32789;\npub const ETHERTYPE_SG_BOUNCE: u32 = 32790;\npub const ETHERTYPE_APOLLODOMAIN: u32 = 32793;\npub const ETHERTYPE_TYMSHARE: u32 = 32814;\npub const ETHERTYPE_TIGAN: u32 = 32815;\npub const ETHERTYPE_REVARP: u32 = 32821;\npub const ETHERTYPE_AEONIC: u32 = 32822;\npub const ETHERTYPE_IPXNEW: u32 = 32823;\npub const ETHERTYPE_LANBRIDGE: u32 = 32824;\npub const ETHERTYPE_DSMD: u32 = 32825;\npub const ETHERTYPE_ARGONAUT: u32 = 32826;\npub const ETHERTYPE_VAXELN: u32 = 32827;\npub const ETHERTYPE_DECDNS: u32 = 32828;\npub const ETHERTYPE_ENCRYPT: u32 = 32829;\npub const ETHERTYPE_DECDTS: u32 = 32830;\npub const ETHERTYPE_DECLTM: u32 = 32831;\npub const ETHERTYPE_DECNETBIOS: u32 = 32832;\npub const ETHERTYPE_DECLAST: u32 = 32833;\npub const ETHERTYPE_PLANNING: u32 = 32836;\npub const ETHERTYPE_DECAM: u32 = 32840;\npub const ETHERTYPE_EXPERDATA: u32 = 32841;\npub const ETHERTYPE_VEXP: u32 = 32859;\npub const ETHERTYPE_VPROD: u32 = 32860;\npub const ETHERTYPE_ES: u32 = 32861;\npub const ETHERTYPE_LITTLE: u32 = 32864;\npub const ETHERTYPE_COUNTERPOINT: u32 = 32866;\npub const ETHERTYPE_VEECO: u32 = 32871;\npub const ETHERTYPE_GENDYN: u32 = 32872;\npub const ETHERTYPE_ATT: u32 = 32873;\npub const ETHERTYPE_AUTOPHON: u32 = 32874;\npub const ETHERTYPE_COMDESIGN: u32 = 32876;\npub const ETHERTYPE_COMPUGRAPHIC: u32 = 32877;\npub const ETHERTYPE_MATRA: u32 = 32890;\npub const ETHERTYPE_DDE: u32 = 32891;\npub const ETHERTYPE_MERIT: u32 = 32892;\npub const ETHERTYPE_VLTLMAN: u32 = 32896;\npub const ETHERTYPE_ATALK: u32 = 32923;\npub const ETHERTYPE_AT: u32 = 32923;\npub const ETHERTYPE_APPLETALK: u32 = 32923;\npub const ETHERTYPE_SPIDER: u32 = 32927;\npub const ETHERTYPE_PACER: u32 = 32966;\npub const ETHERTYPE_APPLITEK: u32 = 32967;\npub const ETHERTYPE_SNA: u32 = 32981;\npub const ETHERTYPE_VARIAN: u32 = 32989;\npub const ETHERTYPE_RETIX: u32 = 33010;\npub const ETHERTYPE_AARP: u32 = 33011;\npub const ETHERTYPE_APOLLO: u32 = 33015;\npub const ETHERTYPE_VLAN: u32 = 33024;\npub const ETHERTYPE_BOFL: u32 = 33026;\npub const ETHERTYPE_WELLFLEET: u32 = 33027;\npub const ETHERTYPE_TALARIS: u32 = 33067;\npub const ETHERTYPE_WATERLOO: u32 = 33072;\npub const ETHERTYPE_HAYES: u32 = 33072;\npub const ETHERTYPE_VGLAB: u32 = 33073;\npub const ETHERTYPE_IPX: u32 = 33079;\npub const ETHERTYPE_NOVELL: u32 = 33080;\npub const ETHERTYPE_MUMPS: u32 = 33087;\npub const ETHERTYPE_AMOEBA: u32 = 33093;\npub const ETHERTYPE_FLIP: u32 = 33094;\npub const ETHERTYPE_VURESERVED: u32 = 33095;\npub const ETHERTYPE_LOGICRAFT: u32 = 33096;\npub const ETHERTYPE_NCD: u32 = 33097;\npub const ETHERTYPE_ALPHA: u32 = 33098;\npub const ETHERTYPE_SNMP: u32 = 33100;\npub const ETHERTYPE_TEC: u32 = 33103;\npub const ETHERTYPE_RATIONAL: u32 = 33104;\npub const ETHERTYPE_XTP: u32 = 33149;\npub const ETHERTYPE_SGITW: u32 = 33150;\npub const ETHERTYPE_HIPPI_FP: u32 = 33152;\npub const ETHERTYPE_STP: u32 = 33153;\npub const ETHERTYPE_MOTOROLA: u32 = 33165;\npub const ETHERTYPE_NETBEUI: u32 = 33169;\npub const ETHERTYPE_ACCTON: u32 = 33680;\npub const ETHERTYPE_TALARISMC: u32 = 34091;\npub const ETHERTYPE_KALPANA: u32 = 34178;\npub const ETHERTYPE_SECTRA: u32 = 34523;\npub const ETHERTYPE_IPV6: u32 = 34525;\npub const ETHERTYPE_DELTACON: u32 = 34526;\npub const ETHERTYPE_ATOMIC: u32 = 34527;\npub const ETHERTYPE_RDP: u32 = 34617;\npub const ETHERTYPE_MICP: u32 = 34618;\npub const ETHERTYPE_TCPCOMP: u32 = 34667;\npub const ETHERTYPE_IPAS: u32 = 34668;\npub const ETHERTYPE_SECUREDATA: u32 = 34669;\npub const ETHERTYPE_FLOWCONTROL: u32 = 34824;\npub const ETHERTYPE_SLOW: u32 = 34825;\npub const ETHERTYPE_PPP: u32 = 34827;\npub const ETHERTYPE_HITACHI: u32 = 34848;\npub const ETHERTYPE_TEST: u32 = 34850;\npub const ETHERTYPE_MPLS: u32 = 34887;\npub const ETHERTYPE_MPLS_MCAST: u32 = 34888;\npub const ETHERTYPE_AXIS: u32 = 34902;\npub const ETHERTYPE_PPPOEDISC: u32 = 34915;\npub const ETHERTYPE_PPPOE: u32 = 34916;\npub const ETHERTYPE_LANPROBE: u32 = 34952;\npub const ETHERTYPE_PAE: u32 = 34958;\npub const ETHERTYPE_PROFINET: u32 = 34962;\npub const ETHERTYPE_AOE: u32 = 34978;\npub const ETHERTYPE_ETHERCAT: u32 = 34980;\npub const ETHERTYPE_QINQ: u32 = 34984;\npub const ETHERTYPE_POWERLINK: u32 = 34987;\npub const ETHERTYPE_LLDP: u32 = 35020;\npub const ETHERTYPE_SERCOS: u32 = 35021;\npub const ETHERTYPE_MACSEC: u32 = 35045;\npub const ETHERTYPE_PBB: u32 = 35047;\npub const ETHERTYPE_FCOE: u32 = 35078;\npub const ETHERTYPE_LOOPBACK: u32 = 36864;\npub const ETHERTYPE_8021Q9100: u32 = 37120;\npub const ETHERTYPE_LBACK: u32 = 36864;\npub const ETHERTYPE_XNSSM: u32 = 36865;\npub const ETHERTYPE_TCPSM: u32 = 36866;\npub const ETHERTYPE_BCLOOP: u32 = 36867;\npub const ETHERTYPE_8021Q9200: u32 = 37376;\npub const ETHERTYPE_8021Q9300: u32 = 37632;\npub const ETHERTYPE_DEBNI: u32 = 43690;\npub const ETHERTYPE_SONIX: u32 = 64245;\npub const ETHERTYPE_VITAL: u32 = 65280;\npub const ETHERTYPE_MAX: u32 = 65535;\npub const ETHERMTU: u32 = 1500;\npub const ETHERMIN: u32 = 46;\npub const ETHERMTU_JUMBO: u32 = 9000;\npub const IEEE8021Q_PCP_BK: u32 = 1;\npub const IEEE8021Q_PCP_BE: u32 = 0;\npub const IEEE8021Q_PCP_EE: u32 = 2;\npub const IEEE8021Q_PCP_CA: u32 = 3;\npub const IEEE8021Q_PCP_VI: u32 = 4;\npub const IEEE8021Q_PCP_VO: u32 = 5;\npub const IEEE8021Q_PCP_IC: u32 = 6;\npub const IEEE8021Q_PCP_NC: u32 = 7;\npub const RNF_NORMAL: u32 = 1;\npub const RNF_ROOT: u32 = 2;\npub const RNF_ACTIVE: u32 = 4;\npub const IPPROTO_IP: u32 = 0;\npub const IPPROTO_ICMP: u32 = 1;\npub const IPPROTO_TCP: u32 = 6;\npub const IPPROTO_UDP: u32 = 17;\npub const IPPROTO_IPV6: u32 = 41;\npub const IPPROTO_RAW: u32 = 255;\npub const INET_ADDRSTRLEN: u32 = 16;\npub const IPPROTO_HOPOPTS: u32 = 0;\npub const IPPROTO_IGMP: u32 = 2;\npub const IPPROTO_GGP: u32 = 3;\npub const IPPROTO_IPV4: u32 = 4;\npub const IPPROTO_IPIP: u32 = 4;\npub const IPPROTO_ST: u32 = 7;\npub const IPPROTO_EGP: u32 = 8;\npub const IPPROTO_PIGP: u32 = 9;\npub const IPPROTO_RCCMON: u32 = 10;\npub const IPPROTO_NVPII: u32 = 11;\npub const IPPROTO_PUP: u32 = 12;\npub const IPPROTO_ARGUS: u32 = 13;\npub const IPPROTO_EMCON: u32 = 14;\npub const IPPROTO_XNET: u32 = 15;\npub const IPPROTO_CHAOS: u32 = 16;\npub const IPPROTO_MUX: u32 = 18;\npub const IPPROTO_MEAS: u32 = 19;\npub const IPPROTO_HMP: u32 = 20;\npub const IPPROTO_PRM: u32 = 21;\npub const IPPROTO_IDP: u32 = 22;\npub const IPPROTO_TRUNK1: u32 = 23;\npub const IPPROTO_TRUNK2: u32 = 24;\npub const IPPROTO_LEAF1: u32 = 25;\npub const IPPROTO_LEAF2: u32 = 26;\npub const IPPROTO_RDP: u32 = 27;\npub const IPPROTO_IRTP: u32 = 28;\npub const IPPROTO_TP: u32 = 29;\npub const IPPROTO_BLT: u32 = 30;\npub const IPPROTO_NSP: u32 = 31;\npub const IPPROTO_INP: u32 = 32;\npub const IPPROTO_DCCP: u32 = 33;\npub const IPPROTO_3PC: u32 = 34;\npub const IPPROTO_IDPR: u32 = 35;\npub const IPPROTO_XTP: u32 = 36;\npub const IPPROTO_DDP: u32 = 37;\npub const IPPROTO_CMTP: u32 = 38;\npub const IPPROTO_TPXX: u32 = 39;\npub const IPPROTO_IL: u32 = 40;\npub const IPPROTO_SDRP: u32 = 42;\npub const IPPROTO_ROUTING: u32 = 43;\npub const IPPROTO_FRAGMENT: u32 = 44;\npub const IPPROTO_IDRP: u32 = 45;\npub const IPPROTO_RSVP: u32 = 46;\npub const IPPROTO_GRE: u32 = 47;\npub const IPPROTO_MHRP: u32 = 48;\npub const IPPROTO_BHA: u32 = 49;\npub const IPPROTO_ESP: u32 = 50;\npub const IPPROTO_AH: u32 = 51;\npub const IPPROTO_INLSP: u32 = 52;\npub const IPPROTO_SWIPE: u32 = 53;\npub const IPPROTO_NHRP: u32 = 54;\npub const IPPROTO_MOBILE: u32 = 55;\npub const IPPROTO_TLSP: u32 = 56;\npub const IPPROTO_SKIP: u32 = 57;\npub const IPPROTO_ICMPV6: u32 = 58;\npub const IPPROTO_NONE: u32 = 59;\npub const IPPROTO_DSTOPTS: u32 = 60;\npub const IPPROTO_AHIP: u32 = 61;\npub const IPPROTO_CFTP: u32 = 62;\npub const IPPROTO_HELLO: u32 = 63;\npub const IPPROTO_SATEXPAK: u32 = 64;\npub const IPPROTO_KRYPTOLAN: u32 = 65;\npub const IPPROTO_RVD: u32 = 66;\npub const IPPROTO_IPPC: u32 = 67;\npub const IPPROTO_ADFS: u32 = 68;\npub const IPPROTO_SATMON: u32 = 69;\npub const IPPROTO_VISA: u32 = 70;\npub const IPPROTO_IPCV: u32 = 71;\npub const IPPROTO_CPNX: u32 = 72;\npub const IPPROTO_CPHB: u32 = 73;\npub const IPPROTO_WSN: u32 = 74;\npub const IPPROTO_PVP: u32 = 75;\npub const IPPROTO_BRSATMON: u32 = 76;\npub const IPPROTO_ND: u32 = 77;\npub const IPPROTO_WBMON: u32 = 78;\npub const IPPROTO_WBEXPAK: u32 = 79;\npub const IPPROTO_EON: u32 = 80;\npub const IPPROTO_VMTP: u32 = 81;\npub const IPPROTO_SVMTP: u32 = 82;\npub const IPPROTO_VINES: u32 = 83;\npub const IPPROTO_TTP: u32 = 84;\npub const IPPROTO_IGP: u32 = 85;\npub const IPPROTO_DGP: u32 = 86;\npub const IPPROTO_TCF: u32 = 87;\npub const IPPROTO_IGRP: u32 = 88;\npub const IPPROTO_OSPFIGP: u32 = 89;\npub const IPPROTO_SRPC: u32 = 90;\npub const IPPROTO_LARP: u32 = 91;\npub const IPPROTO_MTP: u32 = 92;\npub const IPPROTO_AX25: u32 = 93;\npub const IPPROTO_IPEIP: u32 = 94;\npub const IPPROTO_MICP: u32 = 95;\npub const IPPROTO_SCCSP: u32 = 96;\npub const IPPROTO_ETHERIP: u32 = 97;\npub const IPPROTO_ENCAP: u32 = 98;\npub const IPPROTO_APES: u32 = 99;\npub const IPPROTO_GMTP: u32 = 100;\npub const IPPROTO_IPCOMP: u32 = 108;\npub const IPPROTO_SCTP: u32 = 132;\npub const IPPROTO_MH: u32 = 135;\npub const IPPROTO_UDPLITE: u32 = 136;\npub const IPPROTO_HIP: u32 = 139;\npub const IPPROTO_SHIM6: u32 = 140;\npub const IPPROTO_PIM: u32 = 103;\npub const IPPROTO_CARP: u32 = 112;\npub const IPPROTO_PGM: u32 = 113;\npub const IPPROTO_MPLS: u32 = 137;\npub const IPPROTO_PFSYNC: u32 = 240;\npub const IPPROTO_RESERVED_253: u32 = 253;\npub const IPPROTO_RESERVED_254: u32 = 254;\npub const IPPROTO_OLD_DIVERT: u32 = 254;\npub const IPPROTO_MAX: u32 = 256;\npub const IPPROTO_DONE: u32 = 257;\npub const IPPROTO_DIVERT: u32 = 258;\npub const IPPROTO_SEND: u32 = 259;\npub const IPPROTO_SPACER: u32 = 32767;\npub const IPPORT_RESERVED: u32 = 1024;\npub const IPPORT_EPHEMERALFIRST: u32 = 10000;\npub const IPPORT_EPHEMERALLAST: u32 = 65535;\npub const IPPORT_HIFIRSTAUTO: u32 = 49152;\npub const IPPORT_HILASTAUTO: u32 = 65535;\npub const IPPORT_RESERVEDSTART: u32 = 600;\npub const IPPORT_MAX: u32 = 65535;\npub const IN_CLASSA_NET: u32 = 4278190080;\npub const IN_CLASSA_NSHIFT: u32 = 24;\npub const IN_CLASSA_HOST: u32 = 16777215;\npub const IN_CLASSA_MAX: u32 = 128;\npub const IN_CLASSB_NET: u32 = 4294901760;\npub const IN_CLASSB_NSHIFT: u32 = 16;\npub const IN_CLASSB_HOST: u32 = 65535;\npub const IN_CLASSB_MAX: u32 = 65536;\npub const IN_CLASSC_NET: u32 = 4294967040;\npub const IN_CLASSC_NSHIFT: u32 = 8;\npub const IN_CLASSC_HOST: u32 = 255;\npub const IN_NETMASK_DEFAULT: u32 = 4294967040;\npub const IN_CLASSD_NET: u32 = 4026531840;\npub const IN_CLASSD_NSHIFT: u32 = 28;\npub const IN_CLASSD_HOST: u32 = 268435455;\npub const IN_LOOPBACKNET: u32 = 127;\npub const IP_OPTIONS: u32 = 1;\npub const IP_HDRINCL: u32 = 2;\npub const IP_TOS: u32 = 3;\npub const IP_TTL: u32 = 4;\npub const IP_RECVOPTS: u32 = 5;\npub const IP_RECVRETOPTS: u32 = 6;\npub const IP_RECVDSTADDR: u32 = 7;\npub const IP_SENDSRCADDR: u32 = 7;\npub const IP_RETOPTS: u32 = 8;\npub const IP_MULTICAST_IF: u32 = 9;\npub const IP_MULTICAST_TTL: u32 = 10;\npub const IP_MULTICAST_LOOP: u32 = 11;\npub const IP_ADD_MEMBERSHIP: u32 = 12;\npub const IP_DROP_MEMBERSHIP: u32 = 13;\npub const IP_MULTICAST_VIF: u32 = 14;\npub const IP_RSVP_ON: u32 = 15;\npub const IP_RSVP_OFF: u32 = 16;\npub const IP_RSVP_VIF_ON: u32 = 17;\npub const IP_RSVP_VIF_OFF: u32 = 18;\npub const IP_PORTRANGE: u32 = 19;\npub const IP_RECVIF: u32 = 20;\npub const IP_IPSEC_POLICY: u32 = 21;\npub const IP_ONESBCAST: u32 = 23;\npub const IP_BINDANY: u32 = 24;\npub const IP_ORIGDSTADDR: u32 = 27;\npub const IP_RECVORIGDSTADDR: u32 = 27;\npub const IP_FW_TABLE_ADD: u32 = 40;\npub const IP_FW_TABLE_DEL: u32 = 41;\npub const IP_FW_TABLE_FLUSH: u32 = 42;\npub const IP_FW_TABLE_GETSIZE: u32 = 43;\npub const IP_FW_TABLE_LIST: u32 = 44;\npub const IP_FW3: u32 = 48;\npub const IP_DUMMYNET3: u32 = 49;\npub const IP_FW_ADD: u32 = 50;\npub const IP_FW_DEL: u32 = 51;\npub const IP_FW_FLUSH: u32 = 52;\npub const IP_FW_ZERO: u32 = 53;\npub const IP_FW_GET: u32 = 54;\npub const IP_FW_RESETLOG: u32 = 55;\npub const IP_FW_NAT_CFG: u32 = 56;\npub const IP_FW_NAT_DEL: u32 = 57;\npub const IP_FW_NAT_GET_CONFIG: u32 = 58;\npub const IP_FW_NAT_GET_LOG: u32 = 59;\npub const IP_DUMMYNET_CONFIGURE: u32 = 60;\npub const IP_DUMMYNET_DEL: u32 = 61;\npub const IP_DUMMYNET_FLUSH: u32 = 62;\npub const IP_DUMMYNET_GET: u32 = 64;\npub const IP_RECVTTL: u32 = 65;\npub const IP_MINTTL: u32 = 66;\npub const IP_DONTFRAG: u32 = 67;\npub const IP_RECVTOS: u32 = 68;\npub const IP_ADD_SOURCE_MEMBERSHIP: u32 = 70;\npub const IP_DROP_SOURCE_MEMBERSHIP: u32 = 71;\npub const IP_BLOCK_SOURCE: u32 = 72;\npub const IP_UNBLOCK_SOURCE: u32 = 73;\npub const IP_MSFILTER: u32 = 74;\npub const IP_VLAN_PCP: u32 = 75;\npub const MCAST_JOIN_GROUP: u32 = 80;\npub const MCAST_LEAVE_GROUP: u32 = 81;\npub const MCAST_JOIN_SOURCE_GROUP: u32 = 82;\npub const MCAST_LEAVE_SOURCE_GROUP: u32 = 83;\npub const MCAST_BLOCK_SOURCE: u32 = 84;\npub const MCAST_UNBLOCK_SOURCE: u32 = 85;\npub const IP_FLOWID: u32 = 90;\npub const IP_FLOWTYPE: u32 = 91;\npub const IP_RSSBUCKETID: u32 = 92;\npub const IP_RECVFLOWID: u32 = 93;\npub const IP_RECVRSSBUCKETID: u32 = 94;\npub const IP_DEFAULT_MULTICAST_TTL: u32 = 1;\npub const IP_DEFAULT_MULTICAST_LOOP: u32 = 1;\npub const IP_MAX_MEMBERSHIPS: u32 = 4095;\npub const IP_MAX_GROUP_SRC_FILTER: u32 = 512;\npub const IP_MAX_SOCK_SRC_FILTER: u32 = 128;\npub const IP_MAX_SOCK_MUTE_FILTER: u32 = 128;\npub const MCAST_UNDEFINED: u32 = 0;\npub const MCAST_INCLUDE: u32 = 1;\npub const MCAST_EXCLUDE: u32 = 2;\npub const IP_PORTRANGE_DEFAULT: u32 = 0;\npub const IP_PORTRANGE_HIGH: u32 = 1;\npub const IP_PORTRANGE_LOW: u32 = 2;\npub const IPCTL_FORWARDING: u32 = 1;\npub const IPCTL_SENDREDIRECTS: u32 = 2;\npub const IPCTL_DEFTTL: u32 = 3;\npub const IPCTL_SOURCEROUTE: u32 = 8;\npub const IPCTL_DIRECTEDBROADCAST: u32 = 9;\npub const IPCTL_INTRQMAXLEN: u32 = 10;\npub const IPCTL_INTRQDROPS: u32 = 11;\npub const IPCTL_STATS: u32 = 12;\npub const IPCTL_ACCEPTSOURCEROUTE: u32 = 13;\npub const IPCTL_FASTFORWARDING: u32 = 14;\npub const IPCTL_GIF_TTL: u32 = 16;\npub const IPCTL_INTRDQMAXLEN: u32 = 17;\npub const IPCTL_INTRDQDROPS: u32 = 18;\npub const __KAME_VERSION: &[u8; 8] = b\"FreeBSD\\0\";\npub const IPV6PORT_RESERVED: u32 = 1024;\npub const IPV6PORT_ANONMIN: u32 = 49152;\npub const IPV6PORT_ANONMAX: u32 = 65535;\npub const IPV6PORT_RESERVEDMIN: u32 = 600;\npub const IPV6PORT_RESERVEDMAX: u32 = 1023;\npub const INET6_ADDRSTRLEN: u32 = 46;\npub const __IPV6_ADDR_SCOPE_NODELOCAL: u32 = 1;\npub const __IPV6_ADDR_SCOPE_INTFACELOCAL: u32 = 1;\npub const __IPV6_ADDR_SCOPE_LINKLOCAL: u32 = 2;\npub const __IPV6_ADDR_SCOPE_SITELOCAL: u32 = 5;\npub const __IPV6_ADDR_SCOPE_ORGLOCAL: u32 = 8;\npub const __IPV6_ADDR_SCOPE_GLOBAL: u32 = 14;\npub const IPV6_SOCKOPT_RESERVED1: u32 = 3;\npub const IPV6_UNICAST_HOPS: u32 = 4;\npub const IPV6_MULTICAST_IF: u32 = 9;\npub const IPV6_MULTICAST_HOPS: u32 = 10;\npub const IPV6_MULTICAST_LOOP: u32 = 11;\npub const IPV6_JOIN_GROUP: u32 = 12;\npub const IPV6_LEAVE_GROUP: u32 = 13;\npub const IPV6_PORTRANGE: u32 = 14;\npub const ICMP6_FILTER: u32 = 18;\npub const IPV6_CHECKSUM: u32 = 26;\npub const IPV6_V6ONLY: u32 = 27;\npub const IPV6_BINDV6ONLY: u32 = 27;\npub const IPV6_IPSEC_POLICY: u32 = 28;\npub const IPV6_FW_ADD: u32 = 30;\npub const IPV6_FW_DEL: u32 = 31;\npub const IPV6_FW_FLUSH: u32 = 32;\npub const IPV6_FW_ZERO: u32 = 33;\npub const IPV6_FW_GET: u32 = 34;\npub const IPV6_RTHDRDSTOPTS: u32 = 35;\npub const IPV6_RECVPKTINFO: u32 = 36;\npub const IPV6_RECVHOPLIMIT: u32 = 37;\npub const IPV6_RECVRTHDR: u32 = 38;\npub const IPV6_RECVHOPOPTS: u32 = 39;\npub const IPV6_RECVDSTOPTS: u32 = 40;\npub const IPV6_USE_MIN_MTU: u32 = 42;\npub const IPV6_RECVPATHMTU: u32 = 43;\npub const IPV6_PATHMTU: u32 = 44;\npub const IPV6_PKTINFO: u32 = 46;\npub const IPV6_HOPLIMIT: u32 = 47;\npub const IPV6_NEXTHOP: u32 = 48;\npub const IPV6_HOPOPTS: u32 = 49;\npub const IPV6_DSTOPTS: u32 = 50;\npub const IPV6_RTHDR: u32 = 51;\npub const IPV6_RECVTCLASS: u32 = 57;\npub const IPV6_AUTOFLOWLABEL: u32 = 59;\npub const IPV6_TCLASS: u32 = 61;\npub const IPV6_DONTFRAG: u32 = 62;\npub const IPV6_PREFER_TEMPADDR: u32 = 63;\npub const IPV6_BINDANY: u32 = 64;\npub const IPV6_FLOWID: u32 = 67;\npub const IPV6_FLOWTYPE: u32 = 68;\npub const IPV6_RSSBUCKETID: u32 = 69;\npub const IPV6_RECVFLOWID: u32 = 70;\npub const IPV6_RECVRSSBUCKETID: u32 = 71;\npub const IPV6_ORIGDSTADDR: u32 = 72;\npub const IPV6_RECVORIGDSTADDR: u32 = 72;\npub const IPV6_MSFILTER: u32 = 74;\npub const IPV6_VLAN_PCP: u32 = 75;\npub const IPV6_RTHDR_LOOSE: u32 = 0;\npub const IPV6_RTHDR_STRICT: u32 = 1;\npub const IPV6_RTHDR_TYPE_0: u32 = 0;\npub const IPV6_DEFAULT_MULTICAST_HOPS: u32 = 1;\npub const IPV6_DEFAULT_MULTICAST_LOOP: u32 = 1;\npub const IPV6_MAX_MEMBERSHIPS: u32 = 4095;\npub const IPV6_MAX_GROUP_SRC_FILTER: u32 = 512;\npub const IPV6_MAX_SOCK_SRC_FILTER: u32 = 128;\npub const IPV6_PORTRANGE_DEFAULT: u32 = 0;\npub const IPV6_PORTRANGE_HIGH: u32 = 1;\npub const IPV6_PORTRANGE_LOW: u32 = 2;\npub const IPV6PROTO_MAXID: u32 = 104;\npub const IPV6CTL_FORWARDING: u32 = 1;\npub const IPV6CTL_SENDREDIRECTS: u32 = 2;\npub const IPV6CTL_DEFHLIM: u32 = 3;\npub const IPV6CTL_FORWSRCRT: u32 = 5;\npub const IPV6CTL_STATS: u32 = 6;\npub const IPV6CTL_MRTSTATS: u32 = 7;\npub const IPV6CTL_MRTPROTO: u32 = 8;\npub const IPV6CTL_MAXFRAGPACKETS: u32 = 9;\npub const IPV6CTL_SOURCECHECK: u32 = 10;\npub const IPV6CTL_SOURCECHECK_LOGINT: u32 = 11;\npub const IPV6CTL_ACCEPT_RTADV: u32 = 12;\npub const IPV6CTL_LOG_INTERVAL: u32 = 14;\npub const IPV6CTL_HDRNESTLIMIT: u32 = 15;\npub const IPV6CTL_DAD_COUNT: u32 = 16;\npub const IPV6CTL_AUTO_FLOWLABEL: u32 = 17;\npub const IPV6CTL_DEFMCASTHLIM: u32 = 18;\npub const IPV6CTL_GIF_HLIM: u32 = 19;\npub const IPV6CTL_KAME_VERSION: u32 = 20;\npub const IPV6CTL_USE_DEPRECATED: u32 = 21;\npub const IPV6CTL_RR_PRUNE: u32 = 22;\npub const IPV6CTL_V6ONLY: u32 = 24;\npub const IPV6CTL_USETEMPADDR: u32 = 32;\npub const IPV6CTL_TEMPPLTIME: u32 = 33;\npub const IPV6CTL_TEMPVLTIME: u32 = 34;\npub const IPV6CTL_AUTO_LINKLOCAL: u32 = 35;\npub const IPV6CTL_RIP6STATS: u32 = 36;\npub const IPV6CTL_PREFER_TEMPADDR: u32 = 37;\npub const IPV6CTL_ADDRCTLPOLICY: u32 = 38;\npub const IPV6CTL_USE_DEFAULTZONE: u32 = 39;\npub const IPV6CTL_MAXFRAGS: u32 = 41;\npub const IPV6CTL_MCAST_PMTU: u32 = 44;\npub const IPV6CTL_STEALTH: u32 = 45;\npub const ICMPV6CTL_ND6_ONLINKNSRFC4861: u32 = 47;\npub const IPV6CTL_NO_RADR: u32 = 48;\npub const IPV6CTL_NORBIT_RAIF: u32 = 49;\npub const IPV6CTL_RFC6204W3: u32 = 50;\npub const IPV6CTL_INTRQMAXLEN: u32 = 51;\npub const IPV6CTL_INTRDQMAXLEN: u32 = 52;\npub const IPV6CTL_MAXFRAGSPERPACKET: u32 = 53;\npub const IPV6CTL_MAXFRAGBUCKETSIZE: u32 = 54;\npub const IPV6CTL_MAXID: u32 = 55;\npub const PF_MD5_DIGEST_LENGTH: u32 = 16;\npub const PFTM_TCP_FIRST_PACKET_VAL: u32 = 120;\npub const PFTM_TCP_OPENING_VAL: u32 = 30;\npub const PFTM_TCP_ESTABLISHED_VAL: u32 = 86400;\npub const PFTM_TCP_CLOSING_VAL: u32 = 900;\npub const PFTM_TCP_FIN_WAIT_VAL: u32 = 45;\npub const PFTM_TCP_CLOSED_VAL: u32 = 90;\npub const PFTM_UDP_FIRST_PACKET_VAL: u32 = 60;\npub const PFTM_UDP_SINGLE_VAL: u32 = 30;\npub const PFTM_UDP_MULTIPLE_VAL: u32 = 60;\npub const PFTM_ICMP_FIRST_PACKET_VAL: u32 = 20;\npub const PFTM_ICMP_ERROR_REPLY_VAL: u32 = 10;\npub const PFTM_OTHER_FIRST_PACKET_VAL: u32 = 60;\npub const PFTM_OTHER_SINGLE_VAL: u32 = 30;\npub const PFTM_OTHER_MULTIPLE_VAL: u32 = 60;\npub const PFTM_FRAG_VAL: u32 = 30;\npub const PFTM_INTERVAL_VAL: u32 = 10;\npub const PFTM_SRC_NODE_VAL: u32 = 0;\npub const PFTM_TS_DIFF_VAL: u32 = 30;\npub const PF_POOL_IDMASK: u32 = 15;\npub const PF_POOL_TYPEMASK: u32 = 15;\npub const PF_POOL_STICKYADDR: u32 = 32;\npub const PF_WSCALE_FLAG: u32 = 128;\npub const PF_WSCALE_MASK: u32 = 15;\npub const PF_LOG: u32 = 1;\npub const PF_LOG_ALL: u32 = 2;\npub const PF_LOG_SOCKET_LOOKUP: u32 = 4;\npub const PF_LOG_FORCE: u32 = 8;\npub const PFRES_MATCH: u32 = 0;\npub const PFRES_BADOFF: u32 = 1;\npub const PFRES_FRAG: u32 = 2;\npub const PFRES_SHORT: u32 = 3;\npub const PFRES_NORM: u32 = 4;\npub const PFRES_MEMORY: u32 = 5;\npub const PFRES_TS: u32 = 6;\npub const PFRES_CONGEST: u32 = 7;\npub const PFRES_IPOPTIONS: u32 = 8;\npub const PFRES_PROTCKSUM: u32 = 9;\npub const PFRES_BADSTATE: u32 = 10;\npub const PFRES_STATEINS: u32 = 11;\npub const PFRES_MAXSTATES: u32 = 12;\npub const PFRES_SRCLIMIT: u32 = 13;\npub const PFRES_SYNPROXY: u32 = 14;\npub const PFRES_MAPFAILED: u32 = 15;\npub const PFRES_MAX: u32 = 16;\npub const LCNT_STATES: u32 = 0;\npub const LCNT_SRCSTATES: u32 = 1;\npub const LCNT_SRCNODES: u32 = 2;\npub const LCNT_SRCCONN: u32 = 3;\npub const LCNT_SRCCONNRATE: u32 = 4;\npub const LCNT_OVERLOAD_TABLE: u32 = 5;\npub const LCNT_OVERLOAD_FLUSH: u32 = 6;\npub const LCNT_MAX: u32 = 7;\npub const KLCNT_SYNFLOODS: u32 = 7;\npub const KLCNT_SYNCOOKIES_SENT: u32 = 8;\npub const KLCNT_SYNCOOKIES_VALID: u32 = 9;\npub const KLCNT_MAX: u32 = 10;\npub const FCNT_STATE_SEARCH: u32 = 0;\npub const FCNT_STATE_INSERT: u32 = 1;\npub const FCNT_STATE_REMOVALS: u32 = 2;\npub const FCNT_MAX: u32 = 3;\npub const SCNT_SRC_NODE_SEARCH: u32 = 0;\npub const SCNT_SRC_NODE_INSERT: u32 = 1;\npub const SCNT_SRC_NODE_REMOVALS: u32 = 2;\npub const SCNT_MAX: u32 = 3;\npub const PF_TABLE_NAME_SIZE: u32 = 32;\npub const PF_QNAME_SIZE: u32 = 64;\npub const PF_REASS_ENABLED: u32 = 1;\npub const PF_REASS_NODF: u32 = 2;\npub const PFI_AFLAG_NETWORK: u32 = 1;\npub const PFI_AFLAG_BROADCAST: u32 = 2;\npub const PFI_AFLAG_PEER: u32 = 4;\npub const PFI_AFLAG_MODEMASK: u32 = 7;\npub const PFI_AFLAG_NOALIAS: u32 = 8;\npub const PF_OSFP_EXPANDED: u32 = 1;\npub const PF_OSFP_GENERIC: u32 = 2;\npub const PF_OSFP_NODETAIL: u32 = 4;\npub const PF_OSFP_LEN: u32 = 32;\npub const _FP_RESERVED_BIT: u32 = 1;\npub const _FP_UNUSED_BITS: u32 = 1;\npub const _FP_CLASS_BITS: u32 = 10;\npub const _FP_VERSION_BITS: u32 = 10;\npub const _FP_SUBTYPE_BITS: u32 = 10;\npub const PF_OSFP_WSIZE_MOD: u32 = 1;\npub const PF_OSFP_WSIZE_DC: u32 = 2;\npub const PF_OSFP_WSIZE_MSS: u32 = 4;\npub const PF_OSFP_WSIZE_MTU: u32 = 8;\npub const PF_OSFP_PSIZE_MOD: u32 = 16;\npub const PF_OSFP_PSIZE_DC: u32 = 32;\npub const PF_OSFP_WSCALE: u32 = 64;\npub const PF_OSFP_WSCALE_MOD: u32 = 128;\npub const PF_OSFP_WSCALE_DC: u32 = 256;\npub const PF_OSFP_MSS: u32 = 512;\npub const PF_OSFP_MSS_MOD: u32 = 1024;\npub const PF_OSFP_MSS_DC: u32 = 2048;\npub const PF_OSFP_DF: u32 = 4096;\npub const PF_OSFP_TS0: u32 = 8192;\npub const PF_OSFP_INET6: u32 = 16384;\npub const PF_OSFP_MAXTTL_OFFSET: u32 = 40;\npub const PF_OSFP_TCPOPT_NOP: u32 = 0;\npub const PF_OSFP_TCPOPT_WSCALE: u32 = 1;\npub const PF_OSFP_TCPOPT_MSS: u32 = 2;\npub const PF_OSFP_TCPOPT_SACK: u32 = 3;\npub const PF_OSFP_TCPOPT_TS: u32 = 4;\npub const PF_OSFP_TCPOPT_BITS: u32 = 3;\npub const PF_ANCHOR_NAME_SIZE: u32 = 64;\npub const PF_SKIP_IFP: u32 = 0;\npub const PF_SKIP_DIR: u32 = 1;\npub const PF_SKIP_AF: u32 = 2;\npub const PF_SKIP_PROTO: u32 = 3;\npub const PF_SKIP_SRC_ADDR: u32 = 4;\npub const PF_SKIP_SRC_PORT: u32 = 5;\npub const PF_SKIP_DST_ADDR: u32 = 6;\npub const PF_SKIP_DST_PORT: u32 = 7;\npub const PF_SKIP_COUNT: u32 = 8;\npub const PF_RULE_LABEL_SIZE: u32 = 64;\npub const PF_RULE_MAX_LABEL_COUNT: u32 = 5;\npub const PF_TAG_NAME_SIZE: u32 = 64;\npub const PF_STATE_NORMAL: u32 = 1;\npub const PF_STATE_MODULATE: u32 = 2;\npub const PF_STATE_SYNPROXY: u32 = 3;\npub const PF_FLUSH: u32 = 1;\npub const PF_FLUSH_GLOBAL: u32 = 2;\npub const PF_PRIO_ZERO: u32 = 255;\npub const PF_PRIO_MAX: u32 = 7;\npub const PFRULE_DROP: u32 = 0;\npub const PFRULE_RETURNRST: u32 = 1;\npub const PFRULE_FRAGMENT: u32 = 2;\npub const PFRULE_RETURNICMP: u32 = 4;\npub const PFRULE_RETURN: u32 = 8;\npub const PFRULE_NOSYNC: u32 = 16;\npub const PFRULE_SRCTRACK: u32 = 32;\npub const PFRULE_RULESRCTRACK: u32 = 64;\npub const PFRULE_NODF: u32 = 256;\npub const PFRULE_FRAGMENT_NOREASS: u32 = 512;\npub const PFRULE_RANDOMID: u32 = 2048;\npub const PFRULE_REASSEMBLE_TCP: u32 = 4096;\npub const PFRULE_SET_TOS: u32 = 8192;\npub const PFRULE_IFBOUND: u32 = 65536;\npub const PFRULE_STATESLOPPY: u32 = 131072;\npub const PFRULE_DN_IS_PIPE: u32 = 64;\npub const PFRULE_DN_IS_QUEUE: u32 = 128;\npub const PFSTATE_ALLOWOPTS: u32 = 1;\npub const PFSTATE_SLOPPY: u32 = 2;\npub const PFSTATE_NOSYNC: u32 = 8;\npub const PFSTATE_ACK: u32 = 16;\npub const PFSTATE_NODF: u32 = 32;\npub const PFSTATE_SETTOS: u32 = 64;\npub const PFSTATE_RANDOMID: u32 = 128;\npub const PFSTATE_SCRUB_TCP: u32 = 256;\npub const PFSTATE_SETPRIO: u32 = 512;\npub const PFSTATE_DN_IS_PIPE: u32 = 16384;\npub const PFSTATE_DN_IS_QUEUE: u32 = 32768;\npub const PFSTATE_SCRUBMASK: u32 = 416;\npub const PFSTATE_SETMASK: u32 = 576;\npub const PFSTATE_HIWAT: u32 = 100000;\npub const PFSTATE_ADAPT_START: u32 = 60000;\npub const PFSTATE_ADAPT_END: u32 = 120000;\npub const PF_THRESHOLD_MULT: u32 = 1000;\npub const PF_THRESHOLD_MAX: u32 = 4294967;\npub const PFSNODE_HIWAT: u32 = 10000;\npub const PFALTQ_FLAG_IF_REMOVED: u32 = 1;\npub const PF_ALTQ_VERSION: u32 = 1;\npub const PFSS_TIMESTAMP: u32 = 1;\npub const PFSS_PAWS: u32 = 16;\npub const PFSS_PAWS_IDLED: u32 = 32;\npub const PFSS_DATA_TS: u32 = 64;\npub const PFSS_DATA_NOTS: u32 = 128;\npub const PF_SCRUB_FLAG_VALID: u32 = 1;\npub const PF_STATE_VERSION: u32 = 20230404;\npub const PFSYNC_SCRUB_FLAG_VALID: u32 = 1;\npub const PFSYNC_FLAG_SRCNODE: u32 = 4;\npub const PFSYNC_FLAG_NATSRCNODE: u32 = 8;\npub const PF_RESERVED_ANCHOR: &[u8; 4] = b\"_pf\\0\";\npub const PFR_TFLAG_PERSIST: u32 = 1;\npub const PFR_TFLAG_CONST: u32 = 2;\npub const PFR_TFLAG_ACTIVE: u32 = 4;\npub const PFR_TFLAG_INACTIVE: u32 = 8;\npub const PFR_TFLAG_REFERENCED: u32 = 16;\npub const PFR_TFLAG_REFDANCHOR: u32 = 32;\npub const PFR_TFLAG_COUNTERS: u32 = 64;\npub const PFR_TFLAG_USRMASK: u32 = 67;\npub const PFR_TFLAG_SETMASK: u32 = 60;\npub const PFR_TFLAG_ALLMASK: u32 = 127;\npub const PFI_IFLAG_REFS: u32 = 1;\npub const PFI_IFLAG_SKIP: u32 = 256;\npub const PF_DPORT_RANGE: u32 = 1;\npub const PF_RPORT_RANGE: u32 = 2;\npub const PFUDPS_NO_TRAFFIC: u32 = 0;\npub const PFUDPS_SINGLE: u32 = 1;\npub const PFUDPS_MULTIPLE: u32 = 2;\npub const PFUDPS_NSTATES: u32 = 3;\npub const PFOTHERS_NO_TRAFFIC: u32 = 0;\npub const PFOTHERS_SINGLE: u32 = 1;\npub const PFOTHERS_MULTIPLE: u32 = 2;\npub const PFOTHERS_NSTATES: u32 = 3;\npub const PF_SYNCOOKIES_HIWATPCT: u32 = 25;\npub const PF_SYNCOOKIES_LOWATPCT: u32 = 12;\npub const PFFRAG_FRENT_HIWAT: u32 = 5000;\npub const PFR_KENTRY_HIWAT: u32 = 200000;\npub const PF_FRAG_ENTRY_POINTS: u32 = 16;\npub const PF_FRAG_ENTRY_LIMIT: u32 = 64;\npub const PFIOC_ALTQ_VERSION: u32 = 1;\npub const PFIOC_QSTATS_VERSION: u32 = 1;\npub const PFR_FLAG_ATOMIC: u32 = 1;\npub const PFR_FLAG_DUMMY: u32 = 2;\npub const PFR_FLAG_FEEDBACK: u32 = 4;\npub const PFR_FLAG_CLSTATS: u32 = 8;\npub const PFR_FLAG_ADDRSTOO: u32 = 16;\npub const PFR_FLAG_REPLACE: u32 = 32;\npub const PFR_FLAG_ALLRSETS: u32 = 64;\npub const PFR_FLAG_ALLMASK: u32 = 127;\npub const PF_IFSPEED_VERSION: u32 = 1;\npub type __int8_t = ::std::os::raw::c_schar;\npub type __uint8_t = ::std::os::raw::c_uchar;\npub type __int16_t = ::std::os::raw::c_short;\npub type __uint16_t = ::std::os::raw::c_ushort;\npub type __int32_t = ::std::os::raw::c_int;\npub type __uint32_t = ::std::os::raw::c_uint;\npub type __int64_t = ::std::os::raw::c_long;\npub type __uint64_t = ::std::os::raw::c_ulong;\npub type __int_least8_t = __int8_t;\npub type __int_least16_t = __int16_t;\npub type __int_least32_t = __int32_t;\npub type __int_least64_t = __int64_t;\npub type __intmax_t = __int64_t;\npub type __uint_least8_t = __uint8_t;\npub type __uint_least16_t = __uint16_t;\npub type __uint_least32_t = __uint32_t;\npub type __uint_least64_t = __uint64_t;\npub type __uintmax_t = __uint64_t;\npub type __intptr_t = __int64_t;\npub type __intfptr_t = __int64_t;\npub type __uintptr_t = __uint64_t;\npub type __uintfptr_t = __uint64_t;\npub type __vm_offset_t = __uint64_t;\npub type __vm_size_t = __uint64_t;\npub type __size_t = __uint64_t;\npub type __ssize_t = __int64_t;\npub type __ptrdiff_t = __int64_t;\npub type __clock_t = __int32_t;\npub type __critical_t = __int64_t;\npub type __double_t = f64;\npub type __float_t = f32;\npub type __int_fast8_t = __int32_t;\npub type __int_fast16_t = __int32_t;\npub type __int_fast32_t = __int32_t;\npub type __int_fast64_t = __int64_t;\npub type __register_t = __int64_t;\npub type __segsz_t = __int64_t;\npub type __time_t = __int64_t;\npub type __uint_fast8_t = __uint32_t;\npub type __uint_fast16_t = __uint32_t;\npub type __uint_fast32_t = __uint32_t;\npub type __uint_fast64_t = __uint64_t;\npub type __u_register_t = __uint64_t;\npub type __vm_paddr_t = __uint64_t;\npub type ___wchar_t = ::std::os::raw::c_int;\npub type __blksize_t = __int32_t;\npub type __blkcnt_t = __int64_t;\npub type __clockid_t = __int32_t;\npub type __fflags_t = __uint32_t;\npub type __fsblkcnt_t = __uint64_t;\npub type __fsfilcnt_t = __uint64_t;\npub type __gid_t = __uint32_t;\npub type __id_t = __int64_t;\npub type __ino_t = __uint64_t;\npub type __key_t = ::std::os::raw::c_long;\npub type __lwpid_t = __int32_t;\npub type __mode_t = __uint16_t;\npub type __accmode_t = ::std::os::raw::c_int;\npub type __nl_item = ::std::os::raw::c_int;\npub type __nlink_t = __uint64_t;\npub type __off_t = __int64_t;\npub type __off64_t = __int64_t;\npub type __pid_t = __int32_t;\npub type __sbintime_t = __int64_t;\npub type __rlim_t = __int64_t;\npub type __sa_family_t = __uint8_t;\npub type __socklen_t = __uint32_t;\npub type __suseconds_t = ::std::os::raw::c_long;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __timer {\n    _unused: [u8; 0],\n}\npub type __timer_t = *mut __timer;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __mq {\n    _unused: [u8; 0],\n}\npub type __mqd_t = *mut __mq;\npub type __uid_t = __uint32_t;\npub type __useconds_t = ::std::os::raw::c_uint;\npub type __cpuwhich_t = ::std::os::raw::c_int;\npub type __cpulevel_t = ::std::os::raw::c_int;\npub type __cpusetid_t = ::std::os::raw::c_int;\npub type __daddr_t = __int64_t;\npub type __ct_rune_t = ::std::os::raw::c_int;\npub type __rune_t = __ct_rune_t;\npub type __wint_t = __ct_rune_t;\npub type __char16_t = __uint_least16_t;\npub type __char32_t = __uint_least32_t;\n#[repr(C)]\n#[repr(align(16))]\n#[derive(Debug, Copy, Clone)]\npub struct __max_align_t {\n    pub __max_align1: ::std::os::raw::c_longlong,\n    pub __bindgen_padding_0: u64,\n    pub __max_align2: u128,\n}\n#[test]\nfn bindgen_test_layout___max_align_t() {\n    const UNINIT: ::std::mem::MaybeUninit<__max_align_t> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__max_align_t>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(__max_align_t))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__max_align_t>(),\n        16usize,\n        concat!(\"Alignment of \", stringify!(__max_align_t))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__max_align1) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__max_align_t),\n            \"::\",\n            stringify!(__max_align1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__max_align2) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__max_align_t),\n            \"::\",\n            stringify!(__max_align2)\n        )\n    );\n}\npub type __dev_t = __uint64_t;\npub type __fixpt_t = __uint32_t;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union __mbstate_t {\n    pub __mbstate8: [::std::os::raw::c_char; 128usize],\n    pub _mbstateL: __int64_t,\n}\n#[test]\nfn bindgen_test_layout___mbstate_t() {\n    const UNINIT: ::std::mem::MaybeUninit<__mbstate_t> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__mbstate_t>(),\n        128usize,\n        concat!(\"Size of: \", stringify!(__mbstate_t))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__mbstate_t>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__mbstate_t))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__mbstate8) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__mbstate_t),\n            \"::\",\n            stringify!(__mbstate8)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._mbstateL) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__mbstate_t),\n            \"::\",\n            stringify!(_mbstateL)\n        )\n    );\n}\npub type __rman_res_t = __uintmax_t;\npub type __va_list = __builtin_va_list;\npub type __gnuc_va_list = __va_list;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pthread {\n    _unused: [u8; 0],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pthread_attr {\n    _unused: [u8; 0],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pthread_cond {\n    _unused: [u8; 0],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pthread_cond_attr {\n    _unused: [u8; 0],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pthread_mutex {\n    _unused: [u8; 0],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pthread_mutex_attr {\n    _unused: [u8; 0],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pthread_rwlock {\n    _unused: [u8; 0],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pthread_rwlockattr {\n    _unused: [u8; 0],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pthread_barrier {\n    _unused: [u8; 0],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pthread_barrier_attr {\n    _unused: [u8; 0],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pthread_spinlock {\n    _unused: [u8; 0],\n}\npub type pthread_t = *mut pthread;\npub type pthread_attr_t = *mut pthread_attr;\npub type pthread_mutex_t = *mut pthread_mutex;\npub type pthread_mutexattr_t = *mut pthread_mutex_attr;\npub type pthread_cond_t = *mut pthread_cond;\npub type pthread_condattr_t = *mut pthread_cond_attr;\npub type pthread_key_t = ::std::os::raw::c_int;\npub type pthread_once_t = pthread_once;\npub type pthread_rwlock_t = *mut pthread_rwlock;\npub type pthread_rwlockattr_t = *mut pthread_rwlockattr;\npub type pthread_barrier_t = *mut pthread_barrier;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pthread_barrierattr {\n    _unused: [u8; 0],\n}\npub type pthread_barrierattr_t = *mut pthread_barrierattr;\npub type pthread_spinlock_t = *mut pthread_spinlock;\npub type pthread_addr_t = *mut ::std::os::raw::c_void;\npub type pthread_startroutine_t =\n    ::std::option::Option<unsafe extern \"C\" fn(arg1: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void>;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pthread_once {\n    pub state: ::std::os::raw::c_int,\n    pub mutex: pthread_mutex_t,\n}\n#[test]\nfn bindgen_test_layout_pthread_once() {\n    const UNINIT: ::std::mem::MaybeUninit<pthread_once> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pthread_once>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pthread_once))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pthread_once>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pthread_once))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).state) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pthread_once), \"::\", stringify!(state))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mutex) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pthread_once), \"::\", stringify!(mutex))\n    );\n}\npub type u_char = ::std::os::raw::c_uchar;\npub type u_short = ::std::os::raw::c_ushort;\npub type u_int = ::std::os::raw::c_uint;\npub type u_long = ::std::os::raw::c_ulong;\npub type ushort = ::std::os::raw::c_ushort;\npub type uint = ::std::os::raw::c_uint;\npub type intmax_t = __intmax_t;\npub type uintmax_t = __uintmax_t;\npub type u_int8_t = __uint8_t;\npub type u_int16_t = __uint16_t;\npub type u_int32_t = __uint32_t;\npub type u_int64_t = __uint64_t;\npub type u_quad_t = __uint64_t;\npub type quad_t = __int64_t;\npub type qaddr_t = *mut quad_t;\npub type caddr_t = *mut ::std::os::raw::c_char;\npub type c_caddr_t = *const ::std::os::raw::c_char;\npub type blksize_t = __blksize_t;\npub type cpuwhich_t = __cpuwhich_t;\npub type cpulevel_t = __cpulevel_t;\npub type cpusetid_t = __cpusetid_t;\npub type blkcnt_t = __blkcnt_t;\npub type clock_t = __clock_t;\npub type clockid_t = __clockid_t;\npub type critical_t = __critical_t;\npub type daddr_t = __daddr_t;\npub type dev_t = __dev_t;\npub type fflags_t = __fflags_t;\npub type fixpt_t = __fixpt_t;\npub type fsblkcnt_t = __fsblkcnt_t;\npub type fsfilcnt_t = __fsfilcnt_t;\npub type gid_t = __gid_t;\npub type in_addr_t = __uint32_t;\npub type in_port_t = __uint16_t;\npub type id_t = __id_t;\npub type ino_t = __ino_t;\npub type key_t = __key_t;\npub type lwpid_t = __lwpid_t;\npub type mode_t = __mode_t;\npub type accmode_t = __accmode_t;\npub type nlink_t = __nlink_t;\npub type off_t = __off_t;\npub type off64_t = __off64_t;\npub type pid_t = __pid_t;\npub type register_t = __register_t;\npub type rlim_t = __rlim_t;\npub type sbintime_t = __sbintime_t;\npub type segsz_t = __segsz_t;\npub type suseconds_t = __suseconds_t;\npub type time_t = __time_t;\npub type timer_t = __timer_t;\npub type mqd_t = __mqd_t;\npub type u_register_t = __u_register_t;\npub type uid_t = __uid_t;\npub type useconds_t = __useconds_t;\npub type cap_ioctl_t = ::std::os::raw::c_ulong;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct cap_rights {\n    _unused: [u8; 0],\n}\npub type cap_rights_t = cap_rights;\npub type kpaddr_t = __uint64_t;\npub type kvaddr_t = __uint64_t;\npub type ksize_t = __uint64_t;\npub type kssize_t = __int64_t;\npub type vm_offset_t = __vm_offset_t;\npub type vm_ooffset_t = __uint64_t;\npub type vm_paddr_t = __vm_paddr_t;\npub type vm_pindex_t = __uint64_t;\npub type vm_size_t = __vm_size_t;\npub type rman_res_t = __rman_res_t;\npub type syscallarg_t = __register_t;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __sigset {\n    pub __bits: [__uint32_t; 4usize],\n}\n#[test]\nfn bindgen_test_layout___sigset() {\n    const UNINIT: ::std::mem::MaybeUninit<__sigset> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__sigset>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(__sigset))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__sigset>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(__sigset))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__bits) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(__sigset), \"::\", stringify!(__bits))\n    );\n}\npub type __sigset_t = __sigset;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct timeval {\n    pub tv_sec: time_t,\n    pub tv_usec: suseconds_t,\n}\n#[test]\nfn bindgen_test_layout_timeval() {\n    const UNINIT: ::std::mem::MaybeUninit<timeval> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<timeval>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(timeval))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<timeval>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(timeval))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tv_sec) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(timeval), \"::\", stringify!(tv_sec))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tv_usec) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(timeval), \"::\", stringify!(tv_usec))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct timespec {\n    pub tv_sec: time_t,\n    pub tv_nsec: ::std::os::raw::c_long,\n}\n#[test]\nfn bindgen_test_layout_timespec() {\n    const UNINIT: ::std::mem::MaybeUninit<timespec> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<timespec>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(timespec))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<timespec>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(timespec))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tv_sec) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(timespec), \"::\", stringify!(tv_sec))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tv_nsec) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(timespec), \"::\", stringify!(tv_nsec))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct itimerspec {\n    pub it_interval: timespec,\n    pub it_value: timespec,\n}\n#[test]\nfn bindgen_test_layout_itimerspec() {\n    const UNINIT: ::std::mem::MaybeUninit<itimerspec> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<itimerspec>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(itimerspec))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<itimerspec>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(itimerspec))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).it_interval) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(itimerspec),\n            \"::\",\n            stringify!(it_interval)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).it_value) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(itimerspec), \"::\", stringify!(it_value))\n    );\n}\npub type __fd_mask = ::std::os::raw::c_ulong;\npub type fd_mask = __fd_mask;\npub type sigset_t = __sigset_t;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct fd_set {\n    pub __fds_bits: [__fd_mask; 16usize],\n}\n#[test]\nfn bindgen_test_layout_fd_set() {\n    const UNINIT: ::std::mem::MaybeUninit<fd_set> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<fd_set>(),\n        128usize,\n        concat!(\"Size of: \", stringify!(fd_set))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<fd_set>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(fd_set))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fds_bits) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(fd_set), \"::\", stringify!(__fds_bits))\n    );\n}\nunsafe extern \"C\" {\n    pub fn pselect(\n        arg1: ::std::os::raw::c_int,\n        arg2: *mut fd_set,\n        arg3: *mut fd_set,\n        arg4: *mut fd_set,\n        arg5: *const timespec,\n        arg6: *const sigset_t,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn select(\n        arg1: ::std::os::raw::c_int,\n        arg2: *mut fd_set,\n        arg3: *mut fd_set,\n        arg4: *mut fd_set,\n        arg5: *mut timeval,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn ftruncate(arg1: ::std::os::raw::c_int, arg2: off_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn lseek(arg1: ::std::os::raw::c_int, arg2: off_t, arg3: ::std::os::raw::c_int) -> off_t;\n}\nunsafe extern \"C\" {\n    pub fn mmap(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: usize,\n        arg3: ::std::os::raw::c_int,\n        arg4: ::std::os::raw::c_int,\n        arg5: ::std::os::raw::c_int,\n        arg6: off_t,\n    ) -> *mut ::std::os::raw::c_void;\n}\nunsafe extern \"C\" {\n    pub fn truncate(arg1: *const ::std::os::raw::c_char, arg2: off_t) -> ::std::os::raw::c_int;\n}\npub type sig_atomic_t = ::std::os::raw::c_long;\n#[repr(C)]\n#[repr(align(16))]\n#[derive(Debug, Copy, Clone)]\npub struct sigcontext {\n    pub sc_mask: __sigset,\n    pub sc_onstack: ::std::os::raw::c_long,\n    pub sc_rdi: ::std::os::raw::c_long,\n    pub sc_rsi: ::std::os::raw::c_long,\n    pub sc_rdx: ::std::os::raw::c_long,\n    pub sc_rcx: ::std::os::raw::c_long,\n    pub sc_r8: ::std::os::raw::c_long,\n    pub sc_r9: ::std::os::raw::c_long,\n    pub sc_rax: ::std::os::raw::c_long,\n    pub sc_rbx: ::std::os::raw::c_long,\n    pub sc_rbp: ::std::os::raw::c_long,\n    pub sc_r10: ::std::os::raw::c_long,\n    pub sc_r11: ::std::os::raw::c_long,\n    pub sc_r12: ::std::os::raw::c_long,\n    pub sc_r13: ::std::os::raw::c_long,\n    pub sc_r14: ::std::os::raw::c_long,\n    pub sc_r15: ::std::os::raw::c_long,\n    pub sc_trapno: ::std::os::raw::c_int,\n    pub sc_fs: ::std::os::raw::c_short,\n    pub sc_gs: ::std::os::raw::c_short,\n    pub sc_addr: ::std::os::raw::c_long,\n    pub sc_flags: ::std::os::raw::c_int,\n    pub sc_es: ::std::os::raw::c_short,\n    pub sc_ds: ::std::os::raw::c_short,\n    pub sc_err: ::std::os::raw::c_long,\n    pub sc_rip: ::std::os::raw::c_long,\n    pub sc_cs: ::std::os::raw::c_long,\n    pub sc_rflags: ::std::os::raw::c_long,\n    pub sc_rsp: ::std::os::raw::c_long,\n    pub sc_ss: ::std::os::raw::c_long,\n    pub sc_len: ::std::os::raw::c_long,\n    pub sc_fpformat: ::std::os::raw::c_long,\n    pub sc_ownedfp: ::std::os::raw::c_long,\n    pub sc_fpstate: [::std::os::raw::c_long; 64usize],\n    pub sc_fsbase: ::std::os::raw::c_long,\n    pub sc_gsbase: ::std::os::raw::c_long,\n    pub sc_xfpustate: ::std::os::raw::c_long,\n    pub sc_xfpustate_len: ::std::os::raw::c_long,\n    pub sc_spare: [::std::os::raw::c_long; 4usize],\n}\n#[test]\nfn bindgen_test_layout_sigcontext() {\n    const UNINIT: ::std::mem::MaybeUninit<sigcontext> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sigcontext>(),\n        816usize,\n        concat!(\"Size of: \", stringify!(sigcontext))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sigcontext>(),\n        16usize,\n        concat!(\"Alignment of \", stringify!(sigcontext))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_mask) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_mask))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_onstack) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sigcontext),\n            \"::\",\n            stringify!(sc_onstack)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_rdi) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_rdi))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_rsi) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_rsi))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_rdx) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_rdx))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_rcx) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_rcx))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_r8) as usize - ptr as usize },\n        56usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_r8))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_r9) as usize - ptr as usize },\n        64usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_r9))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_rax) as usize - ptr as usize },\n        72usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_rax))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_rbx) as usize - ptr as usize },\n        80usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_rbx))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_rbp) as usize - ptr as usize },\n        88usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_rbp))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_r10) as usize - ptr as usize },\n        96usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_r10))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_r11) as usize - ptr as usize },\n        104usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_r11))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_r12) as usize - ptr as usize },\n        112usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_r12))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_r13) as usize - ptr as usize },\n        120usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_r13))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_r14) as usize - ptr as usize },\n        128usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_r14))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_r15) as usize - ptr as usize },\n        136usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_r15))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_trapno) as usize - ptr as usize },\n        144usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_trapno))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_fs) as usize - ptr as usize },\n        148usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_fs))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_gs) as usize - ptr as usize },\n        150usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_gs))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_addr) as usize - ptr as usize },\n        152usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_flags) as usize - ptr as usize },\n        160usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_es) as usize - ptr as usize },\n        164usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_es))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_ds) as usize - ptr as usize },\n        166usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_ds))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_err) as usize - ptr as usize },\n        168usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_err))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_rip) as usize - ptr as usize },\n        176usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_rip))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_cs) as usize - ptr as usize },\n        184usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_cs))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_rflags) as usize - ptr as usize },\n        192usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_rflags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_rsp) as usize - ptr as usize },\n        200usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_rsp))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_ss) as usize - ptr as usize },\n        208usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_ss))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_len) as usize - ptr as usize },\n        216usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_len))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_fpformat) as usize - ptr as usize },\n        224usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sigcontext),\n            \"::\",\n            stringify!(sc_fpformat)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_ownedfp) as usize - ptr as usize },\n        232usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sigcontext),\n            \"::\",\n            stringify!(sc_ownedfp)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_fpstate) as usize - ptr as usize },\n        240usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sigcontext),\n            \"::\",\n            stringify!(sc_fpstate)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_fsbase) as usize - ptr as usize },\n        752usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_fsbase))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_gsbase) as usize - ptr as usize },\n        760usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_gsbase))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_xfpustate) as usize - ptr as usize },\n        768usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sigcontext),\n            \"::\",\n            stringify!(sc_xfpustate)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_xfpustate_len) as usize - ptr as usize },\n        776usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sigcontext),\n            \"::\",\n            stringify!(sc_xfpustate_len)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_spare) as usize - ptr as usize },\n        784usize,\n        concat!(\"Offset of field: \", stringify!(sigcontext), \"::\", stringify!(sc_spare))\n    );\n}\npub type __sighandler_t = ::std::option::Option<unsafe extern \"C\" fn(arg1: ::std::os::raw::c_int)>;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union sigval {\n    pub sival_int: ::std::os::raw::c_int,\n    pub sival_ptr: *mut ::std::os::raw::c_void,\n    pub sigval_int: ::std::os::raw::c_int,\n    pub sigval_ptr: *mut ::std::os::raw::c_void,\n}\n#[test]\nfn bindgen_test_layout_sigval() {\n    const UNINIT: ::std::mem::MaybeUninit<sigval> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sigval>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(sigval))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sigval>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(sigval))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sival_int) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sigval), \"::\", stringify!(sival_int))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sival_ptr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sigval), \"::\", stringify!(sival_ptr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sigval_int) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sigval), \"::\", stringify!(sigval_int))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sigval_ptr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sigval), \"::\", stringify!(sigval_ptr))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct sigevent {\n    pub sigev_notify: ::std::os::raw::c_int,\n    pub sigev_signo: ::std::os::raw::c_int,\n    pub sigev_value: sigval,\n    pub _sigev_un: sigevent__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union sigevent__bindgen_ty_1 {\n    pub _threadid: __lwpid_t,\n    pub _sigev_thread: sigevent__bindgen_ty_1__bindgen_ty_1,\n    pub _kevent_flags: ::std::os::raw::c_ushort,\n    pub __spare__: [::std::os::raw::c_long; 8usize],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sigevent__bindgen_ty_1__bindgen_ty_1 {\n    pub _function: ::std::option::Option<unsafe extern \"C\" fn(arg1: sigval)>,\n    pub _attribute: *mut *mut pthread_attr,\n}\n#[test]\nfn bindgen_test_layout_sigevent__bindgen_ty_1__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<sigevent__bindgen_ty_1__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sigevent__bindgen_ty_1__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(sigevent__bindgen_ty_1__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sigevent__bindgen_ty_1__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(sigevent__bindgen_ty_1__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._function) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sigevent__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(_function)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._attribute) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sigevent__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(_attribute)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_sigevent__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<sigevent__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sigevent__bindgen_ty_1>(),\n        64usize,\n        concat!(\"Size of: \", stringify!(sigevent__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sigevent__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(sigevent__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._threadid) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sigevent__bindgen_ty_1),\n            \"::\",\n            stringify!(_threadid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._sigev_thread) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sigevent__bindgen_ty_1),\n            \"::\",\n            stringify!(_sigev_thread)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._kevent_flags) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sigevent__bindgen_ty_1),\n            \"::\",\n            stringify!(_kevent_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__spare__) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sigevent__bindgen_ty_1),\n            \"::\",\n            stringify!(__spare__)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_sigevent() {\n    const UNINIT: ::std::mem::MaybeUninit<sigevent> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sigevent>(),\n        80usize,\n        concat!(\"Size of: \", stringify!(sigevent))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sigevent>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(sigevent))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sigev_notify) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sigevent),\n            \"::\",\n            stringify!(sigev_notify)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sigev_signo) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(sigevent), \"::\", stringify!(sigev_signo))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sigev_value) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(sigevent), \"::\", stringify!(sigev_value))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._sigev_un) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(sigevent), \"::\", stringify!(_sigev_un))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct __siginfo {\n    pub si_signo: ::std::os::raw::c_int,\n    pub si_errno: ::std::os::raw::c_int,\n    pub si_code: ::std::os::raw::c_int,\n    pub si_pid: __pid_t,\n    pub si_uid: __uid_t,\n    pub si_status: ::std::os::raw::c_int,\n    pub si_addr: *mut ::std::os::raw::c_void,\n    pub si_value: sigval,\n    pub _reason: __siginfo__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union __siginfo__bindgen_ty_1 {\n    pub _fault: __siginfo__bindgen_ty_1__bindgen_ty_1,\n    pub _timer: __siginfo__bindgen_ty_1__bindgen_ty_2,\n    pub _mesgq: __siginfo__bindgen_ty_1__bindgen_ty_3,\n    pub _poll: __siginfo__bindgen_ty_1__bindgen_ty_4,\n    pub _capsicum: __siginfo__bindgen_ty_1__bindgen_ty_5,\n    pub __spare__: __siginfo__bindgen_ty_1__bindgen_ty_6,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __siginfo__bindgen_ty_1__bindgen_ty_1 {\n    pub _trapno: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout___siginfo__bindgen_ty_1__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<__siginfo__bindgen_ty_1__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__siginfo__bindgen_ty_1__bindgen_ty_1>(),\n        4usize,\n        concat!(\"Size of: \", stringify!(__siginfo__bindgen_ty_1__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__siginfo__bindgen_ty_1__bindgen_ty_1>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(__siginfo__bindgen_ty_1__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._trapno) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__siginfo__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(_trapno)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __siginfo__bindgen_ty_1__bindgen_ty_2 {\n    pub _timerid: ::std::os::raw::c_int,\n    pub _overrun: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout___siginfo__bindgen_ty_1__bindgen_ty_2() {\n    const UNINIT: ::std::mem::MaybeUninit<__siginfo__bindgen_ty_1__bindgen_ty_2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__siginfo__bindgen_ty_1__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(__siginfo__bindgen_ty_1__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__siginfo__bindgen_ty_1__bindgen_ty_2>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(__siginfo__bindgen_ty_1__bindgen_ty_2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._timerid) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__siginfo__bindgen_ty_1__bindgen_ty_2),\n            \"::\",\n            stringify!(_timerid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._overrun) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__siginfo__bindgen_ty_1__bindgen_ty_2),\n            \"::\",\n            stringify!(_overrun)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __siginfo__bindgen_ty_1__bindgen_ty_3 {\n    pub _mqd: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout___siginfo__bindgen_ty_1__bindgen_ty_3() {\n    const UNINIT: ::std::mem::MaybeUninit<__siginfo__bindgen_ty_1__bindgen_ty_3> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__siginfo__bindgen_ty_1__bindgen_ty_3>(),\n        4usize,\n        concat!(\"Size of: \", stringify!(__siginfo__bindgen_ty_1__bindgen_ty_3))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__siginfo__bindgen_ty_1__bindgen_ty_3>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(__siginfo__bindgen_ty_1__bindgen_ty_3))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._mqd) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__siginfo__bindgen_ty_1__bindgen_ty_3),\n            \"::\",\n            stringify!(_mqd)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __siginfo__bindgen_ty_1__bindgen_ty_4 {\n    pub _band: ::std::os::raw::c_long,\n}\n#[test]\nfn bindgen_test_layout___siginfo__bindgen_ty_1__bindgen_ty_4() {\n    const UNINIT: ::std::mem::MaybeUninit<__siginfo__bindgen_ty_1__bindgen_ty_4> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__siginfo__bindgen_ty_1__bindgen_ty_4>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(__siginfo__bindgen_ty_1__bindgen_ty_4))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__siginfo__bindgen_ty_1__bindgen_ty_4>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__siginfo__bindgen_ty_1__bindgen_ty_4))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._band) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__siginfo__bindgen_ty_1__bindgen_ty_4),\n            \"::\",\n            stringify!(_band)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __siginfo__bindgen_ty_1__bindgen_ty_5 {\n    pub _syscall: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout___siginfo__bindgen_ty_1__bindgen_ty_5() {\n    const UNINIT: ::std::mem::MaybeUninit<__siginfo__bindgen_ty_1__bindgen_ty_5> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__siginfo__bindgen_ty_1__bindgen_ty_5>(),\n        4usize,\n        concat!(\"Size of: \", stringify!(__siginfo__bindgen_ty_1__bindgen_ty_5))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__siginfo__bindgen_ty_1__bindgen_ty_5>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(__siginfo__bindgen_ty_1__bindgen_ty_5))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._syscall) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__siginfo__bindgen_ty_1__bindgen_ty_5),\n            \"::\",\n            stringify!(_syscall)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __siginfo__bindgen_ty_1__bindgen_ty_6 {\n    pub __spare1__: ::std::os::raw::c_long,\n    pub __spare2__: [::std::os::raw::c_int; 7usize],\n}\n#[test]\nfn bindgen_test_layout___siginfo__bindgen_ty_1__bindgen_ty_6() {\n    const UNINIT: ::std::mem::MaybeUninit<__siginfo__bindgen_ty_1__bindgen_ty_6> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__siginfo__bindgen_ty_1__bindgen_ty_6>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(__siginfo__bindgen_ty_1__bindgen_ty_6))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__siginfo__bindgen_ty_1__bindgen_ty_6>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__siginfo__bindgen_ty_1__bindgen_ty_6))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__spare1__) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__siginfo__bindgen_ty_1__bindgen_ty_6),\n            \"::\",\n            stringify!(__spare1__)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__spare2__) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__siginfo__bindgen_ty_1__bindgen_ty_6),\n            \"::\",\n            stringify!(__spare2__)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout___siginfo__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<__siginfo__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__siginfo__bindgen_ty_1>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(__siginfo__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__siginfo__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__siginfo__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._fault) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__siginfo__bindgen_ty_1),\n            \"::\",\n            stringify!(_fault)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._timer) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__siginfo__bindgen_ty_1),\n            \"::\",\n            stringify!(_timer)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._mesgq) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__siginfo__bindgen_ty_1),\n            \"::\",\n            stringify!(_mesgq)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._poll) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__siginfo__bindgen_ty_1),\n            \"::\",\n            stringify!(_poll)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._capsicum) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__siginfo__bindgen_ty_1),\n            \"::\",\n            stringify!(_capsicum)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__spare__) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__siginfo__bindgen_ty_1),\n            \"::\",\n            stringify!(__spare__)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout___siginfo() {\n    const UNINIT: ::std::mem::MaybeUninit<__siginfo> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__siginfo>(),\n        80usize,\n        concat!(\"Size of: \", stringify!(__siginfo))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__siginfo>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__siginfo))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).si_signo) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(__siginfo), \"::\", stringify!(si_signo))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).si_errno) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(__siginfo), \"::\", stringify!(si_errno))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).si_code) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(__siginfo), \"::\", stringify!(si_code))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).si_pid) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(__siginfo), \"::\", stringify!(si_pid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).si_uid) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(__siginfo), \"::\", stringify!(si_uid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).si_status) as usize - ptr as usize },\n        20usize,\n        concat!(\"Offset of field: \", stringify!(__siginfo), \"::\", stringify!(si_status))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).si_addr) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(__siginfo), \"::\", stringify!(si_addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).si_value) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(__siginfo), \"::\", stringify!(si_value))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._reason) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(__siginfo), \"::\", stringify!(_reason))\n    );\n}\npub type siginfo_t = __siginfo;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct sigaction {\n    pub __sigaction_u: sigaction__bindgen_ty_1,\n    pub sa_flags: ::std::os::raw::c_int,\n    pub sa_mask: sigset_t,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union sigaction__bindgen_ty_1 {\n    pub __sa_handler: ::std::option::Option<unsafe extern \"C\" fn(arg1: ::std::os::raw::c_int)>,\n    pub __sa_sigaction: ::std::option::Option<\n        unsafe extern \"C\" fn(arg1: ::std::os::raw::c_int, arg2: *mut __siginfo, arg3: *mut ::std::os::raw::c_void),\n    >,\n}\n#[test]\nfn bindgen_test_layout_sigaction__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<sigaction__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sigaction__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(sigaction__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sigaction__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(sigaction__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__sa_handler) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sigaction__bindgen_ty_1),\n            \"::\",\n            stringify!(__sa_handler)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__sa_sigaction) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sigaction__bindgen_ty_1),\n            \"::\",\n            stringify!(__sa_sigaction)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_sigaction() {\n    const UNINIT: ::std::mem::MaybeUninit<sigaction> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sigaction>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(sigaction))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sigaction>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(sigaction))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__sigaction_u) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sigaction),\n            \"::\",\n            stringify!(__sigaction_u)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sa_flags) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(sigaction), \"::\", stringify!(sa_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sa_mask) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(sigaction), \"::\", stringify!(sa_mask))\n    );\n}\npub type sig_t = __sighandler_t;\npub type __siginfohandler_t = ::std::option::Option<\n    unsafe extern \"C\" fn(arg1: ::std::os::raw::c_int, arg2: *mut __siginfo, arg3: *mut ::std::os::raw::c_void),\n>;\npub type stack_t = sigaltstack;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sigaltstack {\n    pub ss_sp: *mut ::std::os::raw::c_void,\n    pub ss_size: __size_t,\n    pub ss_flags: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_sigaltstack() {\n    const UNINIT: ::std::mem::MaybeUninit<sigaltstack> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sigaltstack>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(sigaltstack))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sigaltstack>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(sigaltstack))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ss_sp) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sigaltstack), \"::\", stringify!(ss_sp))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ss_size) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(sigaltstack), \"::\", stringify!(ss_size))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ss_flags) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(sigaltstack), \"::\", stringify!(ss_flags))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sigvec {\n    pub sv_handler: __sighandler_t,\n    pub sv_mask: ::std::os::raw::c_int,\n    pub sv_flags: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_sigvec() {\n    const UNINIT: ::std::mem::MaybeUninit<sigvec> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sigvec>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(sigvec))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sigvec>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(sigvec))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sv_handler) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sigvec), \"::\", stringify!(sv_handler))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sv_mask) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(sigvec), \"::\", stringify!(sv_mask))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sv_flags) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(sigvec), \"::\", stringify!(sv_flags))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sigstack {\n    pub ss_sp: *mut ::std::os::raw::c_void,\n    pub ss_onstack: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_sigstack() {\n    const UNINIT: ::std::mem::MaybeUninit<sigstack> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sigstack>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(sigstack))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sigstack>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(sigstack))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ss_sp) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sigstack), \"::\", stringify!(ss_sp))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ss_onstack) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(sigstack), \"::\", stringify!(ss_onstack))\n    );\n}\nunsafe extern \"C\" {\n    pub fn signal(arg1: ::std::os::raw::c_int, arg2: __sighandler_t) -> __sighandler_t;\n}\npub type counter_u64_t = *mut u64;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct _cpuset {\n    pub __bits: [::std::os::raw::c_long; 16usize],\n}\n#[test]\nfn bindgen_test_layout__cpuset() {\n    const UNINIT: ::std::mem::MaybeUninit<_cpuset> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<_cpuset>(),\n        128usize,\n        concat!(\"Size of: \", stringify!(_cpuset))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<_cpuset>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(_cpuset))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__bits) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(_cpuset), \"::\", stringify!(__bits))\n    );\n}\npub type cpuset_t = _cpuset;\nunsafe extern \"C\" {\n    pub fn __cpuset_alloc(set_size: usize) -> *mut cpuset_t;\n}\nunsafe extern \"C\" {\n    pub fn __cpuset_free(ptr: *mut cpuset_t);\n}\nunsafe extern \"C\" {\n    pub fn cpuset(arg1: *mut cpusetid_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn cpuset_setid(arg1: cpuwhich_t, arg2: id_t, arg3: cpusetid_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn cpuset_getid(arg1: cpulevel_t, arg2: cpuwhich_t, arg3: id_t, arg4: *mut cpusetid_t)\n    -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn cpuset_getaffinity(\n        arg1: cpulevel_t,\n        arg2: cpuwhich_t,\n        arg3: id_t,\n        arg4: usize,\n        arg5: *mut cpuset_t,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn cpuset_setaffinity(\n        arg1: cpulevel_t,\n        arg2: cpuwhich_t,\n        arg3: id_t,\n        arg4: usize,\n        arg5: *const cpuset_t,\n    ) -> ::std::os::raw::c_int;\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct epoch_context {\n    pub data: [*mut ::std::os::raw::c_void; 2usize],\n}\n#[test]\nfn bindgen_test_layout_epoch_context() {\n    const UNINIT: ::std::mem::MaybeUninit<epoch_context> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<epoch_context>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(epoch_context))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<epoch_context>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(epoch_context))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).data) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(epoch_context), \"::\", stringify!(data))\n    );\n}\npub type epoch_context_t = *mut epoch_context;\npub type epoch_callback_t = ::std::option::Option<unsafe extern \"C\" fn(arg1: epoch_context_t)>;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct lock_object {\n    pub lo_name: *const ::std::os::raw::c_char,\n    pub lo_flags: u_int,\n    pub lo_data: u_int,\n    pub lo_witness: *mut witness,\n}\n#[test]\nfn bindgen_test_layout_lock_object() {\n    const UNINIT: ::std::mem::MaybeUninit<lock_object> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<lock_object>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(lock_object))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<lock_object>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(lock_object))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lo_name) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(lock_object), \"::\", stringify!(lo_name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lo_flags) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(lock_object), \"::\", stringify!(lo_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lo_data) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(lock_object), \"::\", stringify!(lo_data))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lo_witness) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(lock_object),\n            \"::\",\n            stringify!(lo_witness)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct mtx {\n    pub lock_object: lock_object,\n    pub mtx_lock: usize,\n}\n#[test]\nfn bindgen_test_layout_mtx() {\n    const UNINIT: ::std::mem::MaybeUninit<mtx> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<mtx>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(mtx))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<mtx>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(mtx))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lock_object) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(mtx), \"::\", stringify!(lock_object))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mtx_lock) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(mtx), \"::\", stringify!(mtx_lock))\n    );\n}\n#[repr(C)]\n#[repr(align(64))]\n#[derive(Debug, Copy, Clone)]\npub struct mtx_padalign {\n    pub lock_object: lock_object,\n    pub mtx_lock: usize,\n}\n#[test]\nfn bindgen_test_layout_mtx_padalign() {\n    const UNINIT: ::std::mem::MaybeUninit<mtx_padalign> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<mtx_padalign>(),\n        64usize,\n        concat!(\"Size of: \", stringify!(mtx_padalign))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<mtx_padalign>(),\n        64usize,\n        concat!(\"Alignment of \", stringify!(mtx_padalign))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lock_object) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(mtx_padalign),\n            \"::\",\n            stringify!(lock_object)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mtx_lock) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(mtx_padalign),\n            \"::\",\n            stringify!(mtx_lock)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct malloc_type_stats {\n    pub mts_memalloced: u64,\n    pub mts_memfreed: u64,\n    pub mts_numallocs: u64,\n    pub mts_numfrees: u64,\n    pub mts_size: u64,\n    pub _mts_reserved1: u64,\n    pub _mts_reserved2: u64,\n    pub _mts_reserved3: u64,\n}\n#[test]\nfn bindgen_test_layout_malloc_type_stats() {\n    const UNINIT: ::std::mem::MaybeUninit<malloc_type_stats> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<malloc_type_stats>(),\n        64usize,\n        concat!(\"Size of: \", stringify!(malloc_type_stats))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<malloc_type_stats>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(malloc_type_stats))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mts_memalloced) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(malloc_type_stats),\n            \"::\",\n            stringify!(mts_memalloced)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mts_memfreed) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(malloc_type_stats),\n            \"::\",\n            stringify!(mts_memfreed)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mts_numallocs) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(malloc_type_stats),\n            \"::\",\n            stringify!(mts_numallocs)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mts_numfrees) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(malloc_type_stats),\n            \"::\",\n            stringify!(mts_numfrees)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mts_size) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(malloc_type_stats),\n            \"::\",\n            stringify!(mts_size)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._mts_reserved1) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(malloc_type_stats),\n            \"::\",\n            stringify!(_mts_reserved1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._mts_reserved2) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(malloc_type_stats),\n            \"::\",\n            stringify!(_mts_reserved2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._mts_reserved3) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(malloc_type_stats),\n            \"::\",\n            stringify!(_mts_reserved3)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct malloc_type_internal {\n    pub mti_probes: [u32; 2usize],\n    pub mti_zone: u_char,\n    pub mti_stats: *mut malloc_type_stats,\n    pub mti_spare: [u_long; 8usize],\n}\n#[test]\nfn bindgen_test_layout_malloc_type_internal() {\n    const UNINIT: ::std::mem::MaybeUninit<malloc_type_internal> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<malloc_type_internal>(),\n        88usize,\n        concat!(\"Size of: \", stringify!(malloc_type_internal))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<malloc_type_internal>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(malloc_type_internal))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mti_probes) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(malloc_type_internal),\n            \"::\",\n            stringify!(mti_probes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mti_zone) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(malloc_type_internal),\n            \"::\",\n            stringify!(mti_zone)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mti_stats) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(malloc_type_internal),\n            \"::\",\n            stringify!(mti_stats)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mti_spare) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(malloc_type_internal),\n            \"::\",\n            stringify!(mti_spare)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct malloc_type {\n    pub ks_next: *mut malloc_type,\n    pub ks_version: u_long,\n    pub ks_shortdesc: *const ::std::os::raw::c_char,\n    pub ks_mti: malloc_type_internal,\n}\n#[test]\nfn bindgen_test_layout_malloc_type() {\n    const UNINIT: ::std::mem::MaybeUninit<malloc_type> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<malloc_type>(),\n        112usize,\n        concat!(\"Size of: \", stringify!(malloc_type))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<malloc_type>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(malloc_type))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ks_next) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(malloc_type), \"::\", stringify!(ks_next))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ks_version) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(malloc_type),\n            \"::\",\n            stringify!(ks_version)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ks_shortdesc) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(malloc_type),\n            \"::\",\n            stringify!(ks_shortdesc)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ks_mti) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(malloc_type), \"::\", stringify!(ks_mti))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct malloc_type_stream_header {\n    pub mtsh_version: u32,\n    pub mtsh_maxcpus: u32,\n    pub mtsh_count: u32,\n    pub _mtsh_pad: u32,\n}\n#[test]\nfn bindgen_test_layout_malloc_type_stream_header() {\n    const UNINIT: ::std::mem::MaybeUninit<malloc_type_stream_header> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<malloc_type_stream_header>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(malloc_type_stream_header))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<malloc_type_stream_header>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(malloc_type_stream_header))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mtsh_version) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(malloc_type_stream_header),\n            \"::\",\n            stringify!(mtsh_version)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mtsh_maxcpus) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(malloc_type_stream_header),\n            \"::\",\n            stringify!(mtsh_maxcpus)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mtsh_count) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(malloc_type_stream_header),\n            \"::\",\n            stringify!(mtsh_count)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._mtsh_pad) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(malloc_type_stream_header),\n            \"::\",\n            stringify!(_mtsh_pad)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct malloc_type_header {\n    pub mth_name: [::std::os::raw::c_char; 32usize],\n}\n#[test]\nfn bindgen_test_layout_malloc_type_header() {\n    const UNINIT: ::std::mem::MaybeUninit<malloc_type_header> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<malloc_type_header>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(malloc_type_header))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<malloc_type_header>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(malloc_type_header))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mth_name) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(malloc_type_header),\n            \"::\",\n            stringify!(mth_name)\n        )\n    );\n}\npub type va_list = __va_list;\npub type int_least8_t = __int_least8_t;\npub type int_least16_t = __int_least16_t;\npub type int_least32_t = __int_least32_t;\npub type int_least64_t = __int_least64_t;\npub type uint_least8_t = __uint_least8_t;\npub type uint_least16_t = __uint_least16_t;\npub type uint_least32_t = __uint_least32_t;\npub type uint_least64_t = __uint_least64_t;\npub type int_fast8_t = __int_fast8_t;\npub type int_fast16_t = __int_fast16_t;\npub type int_fast32_t = __int_fast32_t;\npub type int_fast64_t = __int_fast64_t;\npub type uint_fast8_t = __uint_fast8_t;\npub type uint_fast16_t = __uint_fast16_t;\npub type uint_fast32_t = __uint_fast32_t;\npub type uint_fast64_t = __uint_fast64_t;\npub type fpos_t = __off_t;\npub type rsize_t = usize;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __sbuf {\n    pub _base: *mut ::std::os::raw::c_uchar,\n    pub _size: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout___sbuf() {\n    const UNINIT: ::std::mem::MaybeUninit<__sbuf> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__sbuf>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(__sbuf))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__sbuf>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__sbuf))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._base) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(__sbuf), \"::\", stringify!(_base))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._size) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(__sbuf), \"::\", stringify!(_size))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct __sFILE {\n    pub _p: *mut ::std::os::raw::c_uchar,\n    pub _r: ::std::os::raw::c_int,\n    pub _w: ::std::os::raw::c_int,\n    pub _flags: ::std::os::raw::c_short,\n    pub _file: ::std::os::raw::c_short,\n    pub _bf: __sbuf,\n    pub _lbfsize: ::std::os::raw::c_int,\n    pub _cookie: *mut ::std::os::raw::c_void,\n    pub _close: ::std::option::Option<unsafe extern \"C\" fn(arg1: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int>,\n    pub _read: ::std::option::Option<\n        unsafe extern \"C\" fn(\n            arg1: *mut ::std::os::raw::c_void,\n            arg2: *mut ::std::os::raw::c_char,\n            arg3: ::std::os::raw::c_int,\n        ) -> ::std::os::raw::c_int,\n    >,\n    pub _seek: ::std::option::Option<\n        unsafe extern \"C\" fn(arg1: *mut ::std::os::raw::c_void, arg2: fpos_t, arg3: ::std::os::raw::c_int) -> fpos_t,\n    >,\n    pub _write: ::std::option::Option<\n        unsafe extern \"C\" fn(\n            arg1: *mut ::std::os::raw::c_void,\n            arg2: *const ::std::os::raw::c_char,\n            arg3: ::std::os::raw::c_int,\n        ) -> ::std::os::raw::c_int,\n    >,\n    pub _ub: __sbuf,\n    pub _up: *mut ::std::os::raw::c_uchar,\n    pub _ur: ::std::os::raw::c_int,\n    pub _ubuf: [::std::os::raw::c_uchar; 3usize],\n    pub _nbuf: [::std::os::raw::c_uchar; 1usize],\n    pub _lb: __sbuf,\n    pub _blksize: ::std::os::raw::c_int,\n    pub _offset: fpos_t,\n    pub _fl_mutex: *mut pthread_mutex,\n    pub _fl_owner: *mut pthread,\n    pub _fl_count: ::std::os::raw::c_int,\n    pub _orientation: ::std::os::raw::c_int,\n    pub _mbstate: __mbstate_t,\n    pub _flags2: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout___sFILE() {\n    const UNINIT: ::std::mem::MaybeUninit<__sFILE> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__sFILE>(),\n        312usize,\n        concat!(\"Size of: \", stringify!(__sFILE))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__sFILE>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__sFILE))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._p) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(__sFILE), \"::\", stringify!(_p))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._r) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(__sFILE), \"::\", stringify!(_r))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._w) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(__sFILE), \"::\", stringify!(_w))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._flags) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(__sFILE), \"::\", stringify!(_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._file) as usize - ptr as usize },\n        18usize,\n        concat!(\"Offset of field: \", stringify!(__sFILE), \"::\", stringify!(_file))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._bf) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(__sFILE), \"::\", stringify!(_bf))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._lbfsize) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(__sFILE), \"::\", stringify!(_lbfsize))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._cookie) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(__sFILE), \"::\", stringify!(_cookie))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._close) as usize - ptr as usize },\n        56usize,\n        concat!(\"Offset of field: \", stringify!(__sFILE), \"::\", stringify!(_close))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._read) as usize - ptr as usize },\n        64usize,\n        concat!(\"Offset of field: \", stringify!(__sFILE), \"::\", stringify!(_read))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._seek) as usize - ptr as usize },\n        72usize,\n        concat!(\"Offset of field: \", stringify!(__sFILE), \"::\", stringify!(_seek))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._write) as usize - ptr as usize },\n        80usize,\n        concat!(\"Offset of field: \", stringify!(__sFILE), \"::\", stringify!(_write))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._ub) as usize - ptr as usize },\n        88usize,\n        concat!(\"Offset of field: \", stringify!(__sFILE), \"::\", stringify!(_ub))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._up) as usize - ptr as usize },\n        104usize,\n        concat!(\"Offset of field: \", stringify!(__sFILE), \"::\", stringify!(_up))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._ur) as usize - ptr as usize },\n        112usize,\n        concat!(\"Offset of field: \", stringify!(__sFILE), \"::\", stringify!(_ur))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._ubuf) as usize - ptr as usize },\n        116usize,\n        concat!(\"Offset of field: \", stringify!(__sFILE), \"::\", stringify!(_ubuf))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._nbuf) as usize - ptr as usize },\n        119usize,\n        concat!(\"Offset of field: \", stringify!(__sFILE), \"::\", stringify!(_nbuf))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._lb) as usize - ptr as usize },\n        120usize,\n        concat!(\"Offset of field: \", stringify!(__sFILE), \"::\", stringify!(_lb))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._blksize) as usize - ptr as usize },\n        136usize,\n        concat!(\"Offset of field: \", stringify!(__sFILE), \"::\", stringify!(_blksize))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._offset) as usize - ptr as usize },\n        144usize,\n        concat!(\"Offset of field: \", stringify!(__sFILE), \"::\", stringify!(_offset))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._fl_mutex) as usize - ptr as usize },\n        152usize,\n        concat!(\"Offset of field: \", stringify!(__sFILE), \"::\", stringify!(_fl_mutex))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._fl_owner) as usize - ptr as usize },\n        160usize,\n        concat!(\"Offset of field: \", stringify!(__sFILE), \"::\", stringify!(_fl_owner))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._fl_count) as usize - ptr as usize },\n        168usize,\n        concat!(\"Offset of field: \", stringify!(__sFILE), \"::\", stringify!(_fl_count))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._orientation) as usize - ptr as usize },\n        172usize,\n        concat!(\"Offset of field: \", stringify!(__sFILE), \"::\", stringify!(_orientation))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._mbstate) as usize - ptr as usize },\n        176usize,\n        concat!(\"Offset of field: \", stringify!(__sFILE), \"::\", stringify!(_mbstate))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._flags2) as usize - ptr as usize },\n        304usize,\n        concat!(\"Offset of field: \", stringify!(__sFILE), \"::\", stringify!(_flags2))\n    );\n}\npub type FILE = __sFILE;\nunsafe extern \"C\" {\n    pub static mut __stdinp: *mut FILE;\n}\nunsafe extern \"C\" {\n    pub static mut __stdoutp: *mut FILE;\n}\nunsafe extern \"C\" {\n    pub static mut __stderrp: *mut FILE;\n}\nunsafe extern \"C\" {\n    pub fn clearerr(arg1: *mut FILE);\n}\nunsafe extern \"C\" {\n    pub fn fclose(arg1: *mut FILE) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn feof(arg1: *mut FILE) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn ferror(arg1: *mut FILE) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn fflush(arg1: *mut FILE) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn fgetc(arg1: *mut FILE) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn fgetpos(arg1: *mut FILE, arg2: *mut fpos_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn fgets(\n        arg1: *mut ::std::os::raw::c_char,\n        arg2: ::std::os::raw::c_int,\n        arg3: *mut FILE,\n    ) -> *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn fopen(arg1: *const ::std::os::raw::c_char, arg2: *const ::std::os::raw::c_char) -> *mut FILE;\n}\nunsafe extern \"C\" {\n    pub fn fprintf(arg1: *mut FILE, arg2: *const ::std::os::raw::c_char, ...) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn fputc(arg1: ::std::os::raw::c_int, arg2: *mut FILE) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn fputs(arg1: *const ::std::os::raw::c_char, arg2: *mut FILE) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn fread(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: ::std::os::raw::c_ulong,\n        arg3: ::std::os::raw::c_ulong,\n        arg4: *mut FILE,\n    ) -> ::std::os::raw::c_ulong;\n}\nunsafe extern \"C\" {\n    pub fn freopen(\n        arg1: *const ::std::os::raw::c_char,\n        arg2: *const ::std::os::raw::c_char,\n        arg3: *mut FILE,\n    ) -> *mut FILE;\n}\nunsafe extern \"C\" {\n    pub fn fscanf(arg1: *mut FILE, arg2: *const ::std::os::raw::c_char, ...) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn fseek(arg1: *mut FILE, arg2: ::std::os::raw::c_long, arg3: ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn fsetpos(arg1: *mut FILE, arg2: *const fpos_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn ftell(arg1: *mut FILE) -> ::std::os::raw::c_long;\n}\nunsafe extern \"C\" {\n    pub fn fwrite(\n        arg1: *const ::std::os::raw::c_void,\n        arg2: ::std::os::raw::c_ulong,\n        arg3: ::std::os::raw::c_ulong,\n        arg4: *mut FILE,\n    ) -> ::std::os::raw::c_ulong;\n}\nunsafe extern \"C\" {\n    pub fn getc(arg1: *mut FILE) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn getchar() -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn gets_s(arg1: *mut ::std::os::raw::c_char, arg2: rsize_t) -> *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn perror(arg1: *const ::std::os::raw::c_char);\n}\nunsafe extern \"C\" {\n    pub fn printf(arg1: *const ::std::os::raw::c_char, ...) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn putc(arg1: ::std::os::raw::c_int, arg2: *mut FILE) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn putchar(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn puts(arg1: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn remove(arg1: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn rename(arg1: *const ::std::os::raw::c_char, arg2: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn rewind(arg1: *mut FILE);\n}\nunsafe extern \"C\" {\n    pub fn scanf(arg1: *const ::std::os::raw::c_char, ...) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn setbuf(arg1: *mut FILE, arg2: *mut ::std::os::raw::c_char);\n}\nunsafe extern \"C\" {\n    pub fn setvbuf(\n        arg1: *mut FILE,\n        arg2: *mut ::std::os::raw::c_char,\n        arg3: ::std::os::raw::c_int,\n        arg4: usize,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn sprintf(\n        arg1: *mut ::std::os::raw::c_char,\n        arg2: *const ::std::os::raw::c_char,\n        ...\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn sscanf(\n        arg1: *const ::std::os::raw::c_char,\n        arg2: *const ::std::os::raw::c_char,\n        ...\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn tmpfile() -> *mut FILE;\n}\nunsafe extern \"C\" {\n    pub fn tmpnam(arg1: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn ungetc(arg1: ::std::os::raw::c_int, arg2: *mut FILE) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn vfprintf(\n        arg1: *mut FILE,\n        arg2: *const ::std::os::raw::c_char,\n        arg3: *mut __va_list_tag,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn vprintf(arg1: *const ::std::os::raw::c_char, arg2: *mut __va_list_tag) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn vsprintf(\n        arg1: *mut ::std::os::raw::c_char,\n        arg2: *const ::std::os::raw::c_char,\n        arg3: *mut __va_list_tag,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn snprintf(\n        arg1: *mut ::std::os::raw::c_char,\n        arg2: ::std::os::raw::c_ulong,\n        arg3: *const ::std::os::raw::c_char,\n        ...\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn vsnprintf(\n        arg1: *mut ::std::os::raw::c_char,\n        arg2: ::std::os::raw::c_ulong,\n        arg3: *const ::std::os::raw::c_char,\n        arg4: *mut __va_list_tag,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn vfscanf(\n        arg1: *mut FILE,\n        arg2: *const ::std::os::raw::c_char,\n        arg3: *mut __va_list_tag,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn vscanf(arg1: *const ::std::os::raw::c_char, arg2: *mut __va_list_tag) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn vsscanf(\n        arg1: *const ::std::os::raw::c_char,\n        arg2: *const ::std::os::raw::c_char,\n        arg3: *mut __va_list_tag,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn ctermid(arg1: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn fdopen(arg1: ::std::os::raw::c_int, arg2: *const ::std::os::raw::c_char) -> *mut FILE;\n}\nunsafe extern \"C\" {\n    pub fn fileno(arg1: *mut FILE) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn pclose(arg1: *mut FILE) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn popen(arg1: *const ::std::os::raw::c_char, arg2: *const ::std::os::raw::c_char) -> *mut FILE;\n}\nunsafe extern \"C\" {\n    pub fn ftrylockfile(arg1: *mut FILE) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn flockfile(arg1: *mut FILE);\n}\nunsafe extern \"C\" {\n    pub fn funlockfile(arg1: *mut FILE);\n}\nunsafe extern \"C\" {\n    pub fn getc_unlocked(arg1: *mut FILE) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn getchar_unlocked() -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn putc_unlocked(arg1: ::std::os::raw::c_int, arg2: *mut FILE) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn putchar_unlocked(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn clearerr_unlocked(arg1: *mut FILE);\n}\nunsafe extern \"C\" {\n    pub fn feof_unlocked(arg1: *mut FILE) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn ferror_unlocked(arg1: *mut FILE) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn fflush_unlocked(arg1: *mut FILE) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn fileno_unlocked(arg1: *mut FILE) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn fputc_unlocked(arg1: ::std::os::raw::c_int, arg2: *mut FILE) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn fputs_unlocked(arg1: *const ::std::os::raw::c_char, arg2: *mut FILE) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn fread_unlocked(arg1: *mut ::std::os::raw::c_void, arg2: usize, arg3: usize, arg4: *mut FILE) -> usize;\n}\nunsafe extern \"C\" {\n    pub fn fwrite_unlocked(arg1: *const ::std::os::raw::c_void, arg2: usize, arg3: usize, arg4: *mut FILE) -> usize;\n}\nunsafe extern \"C\" {\n    pub fn fseeko(arg1: *mut FILE, arg2: __off_t, arg3: ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn ftello(arg1: *mut FILE) -> __off_t;\n}\nunsafe extern \"C\" {\n    pub fn getw(arg1: *mut FILE) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn putw(arg1: ::std::os::raw::c_int, arg2: *mut FILE) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn tempnam(\n        arg1: *const ::std::os::raw::c_char,\n        arg2: *const ::std::os::raw::c_char,\n    ) -> *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn fmemopen(arg1: *mut ::std::os::raw::c_void, arg2: usize, arg3: *const ::std::os::raw::c_char) -> *mut FILE;\n}\nunsafe extern \"C\" {\n    pub fn getdelim(\n        arg1: *mut *mut ::std::os::raw::c_char,\n        arg2: *mut usize,\n        arg3: ::std::os::raw::c_int,\n        arg4: *mut FILE,\n    ) -> isize;\n}\nunsafe extern \"C\" {\n    pub fn open_memstream(arg1: *mut *mut ::std::os::raw::c_char, arg2: *mut usize) -> *mut FILE;\n}\nunsafe extern \"C\" {\n    pub fn renameat(\n        arg1: ::std::os::raw::c_int,\n        arg2: *const ::std::os::raw::c_char,\n        arg3: ::std::os::raw::c_int,\n        arg4: *const ::std::os::raw::c_char,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn vdprintf(\n        arg1: ::std::os::raw::c_int,\n        arg2: *const ::std::os::raw::c_char,\n        arg3: *mut __va_list_tag,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn getline(arg1: *mut *mut ::std::os::raw::c_char, arg2: *mut usize, arg3: *mut FILE) -> isize;\n}\nunsafe extern \"C\" {\n    pub fn dprintf(arg1: ::std::os::raw::c_int, arg2: *const ::std::os::raw::c_char, ...) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn asprintf(\n        arg1: *mut *mut ::std::os::raw::c_char,\n        arg2: *const ::std::os::raw::c_char,\n        ...\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn ctermid_r(arg1: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn fcloseall();\n}\nunsafe extern \"C\" {\n    pub fn fdclose(arg1: *mut FILE, arg2: *mut ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn fgetln(arg1: *mut FILE, arg2: *mut usize) -> *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn fmtcheck(\n        arg1: *const ::std::os::raw::c_char,\n        arg2: *const ::std::os::raw::c_char,\n    ) -> *const ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn fpurge(arg1: *mut FILE) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn setbuffer(arg1: *mut FILE, arg2: *mut ::std::os::raw::c_char, arg3: ::std::os::raw::c_int);\n}\nunsafe extern \"C\" {\n    pub fn setlinebuf(arg1: *mut FILE) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn vasprintf(\n        arg1: *mut *mut ::std::os::raw::c_char,\n        arg2: *const ::std::os::raw::c_char,\n        arg3: *mut __va_list_tag,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub static sys_nerr: ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub static sys_errlist: [*const ::std::os::raw::c_char; 0usize];\n}\nunsafe extern \"C\" {\n    pub fn funopen(\n        arg1: *const ::std::os::raw::c_void,\n        arg2: ::std::option::Option<\n            unsafe extern \"C\" fn(\n                arg1: *mut ::std::os::raw::c_void,\n                arg2: *mut ::std::os::raw::c_char,\n                arg3: ::std::os::raw::c_int,\n            ) -> ::std::os::raw::c_int,\n        >,\n        arg3: ::std::option::Option<\n            unsafe extern \"C\" fn(\n                arg1: *mut ::std::os::raw::c_void,\n                arg2: *const ::std::os::raw::c_char,\n                arg3: ::std::os::raw::c_int,\n            ) -> ::std::os::raw::c_int,\n        >,\n        arg4: ::std::option::Option<\n            unsafe extern \"C\" fn(\n                arg1: *mut ::std::os::raw::c_void,\n                arg2: fpos_t,\n                arg3: ::std::os::raw::c_int,\n            ) -> fpos_t,\n        >,\n        arg5: ::std::option::Option<unsafe extern \"C\" fn(arg1: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int>,\n    ) -> *mut FILE;\n}\npub type cookie_read_function_t = ::std::option::Option<\n    unsafe extern \"C\" fn(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: *mut ::std::os::raw::c_char,\n        arg3: usize,\n    ) -> __ssize_t,\n>;\npub type cookie_write_function_t = ::std::option::Option<\n    unsafe extern \"C\" fn(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: *const ::std::os::raw::c_char,\n        arg3: usize,\n    ) -> __ssize_t,\n>;\npub type cookie_seek_function_t = ::std::option::Option<\n    unsafe extern \"C\" fn(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: *mut off64_t,\n        arg3: ::std::os::raw::c_int,\n    ) -> ::std::os::raw::c_int,\n>;\npub type cookie_close_function_t =\n    ::std::option::Option<unsafe extern \"C\" fn(arg1: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int>;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct cookie_io_functions_t {\n    pub read: cookie_read_function_t,\n    pub write: cookie_write_function_t,\n    pub seek: cookie_seek_function_t,\n    pub close: cookie_close_function_t,\n}\n#[test]\nfn bindgen_test_layout_cookie_io_functions_t() {\n    const UNINIT: ::std::mem::MaybeUninit<cookie_io_functions_t> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<cookie_io_functions_t>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(cookie_io_functions_t))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<cookie_io_functions_t>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(cookie_io_functions_t))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).read) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(cookie_io_functions_t),\n            \"::\",\n            stringify!(read)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).write) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(cookie_io_functions_t),\n            \"::\",\n            stringify!(write)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).seek) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(cookie_io_functions_t),\n            \"::\",\n            stringify!(seek)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).close) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(cookie_io_functions_t),\n            \"::\",\n            stringify!(close)\n        )\n    );\n}\nunsafe extern \"C\" {\n    pub fn fopencookie(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: *const ::std::os::raw::c_char,\n        arg3: cookie_io_functions_t,\n    ) -> *mut FILE;\n}\nunsafe extern \"C\" {\n    pub fn __srget(arg1: *mut FILE) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn __swbuf(arg1: ::std::os::raw::c_int, arg2: *mut FILE) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub static mut __isthreaded: ::std::os::raw::c_int;\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct FreeBSD_nvlist {\n    _unused: [u8; 0],\n}\npub type FreeBSD_nvlist_t = FreeBSD_nvlist;\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_create(flags: ::std::os::raw::c_int) -> *mut FreeBSD_nvlist_t;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_destroy(nvl: *mut FreeBSD_nvlist_t);\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_error(nvl: *const FreeBSD_nvlist_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_empty(nvl: *const FreeBSD_nvlist_t) -> bool;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_flags(nvl: *const FreeBSD_nvlist_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_set_error(nvl: *mut FreeBSD_nvlist_t, error: ::std::os::raw::c_int);\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_clone(nvl: *const FreeBSD_nvlist_t) -> *mut FreeBSD_nvlist_t;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_dump(nvl: *const FreeBSD_nvlist_t, fd: ::std::os::raw::c_int);\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_fdump(nvl: *const FreeBSD_nvlist_t, fp: *mut FILE);\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_size(nvl: *const FreeBSD_nvlist_t) -> usize;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_pack(nvl: *const FreeBSD_nvlist_t, sizep: *mut usize) -> *mut ::std::os::raw::c_void;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_unpack(\n        buf: *const ::std::os::raw::c_void,\n        size: usize,\n        flags: ::std::os::raw::c_int,\n    ) -> *mut FreeBSD_nvlist_t;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_send(sock: ::std::os::raw::c_int, nvl: *const FreeBSD_nvlist_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_recv(sock: ::std::os::raw::c_int, flags: ::std::os::raw::c_int) -> *mut FreeBSD_nvlist_t;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_xfer(\n        sock: ::std::os::raw::c_int,\n        nvl: *mut FreeBSD_nvlist_t,\n        flags: ::std::os::raw::c_int,\n    ) -> *mut FreeBSD_nvlist_t;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_next(\n        nvl: *const FreeBSD_nvlist_t,\n        typep: *mut ::std::os::raw::c_int,\n        cookiep: *mut *mut ::std::os::raw::c_void,\n    ) -> *const ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_get_parent(\n        nvl: *const FreeBSD_nvlist_t,\n        cookiep: *mut *mut ::std::os::raw::c_void,\n    ) -> *const FreeBSD_nvlist_t;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_get_array_next(nvl: *const FreeBSD_nvlist_t) -> *const FreeBSD_nvlist_t;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_in_array(nvl: *const FreeBSD_nvlist_t) -> bool;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_get_pararr(\n        nvl: *const FreeBSD_nvlist_t,\n        cookiep: *mut *mut ::std::os::raw::c_void,\n    ) -> *const FreeBSD_nvlist_t;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_exists(nvl: *const FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char) -> bool;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_exists_type(\n        nvl: *const FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        type_: ::std::os::raw::c_int,\n    ) -> bool;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_exists_null(nvl: *const FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char) -> bool;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_exists_bool(nvl: *const FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char) -> bool;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_exists_number(nvl: *const FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char) -> bool;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_exists_string(nvl: *const FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char) -> bool;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_exists_nvlist(nvl: *const FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char) -> bool;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_exists_binary(nvl: *const FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char) -> bool;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_exists_bool_array(nvl: *const FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char) -> bool;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_exists_number_array(\n        nvl: *const FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n    ) -> bool;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_exists_string_array(\n        nvl: *const FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n    ) -> bool;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_exists_nvlist_array(\n        nvl: *const FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n    ) -> bool;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_exists_descriptor(nvl: *const FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char) -> bool;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_exists_descriptor_array(\n        nvl: *const FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n    ) -> bool;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_add_null(nvl: *mut FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char);\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_add_bool(nvl: *mut FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char, value: bool);\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_add_number(nvl: *mut FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char, value: u64);\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_add_string(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        value: *const ::std::os::raw::c_char,\n    );\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_add_stringf(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        valuefmt: *const ::std::os::raw::c_char,\n        ...\n    );\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_add_stringv(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        valuefmt: *const ::std::os::raw::c_char,\n        valueap: *mut __va_list_tag,\n    );\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_add_nvlist(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        value: *const FreeBSD_nvlist_t,\n    );\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_add_binary(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        value: *const ::std::os::raw::c_void,\n        size: usize,\n    );\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_add_bool_array(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        value: *const bool,\n        nitems: usize,\n    );\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_add_number_array(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        value: *const u64,\n        nitems: usize,\n    );\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_add_string_array(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        value: *const *const ::std::os::raw::c_char,\n        nitems: usize,\n    );\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_add_nvlist_array(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        value: *const *const FreeBSD_nvlist_t,\n        nitems: usize,\n    );\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_add_descriptor(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        value: ::std::os::raw::c_int,\n    );\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_add_descriptor_array(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        value: *const ::std::os::raw::c_int,\n        nitems: usize,\n    );\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_append_bool_array(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        value: bool,\n    );\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_append_number_array(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        value: u64,\n    );\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_append_string_array(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        value: *const ::std::os::raw::c_char,\n    );\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_append_nvlist_array(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        value: *const FreeBSD_nvlist_t,\n    );\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_append_descriptor_array(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        value: ::std::os::raw::c_int,\n    );\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_move_string(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        value: *mut ::std::os::raw::c_char,\n    );\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_move_nvlist(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        value: *mut FreeBSD_nvlist_t,\n    );\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_move_binary(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        value: *mut ::std::os::raw::c_void,\n        size: usize,\n    );\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_move_bool_array(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        value: *mut bool,\n        nitems: usize,\n    );\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_move_string_array(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        value: *mut *mut ::std::os::raw::c_char,\n        nitems: usize,\n    );\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_move_nvlist_array(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        value: *mut *mut FreeBSD_nvlist_t,\n        nitems: usize,\n    );\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_move_number_array(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        value: *mut u64,\n        nitems: usize,\n    );\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_move_descriptor(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        value: ::std::os::raw::c_int,\n    );\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_move_descriptor_array(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        value: *mut ::std::os::raw::c_int,\n        nitems: usize,\n    );\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_get_bool(nvl: *const FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char) -> bool;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_get_number(nvl: *const FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char) -> u64;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_get_string(\n        nvl: *const FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n    ) -> *const ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_get_nvlist(\n        nvl: *const FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n    ) -> *const FreeBSD_nvlist_t;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_get_binary(\n        nvl: *const FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        sizep: *mut usize,\n    ) -> *const ::std::os::raw::c_void;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_get_bool_array(\n        nvl: *const FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        nitemsp: *mut usize,\n    ) -> *const bool;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_get_number_array(\n        nvl: *const FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        nitemsp: *mut usize,\n    ) -> *const u64;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_get_string_array(\n        nvl: *const FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        nitemsp: *mut usize,\n    ) -> *const *const ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_get_nvlist_array(\n        nvl: *const FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        nitemsp: *mut usize,\n    ) -> *const *const FreeBSD_nvlist_t;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_get_descriptor(\n        nvl: *const FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_get_descriptor_array(\n        nvl: *const FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        nitemsp: *mut usize,\n    ) -> *const ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_take_bool(nvl: *mut FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char) -> bool;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_take_number(nvl: *mut FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char) -> u64;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_take_string(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n    ) -> *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_take_nvlist(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n    ) -> *mut FreeBSD_nvlist_t;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_take_binary(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        sizep: *mut usize,\n    ) -> *mut ::std::os::raw::c_void;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_take_bool_array(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        nitemsp: *mut usize,\n    ) -> *mut bool;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_take_number_array(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        nitemsp: *mut usize,\n    ) -> *mut u64;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_take_string_array(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        nitemsp: *mut usize,\n    ) -> *mut *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_take_nvlist_array(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        nitemsp: *mut usize,\n    ) -> *mut *mut FreeBSD_nvlist_t;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_take_descriptor(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_take_descriptor_array(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        nitemsp: *mut usize,\n    ) -> *mut ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_free(nvl: *mut FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char);\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_free_type(\n        nvl: *mut FreeBSD_nvlist_t,\n        name: *const ::std::os::raw::c_char,\n        type_: ::std::os::raw::c_int,\n    );\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_free_null(nvl: *mut FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char);\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_free_bool(nvl: *mut FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char);\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_free_number(nvl: *mut FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char);\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_free_string(nvl: *mut FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char);\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_free_nvlist(nvl: *mut FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char);\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_free_binary(nvl: *mut FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char);\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_free_bool_array(nvl: *mut FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char);\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_free_number_array(nvl: *mut FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char);\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_free_string_array(nvl: *mut FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char);\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_free_nvlist_array(nvl: *mut FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char);\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_free_binary_array(nvl: *mut FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char);\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_free_descriptor(nvl: *mut FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char);\n}\nunsafe extern \"C\" {\n    pub fn FreeBSD_nvlist_free_descriptor_array(nvl: *mut FreeBSD_nvlist_t, name: *const ::std::os::raw::c_char);\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __hack {\n    _unused: [u8; 0],\n}\nunsafe extern \"C\" {\n    pub fn sysctl(\n        arg1: *const ::std::os::raw::c_int,\n        arg2: ::std::os::raw::c_uint,\n        arg3: *mut ::std::os::raw::c_void,\n        arg4: *mut usize,\n        arg5: *const ::std::os::raw::c_void,\n        arg6: usize,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn sysctlbyname(\n        arg1: *const ::std::os::raw::c_char,\n        arg2: *mut ::std::os::raw::c_void,\n        arg3: *mut usize,\n        arg4: *const ::std::os::raw::c_void,\n        arg5: usize,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn sysctlnametomib(\n        arg1: *const ::std::os::raw::c_char,\n        arg2: *mut ::std::os::raw::c_int,\n        arg3: *mut usize,\n    ) -> ::std::os::raw::c_int;\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct lock_list_entry {\n    _unused: [u8; 0],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct thread {\n    _unused: [u8; 0],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct lock_class {\n    pub lc_name: *const ::std::os::raw::c_char,\n    pub lc_flags: u_int,\n    pub lc_assert: ::std::option::Option<unsafe extern \"C\" fn(lock: *const lock_object, what: ::std::os::raw::c_int)>,\n    pub lc_ddb_show: ::std::option::Option<unsafe extern \"C\" fn(lock: *const lock_object)>,\n    pub lc_lock: ::std::option::Option<unsafe extern \"C\" fn(lock: *mut lock_object, how: usize)>,\n    pub lc_owner: ::std::option::Option<\n        unsafe extern \"C\" fn(lock: *const lock_object, owner: *mut *mut thread) -> ::std::os::raw::c_int,\n    >,\n    pub lc_unlock: ::std::option::Option<unsafe extern \"C\" fn(lock: *mut lock_object) -> usize>,\n}\n#[test]\nfn bindgen_test_layout_lock_class() {\n    const UNINIT: ::std::mem::MaybeUninit<lock_class> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<lock_class>(),\n        56usize,\n        concat!(\"Size of: \", stringify!(lock_class))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<lock_class>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(lock_class))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lc_name) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(lock_class), \"::\", stringify!(lc_name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lc_flags) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(lock_class), \"::\", stringify!(lc_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lc_assert) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(lock_class), \"::\", stringify!(lc_assert))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lc_ddb_show) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(lock_class),\n            \"::\",\n            stringify!(lc_ddb_show)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lc_lock) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(lock_class), \"::\", stringify!(lc_lock))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lc_owner) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(lock_class), \"::\", stringify!(lc_owner))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lc_unlock) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(lock_class), \"::\", stringify!(lc_unlock))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sx {\n    pub lock_object: lock_object,\n    pub sx_lock: usize,\n}\n#[test]\nfn bindgen_test_layout_sx() {\n    const UNINIT: ::std::mem::MaybeUninit<sx> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sx>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(sx))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sx>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(sx))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lock_object) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sx), \"::\", stringify!(lock_object))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sx_lock) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(sx), \"::\", stringify!(sx_lock))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct rmpriolist {\n    pub lh_first: *mut rm_priotracker,\n}\n#[test]\nfn bindgen_test_layout_rmpriolist() {\n    const UNINIT: ::std::mem::MaybeUninit<rmpriolist> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<rmpriolist>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(rmpriolist))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<rmpriolist>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(rmpriolist))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lh_first) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(rmpriolist), \"::\", stringify!(lh_first))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct rm_queue {\n    pub rmq_next: *mut rm_queue,\n    pub rmq_prev: *mut rm_queue,\n}\n#[test]\nfn bindgen_test_layout_rm_queue() {\n    const UNINIT: ::std::mem::MaybeUninit<rm_queue> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<rm_queue>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(rm_queue))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<rm_queue>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(rm_queue))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmq_next) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(rm_queue), \"::\", stringify!(rmq_next))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmq_prev) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(rm_queue), \"::\", stringify!(rmq_prev))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct rmlock {\n    pub lock_object: lock_object,\n    pub rm_writecpus: cpuset_t,\n    pub rm_activeReaders: rmlock__bindgen_ty_1,\n    pub _rm_lock: rmlock__bindgen_ty_2,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct rmlock__bindgen_ty_1 {\n    pub lh_first: *mut rm_priotracker,\n}\n#[test]\nfn bindgen_test_layout_rmlock__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<rmlock__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<rmlock__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(rmlock__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<rmlock__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(rmlock__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lh_first) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rmlock__bindgen_ty_1),\n            \"::\",\n            stringify!(lh_first)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union rmlock__bindgen_ty_2 {\n    pub _rm_wlock_object: lock_object,\n    pub _rm_lock_mtx: mtx,\n    pub _rm_lock_sx: sx,\n}\n#[test]\nfn bindgen_test_layout_rmlock__bindgen_ty_2() {\n    const UNINIT: ::std::mem::MaybeUninit<rmlock__bindgen_ty_2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<rmlock__bindgen_ty_2>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(rmlock__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<rmlock__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(rmlock__bindgen_ty_2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._rm_wlock_object) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rmlock__bindgen_ty_2),\n            \"::\",\n            stringify!(_rm_wlock_object)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._rm_lock_mtx) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rmlock__bindgen_ty_2),\n            \"::\",\n            stringify!(_rm_lock_mtx)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._rm_lock_sx) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rmlock__bindgen_ty_2),\n            \"::\",\n            stringify!(_rm_lock_sx)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_rmlock() {\n    const UNINIT: ::std::mem::MaybeUninit<rmlock> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<rmlock>(),\n        192usize,\n        concat!(\"Size of: \", stringify!(rmlock))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<rmlock>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(rmlock))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lock_object) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(rmlock), \"::\", stringify!(lock_object))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rm_writecpus) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(rmlock), \"::\", stringify!(rm_writecpus))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rm_activeReaders) as usize - ptr as usize },\n        152usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rmlock),\n            \"::\",\n            stringify!(rm_activeReaders)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._rm_lock) as usize - ptr as usize },\n        160usize,\n        concat!(\"Offset of field: \", stringify!(rmlock), \"::\", stringify!(_rm_lock))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct rm_priotracker {\n    pub rmp_cpuQueue: rm_queue,\n    pub rmp_rmlock: *mut rmlock,\n    pub rmp_thread: *mut thread,\n    pub rmp_flags: ::std::os::raw::c_int,\n    pub rmp_qentry: rm_priotracker__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct rm_priotracker__bindgen_ty_1 {\n    pub le_next: *mut rm_priotracker,\n    pub le_prev: *mut *mut rm_priotracker,\n}\n#[test]\nfn bindgen_test_layout_rm_priotracker__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<rm_priotracker__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<rm_priotracker__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(rm_priotracker__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<rm_priotracker__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(rm_priotracker__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).le_next) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rm_priotracker__bindgen_ty_1),\n            \"::\",\n            stringify!(le_next)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).le_prev) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rm_priotracker__bindgen_ty_1),\n            \"::\",\n            stringify!(le_prev)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_rm_priotracker() {\n    const UNINIT: ::std::mem::MaybeUninit<rm_priotracker> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<rm_priotracker>(),\n        56usize,\n        concat!(\"Size of: \", stringify!(rm_priotracker))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<rm_priotracker>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(rm_priotracker))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmp_cpuQueue) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rm_priotracker),\n            \"::\",\n            stringify!(rmp_cpuQueue)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmp_rmlock) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rm_priotracker),\n            \"::\",\n            stringify!(rmp_rmlock)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmp_thread) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rm_priotracker),\n            \"::\",\n            stringify!(rmp_thread)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmp_flags) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rm_priotracker),\n            \"::\",\n            stringify!(rmp_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmp_qentry) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rm_priotracker),\n            \"::\",\n            stringify!(rmp_qentry)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct rmslock_pcpu {\n    _unused: [u8; 0],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct rmslock {\n    pub mtx: mtx,\n    pub owner: *mut thread,\n    pub pcpu: *mut rmslock_pcpu,\n    pub writers: ::std::os::raw::c_int,\n    pub readers: ::std::os::raw::c_int,\n    pub debug_readers: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_rmslock() {\n    const UNINIT: ::std::mem::MaybeUninit<rmslock> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<rmslock>(),\n        64usize,\n        concat!(\"Size of: \", stringify!(rmslock))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<rmslock>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(rmslock))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mtx) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(rmslock), \"::\", stringify!(mtx))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).owner) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(rmslock), \"::\", stringify!(owner))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pcpu) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(rmslock), \"::\", stringify!(pcpu))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).writers) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(rmslock), \"::\", stringify!(writers))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).readers) as usize - ptr as usize },\n        52usize,\n        concat!(\"Offset of field: \", stringify!(rmslock), \"::\", stringify!(readers))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).debug_readers) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rmslock),\n            \"::\",\n            stringify!(debug_readers)\n        )\n    );\n}\npub type seqc_t = u32;\npub type smr_seq_t = u32;\npub type smr_delta_t = i32;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct smr {\n    _unused: [u8; 0],\n}\npub type smr_t = *mut smr;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct uma_zone {\n    _unused: [u8; 0],\n}\npub type uma_zone_t = *mut uma_zone;\npub type uma_ctor = ::std::option::Option<\n    unsafe extern \"C\" fn(\n        mem: *mut ::std::os::raw::c_void,\n        size: ::std::os::raw::c_int,\n        arg: *mut ::std::os::raw::c_void,\n        flags: ::std::os::raw::c_int,\n    ) -> ::std::os::raw::c_int,\n>;\npub type uma_dtor = ::std::option::Option<\n    unsafe extern \"C\" fn(\n        mem: *mut ::std::os::raw::c_void,\n        size: ::std::os::raw::c_int,\n        arg: *mut ::std::os::raw::c_void,\n    ),\n>;\npub type uma_init = ::std::option::Option<\n    unsafe extern \"C\" fn(\n        mem: *mut ::std::os::raw::c_void,\n        size: ::std::os::raw::c_int,\n        flags: ::std::os::raw::c_int,\n    ) -> ::std::os::raw::c_int,\n>;\npub type uma_fini =\n    ::std::option::Option<unsafe extern \"C\" fn(mem: *mut ::std::os::raw::c_void, size: ::std::os::raw::c_int)>;\npub type uma_import = ::std::option::Option<\n    unsafe extern \"C\" fn(\n        arg: *mut ::std::os::raw::c_void,\n        store: *mut *mut ::std::os::raw::c_void,\n        count: ::std::os::raw::c_int,\n        domain: ::std::os::raw::c_int,\n        flags: ::std::os::raw::c_int,\n    ) -> ::std::os::raw::c_int,\n>;\npub type uma_release = ::std::option::Option<\n    unsafe extern \"C\" fn(\n        arg: *mut ::std::os::raw::c_void,\n        store: *mut *mut ::std::os::raw::c_void,\n        count: ::std::os::raw::c_int,\n    ),\n>;\nunsafe extern \"C\" {\n    pub fn uma_zcreate(\n        name: *const ::std::os::raw::c_char,\n        size: usize,\n        ctor: uma_ctor,\n        dtor: uma_dtor,\n        uminit: uma_init,\n        fini: uma_fini,\n        align: ::std::os::raw::c_int,\n        flags: u32,\n    ) -> uma_zone_t;\n}\nunsafe extern \"C\" {\n    pub fn uma_zsecond_create(\n        name: *const ::std::os::raw::c_char,\n        ctor: uma_ctor,\n        dtor: uma_dtor,\n        zinit: uma_init,\n        zfini: uma_fini,\n        primary: uma_zone_t,\n    ) -> uma_zone_t;\n}\nunsafe extern \"C\" {\n    pub fn uma_zcache_create(\n        name: *const ::std::os::raw::c_char,\n        size: ::std::os::raw::c_int,\n        ctor: uma_ctor,\n        dtor: uma_dtor,\n        zinit: uma_init,\n        zfini: uma_fini,\n        zimport: uma_import,\n        zrelease: uma_release,\n        arg: *mut ::std::os::raw::c_void,\n        flags: ::std::os::raw::c_int,\n    ) -> uma_zone_t;\n}\nunsafe extern \"C\" {\n    pub fn uma_zdestroy(zone: uma_zone_t);\n}\nunsafe extern \"C\" {\n    pub fn uma_zalloc_arg(\n        zone: uma_zone_t,\n        arg: *mut ::std::os::raw::c_void,\n        flags: ::std::os::raw::c_int,\n    ) -> *mut ::std::os::raw::c_void;\n}\nunsafe extern \"C\" {\n    pub fn uma_zalloc_pcpu_arg(\n        zone: uma_zone_t,\n        arg: *mut ::std::os::raw::c_void,\n        flags: ::std::os::raw::c_int,\n    ) -> *mut ::std::os::raw::c_void;\n}\nunsafe extern \"C\" {\n    pub fn uma_zalloc_smr(zone: uma_zone_t, flags: ::std::os::raw::c_int) -> *mut ::std::os::raw::c_void;\n}\nunsafe extern \"C\" {\n    pub fn uma_zalloc_domain(\n        zone: uma_zone_t,\n        arg: *mut ::std::os::raw::c_void,\n        domain: ::std::os::raw::c_int,\n        flags: ::std::os::raw::c_int,\n    ) -> *mut ::std::os::raw::c_void;\n}\nunsafe extern \"C\" {\n    pub fn uma_zfree_arg(zone: uma_zone_t, item: *mut ::std::os::raw::c_void, arg: *mut ::std::os::raw::c_void);\n}\nunsafe extern \"C\" {\n    pub fn uma_zfree_pcpu_arg(zone: uma_zone_t, item: *mut ::std::os::raw::c_void, arg: *mut ::std::os::raw::c_void);\n}\nunsafe extern \"C\" {\n    pub fn uma_zfree_smr(zone: uma_zone_t, item: *mut ::std::os::raw::c_void);\n}\nunsafe extern \"C\" {\n    pub fn uma_zwait(zone: uma_zone_t);\n}\npub type uma_alloc = ::std::option::Option<\n    unsafe extern \"C\" fn(\n        zone: uma_zone_t,\n        size: vm_size_t,\n        domain: ::std::os::raw::c_int,\n        pflag: *mut u8,\n        wait: ::std::os::raw::c_int,\n    ) -> *mut ::std::os::raw::c_void,\n>;\npub type uma_free =\n    ::std::option::Option<unsafe extern \"C\" fn(item: *mut ::std::os::raw::c_void, size: vm_size_t, pflag: u8)>;\nunsafe extern \"C\" {\n    pub fn uma_reclaim(req: ::std::os::raw::c_int);\n}\nunsafe extern \"C\" {\n    pub fn uma_reclaim_domain(req: ::std::os::raw::c_int, domain: ::std::os::raw::c_int);\n}\nunsafe extern \"C\" {\n    pub fn uma_zone_reclaim(arg1: uma_zone_t, req: ::std::os::raw::c_int);\n}\nunsafe extern \"C\" {\n    pub fn uma_zone_reclaim_domain(arg1: uma_zone_t, req: ::std::os::raw::c_int, domain: ::std::os::raw::c_int);\n}\nunsafe extern \"C\" {\n    pub fn uma_set_align(align: ::std::os::raw::c_int);\n}\nunsafe extern \"C\" {\n    pub fn uma_zone_reserve(zone: uma_zone_t, nitems: ::std::os::raw::c_int);\n}\nunsafe extern \"C\" {\n    pub fn uma_zone_reserve_kva(zone: uma_zone_t, nitems: ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn uma_zone_set_max(zone: uma_zone_t, nitems: ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn uma_zone_set_maxcache(zone: uma_zone_t, nitems: ::std::os::raw::c_int);\n}\nunsafe extern \"C\" {\n    pub fn uma_zone_get_max(zone: uma_zone_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn uma_zone_set_warning(zone: uma_zone_t, warning: *const ::std::os::raw::c_char);\n}\npub type uma_maxaction_t = ::std::option::Option<unsafe extern \"C\" fn(arg1: uma_zone_t, arg2: ::std::os::raw::c_int)>;\nunsafe extern \"C\" {\n    pub fn uma_zone_set_maxaction(zone: uma_zone_t, arg1: uma_maxaction_t);\n}\nunsafe extern \"C\" {\n    pub fn uma_zone_get_cur(zone: uma_zone_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn uma_zone_set_init(zone: uma_zone_t, uminit: uma_init);\n}\nunsafe extern \"C\" {\n    pub fn uma_zone_set_fini(zone: uma_zone_t, fini: uma_fini);\n}\nunsafe extern \"C\" {\n    pub fn uma_zone_set_zinit(zone: uma_zone_t, zinit: uma_init);\n}\nunsafe extern \"C\" {\n    pub fn uma_zone_set_zfini(zone: uma_zone_t, zfini: uma_fini);\n}\nunsafe extern \"C\" {\n    pub fn uma_zone_set_allocf(zone: uma_zone_t, allocf: uma_alloc);\n}\nunsafe extern \"C\" {\n    pub fn uma_zone_set_freef(zone: uma_zone_t, freef: uma_free);\n}\nunsafe extern \"C\" {\n    pub fn uma_zone_set_smr(zone: uma_zone_t, smr: smr_t);\n}\nunsafe extern \"C\" {\n    pub fn uma_zone_get_smr(zone: uma_zone_t) -> smr_t;\n}\nunsafe extern \"C\" {\n    pub fn uma_prealloc(zone: uma_zone_t, itemcnt: ::std::os::raw::c_int);\n}\nunsafe extern \"C\" {\n    pub fn uma_zone_exhausted(zone: uma_zone_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn uma_zone_memory(zone: uma_zone_t) -> usize;\n}\nunsafe extern \"C\" {\n    pub static mut pcpu_zone_4: uma_zone_t;\n}\nunsafe extern \"C\" {\n    pub static mut pcpu_zone_8: uma_zone_t;\n}\nunsafe extern \"C\" {\n    pub static mut pcpu_zone_16: uma_zone_t;\n}\nunsafe extern \"C\" {\n    pub static mut pcpu_zone_32: uma_zone_t;\n}\nunsafe extern \"C\" {\n    pub static mut pcpu_zone_64: uma_zone_t;\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct uma_stream_header {\n    pub ush_version: u32,\n    pub ush_maxcpus: u32,\n    pub ush_count: u32,\n    pub _ush_pad: u32,\n}\n#[test]\nfn bindgen_test_layout_uma_stream_header() {\n    const UNINIT: ::std::mem::MaybeUninit<uma_stream_header> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<uma_stream_header>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(uma_stream_header))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<uma_stream_header>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(uma_stream_header))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ush_version) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(uma_stream_header),\n            \"::\",\n            stringify!(ush_version)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ush_maxcpus) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(uma_stream_header),\n            \"::\",\n            stringify!(ush_maxcpus)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ush_count) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(uma_stream_header),\n            \"::\",\n            stringify!(ush_count)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._ush_pad) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(uma_stream_header),\n            \"::\",\n            stringify!(_ush_pad)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct uma_type_header {\n    pub uth_name: [::std::os::raw::c_char; 32usize],\n    pub uth_align: u32,\n    pub uth_size: u32,\n    pub uth_rsize: u32,\n    pub uth_maxpages: u32,\n    pub uth_limit: u32,\n    pub uth_pages: u32,\n    pub uth_keg_free: u32,\n    pub uth_zone_free: u32,\n    pub uth_bucketsize: u32,\n    pub uth_zone_flags: u32,\n    pub uth_allocs: u64,\n    pub uth_frees: u64,\n    pub uth_fails: u64,\n    pub uth_sleeps: u64,\n    pub uth_xdomain: u64,\n    pub _uth_reserved1: [u64; 1usize],\n}\n#[test]\nfn bindgen_test_layout_uma_type_header() {\n    const UNINIT: ::std::mem::MaybeUninit<uma_type_header> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<uma_type_header>(),\n        120usize,\n        concat!(\"Size of: \", stringify!(uma_type_header))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<uma_type_header>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(uma_type_header))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uth_name) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(uma_type_header),\n            \"::\",\n            stringify!(uth_name)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uth_align) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(uma_type_header),\n            \"::\",\n            stringify!(uth_align)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uth_size) as usize - ptr as usize },\n        36usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(uma_type_header),\n            \"::\",\n            stringify!(uth_size)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uth_rsize) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(uma_type_header),\n            \"::\",\n            stringify!(uth_rsize)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uth_maxpages) as usize - ptr as usize },\n        44usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(uma_type_header),\n            \"::\",\n            stringify!(uth_maxpages)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uth_limit) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(uma_type_header),\n            \"::\",\n            stringify!(uth_limit)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uth_pages) as usize - ptr as usize },\n        52usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(uma_type_header),\n            \"::\",\n            stringify!(uth_pages)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uth_keg_free) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(uma_type_header),\n            \"::\",\n            stringify!(uth_keg_free)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uth_zone_free) as usize - ptr as usize },\n        60usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(uma_type_header),\n            \"::\",\n            stringify!(uth_zone_free)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uth_bucketsize) as usize - ptr as usize },\n        64usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(uma_type_header),\n            \"::\",\n            stringify!(uth_bucketsize)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uth_zone_flags) as usize - ptr as usize },\n        68usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(uma_type_header),\n            \"::\",\n            stringify!(uth_zone_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uth_allocs) as usize - ptr as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(uma_type_header),\n            \"::\",\n            stringify!(uth_allocs)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uth_frees) as usize - ptr as usize },\n        80usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(uma_type_header),\n            \"::\",\n            stringify!(uth_frees)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uth_fails) as usize - ptr as usize },\n        88usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(uma_type_header),\n            \"::\",\n            stringify!(uth_fails)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uth_sleeps) as usize - ptr as usize },\n        96usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(uma_type_header),\n            \"::\",\n            stringify!(uth_sleeps)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uth_xdomain) as usize - ptr as usize },\n        104usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(uma_type_header),\n            \"::\",\n            stringify!(uth_xdomain)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._uth_reserved1) as usize - ptr as usize },\n        112usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(uma_type_header),\n            \"::\",\n            stringify!(_uth_reserved1)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct uma_percpu_stat {\n    pub ups_allocs: u64,\n    pub ups_frees: u64,\n    pub ups_cache_free: u64,\n    pub _ups_reserved: [u64; 5usize],\n}\n#[test]\nfn bindgen_test_layout_uma_percpu_stat() {\n    const UNINIT: ::std::mem::MaybeUninit<uma_percpu_stat> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<uma_percpu_stat>(),\n        64usize,\n        concat!(\"Size of: \", stringify!(uma_percpu_stat))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<uma_percpu_stat>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(uma_percpu_stat))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ups_allocs) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(uma_percpu_stat),\n            \"::\",\n            stringify!(ups_allocs)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ups_frees) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(uma_percpu_stat),\n            \"::\",\n            stringify!(ups_frees)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ups_cache_free) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(uma_percpu_stat),\n            \"::\",\n            stringify!(ups_cache_free)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._ups_reserved) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(uma_percpu_stat),\n            \"::\",\n            stringify!(_ups_reserved)\n        )\n    );\n}\nunsafe extern \"C\" {\n    pub fn uma_reclaim_wakeup();\n}\nunsafe extern \"C\" {\n    pub fn uma_reclaim_worker(arg1: *mut ::std::os::raw::c_void);\n}\nunsafe extern \"C\" {\n    pub fn uma_limit() -> ::std::os::raw::c_ulong;\n}\nunsafe extern \"C\" {\n    pub fn uma_size() -> ::std::os::raw::c_ulong;\n}\nunsafe extern \"C\" {\n    pub fn uma_avail() -> ::std::os::raw::c_long;\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct timezone {\n    pub tz_minuteswest: ::std::os::raw::c_int,\n    pub tz_dsttime: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_timezone() {\n    const UNINIT: ::std::mem::MaybeUninit<timezone> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<timezone>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(timezone))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<timezone>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(timezone))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tz_minuteswest) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(timezone),\n            \"::\",\n            stringify!(tz_minuteswest)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tz_dsttime) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(timezone), \"::\", stringify!(tz_dsttime))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct bintime {\n    pub sec: time_t,\n    pub frac: u64,\n}\n#[test]\nfn bindgen_test_layout_bintime() {\n    const UNINIT: ::std::mem::MaybeUninit<bintime> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<bintime>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(bintime))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<bintime>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(bintime))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sec) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(bintime), \"::\", stringify!(sec))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).frac) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(bintime), \"::\", stringify!(frac))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct itimerval {\n    pub it_interval: timeval,\n    pub it_value: timeval,\n}\n#[test]\nfn bindgen_test_layout_itimerval() {\n    const UNINIT: ::std::mem::MaybeUninit<itimerval> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<itimerval>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(itimerval))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<itimerval>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(itimerval))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).it_interval) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(itimerval),\n            \"::\",\n            stringify!(it_interval)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).it_value) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(itimerval), \"::\", stringify!(it_value))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct clockinfo {\n    pub hz: ::std::os::raw::c_int,\n    pub tick: ::std::os::raw::c_int,\n    pub spare: ::std::os::raw::c_int,\n    pub stathz: ::std::os::raw::c_int,\n    pub profhz: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_clockinfo() {\n    const UNINIT: ::std::mem::MaybeUninit<clockinfo> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<clockinfo>(),\n        20usize,\n        concat!(\"Size of: \", stringify!(clockinfo))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<clockinfo>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(clockinfo))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).hz) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(clockinfo), \"::\", stringify!(hz))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tick) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(clockinfo), \"::\", stringify!(tick))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).spare) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(clockinfo), \"::\", stringify!(spare))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).stathz) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(clockinfo), \"::\", stringify!(stathz))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).profhz) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(clockinfo), \"::\", stringify!(profhz))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct tm {\n    pub tm_sec: ::std::os::raw::c_int,\n    pub tm_min: ::std::os::raw::c_int,\n    pub tm_hour: ::std::os::raw::c_int,\n    pub tm_mday: ::std::os::raw::c_int,\n    pub tm_mon: ::std::os::raw::c_int,\n    pub tm_year: ::std::os::raw::c_int,\n    pub tm_wday: ::std::os::raw::c_int,\n    pub tm_yday: ::std::os::raw::c_int,\n    pub tm_isdst: ::std::os::raw::c_int,\n    pub tm_gmtoff: ::std::os::raw::c_long,\n    pub tm_zone: *mut ::std::os::raw::c_char,\n}\n#[test]\nfn bindgen_test_layout_tm() {\n    const UNINIT: ::std::mem::MaybeUninit<tm> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<tm>(),\n        56usize,\n        concat!(\"Size of: \", stringify!(tm))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<tm>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(tm))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_sec) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_sec))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_min) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_min))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_hour) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_hour))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_mday) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_mday))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_mon) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_mon))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_year) as usize - ptr as usize },\n        20usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_year))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_wday) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_wday))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_yday) as usize - ptr as usize },\n        28usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_yday))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_isdst) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_isdst))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_gmtoff) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_gmtoff))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_zone) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_zone))\n    );\n}\nunsafe extern \"C\" {\n    pub static mut tzname: [*mut ::std::os::raw::c_char; 0usize];\n}\nunsafe extern \"C\" {\n    pub fn asctime(arg1: *const tm) -> *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn clock() -> clock_t;\n}\nunsafe extern \"C\" {\n    pub fn ctime(arg1: *const time_t) -> *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn difftime(arg1: time_t, arg2: time_t) -> f64;\n}\nunsafe extern \"C\" {\n    pub fn gmtime(arg1: *const time_t) -> *mut tm;\n}\nunsafe extern \"C\" {\n    pub fn localtime(arg1: *const time_t) -> *mut tm;\n}\nunsafe extern \"C\" {\n    pub fn mktime(arg1: *mut tm) -> time_t;\n}\nunsafe extern \"C\" {\n    pub fn strftime(\n        arg1: *mut ::std::os::raw::c_char,\n        arg2: usize,\n        arg3: *const ::std::os::raw::c_char,\n        arg4: *const tm,\n    ) -> usize;\n}\nunsafe extern \"C\" {\n    pub fn time(arg1: *mut time_t) -> time_t;\n}\nunsafe extern \"C\" {\n    pub fn timer_create(arg1: clockid_t, arg2: *mut sigevent, arg3: *mut timer_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn timer_delete(arg1: timer_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn timer_gettime(arg1: timer_t, arg2: *mut itimerspec) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn timer_getoverrun(arg1: timer_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn timer_settime(\n        arg1: timer_t,\n        arg2: ::std::os::raw::c_int,\n        arg3: *const itimerspec,\n        arg4: *mut itimerspec,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn tzset();\n}\nunsafe extern \"C\" {\n    pub fn clock_getres(arg1: clockid_t, arg2: *mut timespec) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn clock_gettime(arg1: clockid_t, arg2: *mut timespec) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn clock_settime(arg1: clockid_t, arg2: *const timespec) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn nanosleep(arg1: *const timespec, arg2: *mut timespec) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn clock_getcpuclockid(arg1: pid_t, arg2: *mut clockid_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn clock_nanosleep(\n        arg1: clockid_t,\n        arg2: ::std::os::raw::c_int,\n        arg3: *const timespec,\n        arg4: *mut timespec,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn asctime_r(arg1: *const tm, arg2: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn ctime_r(arg1: *const time_t, arg2: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn gmtime_r(arg1: *const time_t, arg2: *mut tm) -> *mut tm;\n}\nunsafe extern \"C\" {\n    pub fn localtime_r(arg1: *const time_t, arg2: *mut tm) -> *mut tm;\n}\nunsafe extern \"C\" {\n    pub fn strptime(\n        arg1: *const ::std::os::raw::c_char,\n        arg2: *const ::std::os::raw::c_char,\n        arg3: *mut tm,\n    ) -> *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn timezone(arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int) -> *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn timelocal(arg1: *mut tm) -> time_t;\n}\nunsafe extern \"C\" {\n    pub fn timegm(arg1: *mut tm) -> time_t;\n}\nunsafe extern \"C\" {\n    pub fn timer_oshandle_np(timerid: timer_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn time2posix(t: time_t) -> time_t;\n}\nunsafe extern \"C\" {\n    pub fn posix2time(t: time_t) -> time_t;\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct _xlocale {\n    _unused: [u8; 0],\n}\npub type locale_t = *mut _xlocale;\nunsafe extern \"C\" {\n    pub fn strftime_l(\n        arg1: *mut ::std::os::raw::c_char,\n        arg2: usize,\n        arg3: *const ::std::os::raw::c_char,\n        arg4: *const tm,\n        arg5: locale_t,\n    ) -> usize;\n}\nunsafe extern \"C\" {\n    pub fn timespec_get(ts: *mut timespec, base: ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn timespec_getres(arg1: *mut timespec, arg2: ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn setitimer(\n        arg1: ::std::os::raw::c_int,\n        arg2: *const itimerval,\n        arg3: *mut itimerval,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn utimes(arg1: *const ::std::os::raw::c_char, arg2: *const timeval) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn adjtime(arg1: *const timeval, arg2: *mut timeval) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn clock_getcpuclockid2(arg1: id_t, arg2: ::std::os::raw::c_int, arg3: *mut clockid_t)\n    -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn futimes(arg1: ::std::os::raw::c_int, arg2: *const timeval) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn futimesat(\n        arg1: ::std::os::raw::c_int,\n        arg2: *const ::std::os::raw::c_char,\n        arg3: *const timeval,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn lutimes(arg1: *const ::std::os::raw::c_char, arg2: *const timeval) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn settimeofday(arg1: *const timeval, arg2: *const timezone) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn getitimer(arg1: ::std::os::raw::c_int, arg2: *mut itimerval) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn gettimeofday(arg1: *mut timeval, arg2: *mut timezone) -> ::std::os::raw::c_int;\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct iovec {\n    pub iov_base: *mut ::std::os::raw::c_void,\n    pub iov_len: usize,\n}\n#[test]\nfn bindgen_test_layout_iovec() {\n    const UNINIT: ::std::mem::MaybeUninit<iovec> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<iovec>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(iovec))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<iovec>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(iovec))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).iov_base) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(iovec), \"::\", stringify!(iov_base))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).iov_len) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(iovec), \"::\", stringify!(iov_len))\n    );\n}\npub type sa_family_t = __sa_family_t;\npub type socklen_t = __socklen_t;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct linger {\n    pub l_onoff: ::std::os::raw::c_int,\n    pub l_linger: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_linger() {\n    const UNINIT: ::std::mem::MaybeUninit<linger> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<linger>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(linger))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<linger>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(linger))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).l_onoff) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(linger), \"::\", stringify!(l_onoff))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).l_linger) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(linger), \"::\", stringify!(l_linger))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct accept_filter_arg {\n    pub af_name: [::std::os::raw::c_char; 16usize],\n    pub af_arg: [::std::os::raw::c_char; 240usize],\n}\n#[test]\nfn bindgen_test_layout_accept_filter_arg() {\n    const UNINIT: ::std::mem::MaybeUninit<accept_filter_arg> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<accept_filter_arg>(),\n        256usize,\n        concat!(\"Size of: \", stringify!(accept_filter_arg))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<accept_filter_arg>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(accept_filter_arg))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).af_name) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(accept_filter_arg),\n            \"::\",\n            stringify!(af_name)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).af_arg) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(accept_filter_arg),\n            \"::\",\n            stringify!(af_arg)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sockaddr {\n    pub sa_len: ::std::os::raw::c_uchar,\n    pub sa_family: sa_family_t,\n    pub sa_data: [::std::os::raw::c_char; 14usize],\n}\n#[test]\nfn bindgen_test_layout_sockaddr() {\n    const UNINIT: ::std::mem::MaybeUninit<sockaddr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sockaddr>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(sockaddr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sockaddr>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(sockaddr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sa_len) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr), \"::\", stringify!(sa_len))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sa_family) as usize - ptr as usize },\n        1usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr), \"::\", stringify!(sa_family))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sa_data) as usize - ptr as usize },\n        2usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr), \"::\", stringify!(sa_data))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sockproto {\n    pub sp_family: ::std::os::raw::c_ushort,\n    pub sp_protocol: ::std::os::raw::c_ushort,\n}\n#[test]\nfn bindgen_test_layout_sockproto() {\n    const UNINIT: ::std::mem::MaybeUninit<sockproto> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sockproto>(),\n        4usize,\n        concat!(\"Size of: \", stringify!(sockproto))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sockproto>(),\n        2usize,\n        concat!(\"Alignment of \", stringify!(sockproto))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sp_family) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sockproto), \"::\", stringify!(sp_family))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sp_protocol) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockproto),\n            \"::\",\n            stringify!(sp_protocol)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sockaddr_storage {\n    pub ss_len: ::std::os::raw::c_uchar,\n    pub ss_family: sa_family_t,\n    pub __ss_pad1: [::std::os::raw::c_char; 6usize],\n    pub __ss_align: __int64_t,\n    pub __ss_pad2: [::std::os::raw::c_char; 112usize],\n}\n#[test]\nfn bindgen_test_layout_sockaddr_storage() {\n    const UNINIT: ::std::mem::MaybeUninit<sockaddr_storage> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sockaddr_storage>(),\n        128usize,\n        concat!(\"Size of: \", stringify!(sockaddr_storage))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sockaddr_storage>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(sockaddr_storage))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ss_len) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_storage),\n            \"::\",\n            stringify!(ss_len)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ss_family) as usize - ptr as usize },\n        1usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_storage),\n            \"::\",\n            stringify!(ss_family)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ss_pad1) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_storage),\n            \"::\",\n            stringify!(__ss_pad1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ss_align) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_storage),\n            \"::\",\n            stringify!(__ss_align)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ss_pad2) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_storage),\n            \"::\",\n            stringify!(__ss_pad2)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct msghdr {\n    pub msg_name: *mut ::std::os::raw::c_void,\n    pub msg_namelen: socklen_t,\n    pub msg_iov: *mut iovec,\n    pub msg_iovlen: ::std::os::raw::c_int,\n    pub msg_control: *mut ::std::os::raw::c_void,\n    pub msg_controllen: socklen_t,\n    pub msg_flags: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_msghdr() {\n    const UNINIT: ::std::mem::MaybeUninit<msghdr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<msghdr>(),\n        48usize,\n        concat!(\"Size of: \", stringify!(msghdr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<msghdr>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(msghdr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_name) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(msghdr), \"::\", stringify!(msg_name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_namelen) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(msghdr), \"::\", stringify!(msg_namelen))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_iov) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(msghdr), \"::\", stringify!(msg_iov))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_iovlen) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(msghdr), \"::\", stringify!(msg_iovlen))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_control) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(msghdr), \"::\", stringify!(msg_control))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_controllen) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(msghdr),\n            \"::\",\n            stringify!(msg_controllen)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_flags) as usize - ptr as usize },\n        44usize,\n        concat!(\"Offset of field: \", stringify!(msghdr), \"::\", stringify!(msg_flags))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct cmsghdr {\n    pub cmsg_len: socklen_t,\n    pub cmsg_level: ::std::os::raw::c_int,\n    pub cmsg_type: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_cmsghdr() {\n    const UNINIT: ::std::mem::MaybeUninit<cmsghdr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<cmsghdr>(),\n        12usize,\n        concat!(\"Size of: \", stringify!(cmsghdr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<cmsghdr>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(cmsghdr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cmsg_len) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(cmsghdr), \"::\", stringify!(cmsg_len))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cmsg_level) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(cmsghdr), \"::\", stringify!(cmsg_level))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cmsg_type) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(cmsghdr), \"::\", stringify!(cmsg_type))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct cmsgcred {\n    pub cmcred_pid: pid_t,\n    pub cmcred_uid: uid_t,\n    pub cmcred_euid: uid_t,\n    pub cmcred_gid: gid_t,\n    pub cmcred_ngroups: ::std::os::raw::c_short,\n    pub cmcred_groups: [gid_t; 16usize],\n}\n#[test]\nfn bindgen_test_layout_cmsgcred() {\n    const UNINIT: ::std::mem::MaybeUninit<cmsgcred> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<cmsgcred>(),\n        84usize,\n        concat!(\"Size of: \", stringify!(cmsgcred))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<cmsgcred>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(cmsgcred))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cmcred_pid) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(cmsgcred), \"::\", stringify!(cmcred_pid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cmcred_uid) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(cmsgcred), \"::\", stringify!(cmcred_uid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cmcred_euid) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(cmsgcred), \"::\", stringify!(cmcred_euid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cmcred_gid) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(cmsgcred), \"::\", stringify!(cmcred_gid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cmcred_ngroups) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(cmsgcred),\n            \"::\",\n            stringify!(cmcred_ngroups)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cmcred_groups) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(cmsgcred),\n            \"::\",\n            stringify!(cmcred_groups)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sockcred {\n    pub sc_uid: uid_t,\n    pub sc_euid: uid_t,\n    pub sc_gid: gid_t,\n    pub sc_egid: gid_t,\n    pub sc_ngroups: ::std::os::raw::c_int,\n    pub sc_groups: [gid_t; 1usize],\n}\n#[test]\nfn bindgen_test_layout_sockcred() {\n    const UNINIT: ::std::mem::MaybeUninit<sockcred> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sockcred>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(sockcred))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sockcred>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(sockcred))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_uid) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sockcred), \"::\", stringify!(sc_uid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_euid) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(sockcred), \"::\", stringify!(sc_euid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_gid) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(sockcred), \"::\", stringify!(sc_gid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_egid) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(sockcred), \"::\", stringify!(sc_egid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_ngroups) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(sockcred), \"::\", stringify!(sc_ngroups))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_groups) as usize - ptr as usize },\n        20usize,\n        concat!(\"Offset of field: \", stringify!(sockcred), \"::\", stringify!(sc_groups))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sockcred2 {\n    pub sc_version: ::std::os::raw::c_int,\n    pub sc_pid: pid_t,\n    pub sc_uid: uid_t,\n    pub sc_euid: uid_t,\n    pub sc_gid: gid_t,\n    pub sc_egid: gid_t,\n    pub sc_ngroups: ::std::os::raw::c_int,\n    pub sc_groups: [gid_t; 1usize],\n}\n#[test]\nfn bindgen_test_layout_sockcred2() {\n    const UNINIT: ::std::mem::MaybeUninit<sockcred2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sockcred2>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(sockcred2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sockcred2>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(sockcred2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_version) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sockcred2), \"::\", stringify!(sc_version))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_pid) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(sockcred2), \"::\", stringify!(sc_pid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_uid) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(sockcred2), \"::\", stringify!(sc_uid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_euid) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(sockcred2), \"::\", stringify!(sc_euid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_gid) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(sockcred2), \"::\", stringify!(sc_gid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_egid) as usize - ptr as usize },\n        20usize,\n        concat!(\"Offset of field: \", stringify!(sockcred2), \"::\", stringify!(sc_egid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_ngroups) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(sockcred2), \"::\", stringify!(sc_ngroups))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sc_groups) as usize - ptr as usize },\n        28usize,\n        concat!(\"Offset of field: \", stringify!(sockcred2), \"::\", stringify!(sc_groups))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sock_timestamp_info {\n    pub st_info_flags: __uint32_t,\n    pub st_info_pad0: __uint32_t,\n    pub st_info_rsv: [__uint64_t; 7usize],\n}\n#[test]\nfn bindgen_test_layout_sock_timestamp_info() {\n    const UNINIT: ::std::mem::MaybeUninit<sock_timestamp_info> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sock_timestamp_info>(),\n        64usize,\n        concat!(\"Size of: \", stringify!(sock_timestamp_info))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sock_timestamp_info>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(sock_timestamp_info))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).st_info_flags) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sock_timestamp_info),\n            \"::\",\n            stringify!(st_info_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).st_info_pad0) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sock_timestamp_info),\n            \"::\",\n            stringify!(st_info_pad0)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).st_info_rsv) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sock_timestamp_info),\n            \"::\",\n            stringify!(st_info_rsv)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct osockaddr {\n    pub sa_family: ::std::os::raw::c_ushort,\n    pub sa_data: [::std::os::raw::c_char; 14usize],\n}\n#[test]\nfn bindgen_test_layout_osockaddr() {\n    const UNINIT: ::std::mem::MaybeUninit<osockaddr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<osockaddr>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(osockaddr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<osockaddr>(),\n        2usize,\n        concat!(\"Alignment of \", stringify!(osockaddr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sa_family) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(osockaddr), \"::\", stringify!(sa_family))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sa_data) as usize - ptr as usize },\n        2usize,\n        concat!(\"Offset of field: \", stringify!(osockaddr), \"::\", stringify!(sa_data))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct omsghdr {\n    pub msg_name: *mut ::std::os::raw::c_char,\n    pub msg_namelen: ::std::os::raw::c_int,\n    pub msg_iov: *mut iovec,\n    pub msg_iovlen: ::std::os::raw::c_int,\n    pub msg_accrights: *mut ::std::os::raw::c_char,\n    pub msg_accrightslen: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_omsghdr() {\n    const UNINIT: ::std::mem::MaybeUninit<omsghdr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<omsghdr>(),\n        48usize,\n        concat!(\"Size of: \", stringify!(omsghdr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<omsghdr>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(omsghdr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_name) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(omsghdr), \"::\", stringify!(msg_name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_namelen) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(omsghdr), \"::\", stringify!(msg_namelen))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_iov) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(omsghdr), \"::\", stringify!(msg_iov))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_iovlen) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(omsghdr), \"::\", stringify!(msg_iovlen))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_accrights) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(omsghdr),\n            \"::\",\n            stringify!(msg_accrights)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_accrightslen) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(omsghdr),\n            \"::\",\n            stringify!(msg_accrightslen)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sf_hdtr {\n    pub headers: *mut iovec,\n    pub hdr_cnt: ::std::os::raw::c_int,\n    pub trailers: *mut iovec,\n    pub trl_cnt: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_sf_hdtr() {\n    const UNINIT: ::std::mem::MaybeUninit<sf_hdtr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sf_hdtr>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(sf_hdtr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sf_hdtr>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(sf_hdtr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).headers) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sf_hdtr), \"::\", stringify!(headers))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).hdr_cnt) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(sf_hdtr), \"::\", stringify!(hdr_cnt))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).trailers) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(sf_hdtr), \"::\", stringify!(trailers))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).trl_cnt) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(sf_hdtr), \"::\", stringify!(trl_cnt))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct mmsghdr {\n    pub msg_hdr: msghdr,\n    pub msg_len: isize,\n}\n#[test]\nfn bindgen_test_layout_mmsghdr() {\n    const UNINIT: ::std::mem::MaybeUninit<mmsghdr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<mmsghdr>(),\n        56usize,\n        concat!(\"Size of: \", stringify!(mmsghdr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<mmsghdr>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(mmsghdr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_hdr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(mmsghdr), \"::\", stringify!(msg_hdr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_len) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(mmsghdr), \"::\", stringify!(msg_len))\n    );\n}\nunsafe extern \"C\" {\n    pub fn accept(arg1: ::std::os::raw::c_int, arg2: *mut sockaddr, arg3: *mut socklen_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn bind(arg1: ::std::os::raw::c_int, arg2: *const sockaddr, arg3: socklen_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn connect(arg1: ::std::os::raw::c_int, arg2: *const sockaddr, arg3: socklen_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn accept4(\n        arg1: ::std::os::raw::c_int,\n        arg2: *mut sockaddr,\n        arg3: *mut socklen_t,\n        arg4: ::std::os::raw::c_int,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn bindat(\n        arg1: ::std::os::raw::c_int,\n        arg2: ::std::os::raw::c_int,\n        arg3: *const sockaddr,\n        arg4: socklen_t,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn connectat(\n        arg1: ::std::os::raw::c_int,\n        arg2: ::std::os::raw::c_int,\n        arg3: *const sockaddr,\n        arg4: socklen_t,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn getpeername(arg1: ::std::os::raw::c_int, arg2: *mut sockaddr, arg3: *mut socklen_t)\n    -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn getsockname(arg1: ::std::os::raw::c_int, arg2: *mut sockaddr, arg3: *mut socklen_t)\n    -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn getsockopt(\n        arg1: ::std::os::raw::c_int,\n        arg2: ::std::os::raw::c_int,\n        arg3: ::std::os::raw::c_int,\n        arg4: *mut ::std::os::raw::c_void,\n        arg5: *mut socklen_t,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn listen(arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn recv(\n        arg1: ::std::os::raw::c_int,\n        arg2: *mut ::std::os::raw::c_void,\n        arg3: usize,\n        arg4: ::std::os::raw::c_int,\n    ) -> isize;\n}\nunsafe extern \"C\" {\n    pub fn recvfrom(\n        arg1: ::std::os::raw::c_int,\n        arg2: *mut ::std::os::raw::c_void,\n        arg3: usize,\n        arg4: ::std::os::raw::c_int,\n        arg5: *mut sockaddr,\n        arg6: *mut socklen_t,\n    ) -> isize;\n}\nunsafe extern \"C\" {\n    pub fn recvmsg(arg1: ::std::os::raw::c_int, arg2: *mut msghdr, arg3: ::std::os::raw::c_int) -> isize;\n}\nunsafe extern \"C\" {\n    pub fn recvmmsg(\n        arg1: ::std::os::raw::c_int,\n        arg2: *mut mmsghdr,\n        arg3: usize,\n        arg4: ::std::os::raw::c_int,\n        arg5: *const timespec,\n    ) -> isize;\n}\nunsafe extern \"C\" {\n    pub fn send(\n        arg1: ::std::os::raw::c_int,\n        arg2: *const ::std::os::raw::c_void,\n        arg3: usize,\n        arg4: ::std::os::raw::c_int,\n    ) -> isize;\n}\nunsafe extern \"C\" {\n    pub fn sendto(\n        arg1: ::std::os::raw::c_int,\n        arg2: *const ::std::os::raw::c_void,\n        arg3: usize,\n        arg4: ::std::os::raw::c_int,\n        arg5: *const sockaddr,\n        arg6: socklen_t,\n    ) -> isize;\n}\nunsafe extern \"C\" {\n    pub fn sendmsg(arg1: ::std::os::raw::c_int, arg2: *const msghdr, arg3: ::std::os::raw::c_int) -> isize;\n}\nunsafe extern \"C\" {\n    pub fn sendfile(\n        arg1: ::std::os::raw::c_int,\n        arg2: ::std::os::raw::c_int,\n        arg3: off_t,\n        arg4: usize,\n        arg5: *mut sf_hdtr,\n        arg6: *mut off_t,\n        arg7: ::std::os::raw::c_int,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn sendmmsg(arg1: ::std::os::raw::c_int, arg2: *mut mmsghdr, arg3: usize, arg4: ::std::os::raw::c_int)\n    -> isize;\n}\nunsafe extern \"C\" {\n    pub fn setfib(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn setsockopt(\n        arg1: ::std::os::raw::c_int,\n        arg2: ::std::os::raw::c_int,\n        arg3: ::std::os::raw::c_int,\n        arg4: *const ::std::os::raw::c_void,\n        arg5: socklen_t,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn shutdown(arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn sockatmark(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn socket(\n        arg1: ::std::os::raw::c_int,\n        arg2: ::std::os::raw::c_int,\n        arg3: ::std::os::raw::c_int,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn socketpair(\n        arg1: ::std::os::raw::c_int,\n        arg2: ::std::os::raw::c_int,\n        arg3: ::std::os::raw::c_int,\n        arg4: *mut ::std::os::raw::c_int,\n    ) -> ::std::os::raw::c_int;\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct if_clonereq {\n    pub ifcr_total: ::std::os::raw::c_int,\n    pub ifcr_count: ::std::os::raw::c_int,\n    pub ifcr_buffer: *mut ::std::os::raw::c_char,\n}\n#[test]\nfn bindgen_test_layout_if_clonereq() {\n    const UNINIT: ::std::mem::MaybeUninit<if_clonereq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_clonereq>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(if_clonereq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_clonereq>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(if_clonereq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifcr_total) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_clonereq),\n            \"::\",\n            stringify!(ifcr_total)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifcr_count) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_clonereq),\n            \"::\",\n            stringify!(ifcr_count)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifcr_buffer) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_clonereq),\n            \"::\",\n            stringify!(ifcr_buffer)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct if_data {\n    pub ifi_type: u8,\n    pub ifi_physical: u8,\n    pub ifi_addrlen: u8,\n    pub ifi_hdrlen: u8,\n    pub ifi_link_state: u8,\n    pub ifi_vhid: u8,\n    pub ifi_datalen: u16,\n    pub ifi_mtu: u32,\n    pub ifi_metric: u32,\n    pub ifi_baudrate: u64,\n    pub ifi_ipackets: u64,\n    pub ifi_ierrors: u64,\n    pub ifi_opackets: u64,\n    pub ifi_oerrors: u64,\n    pub ifi_collisions: u64,\n    pub ifi_ibytes: u64,\n    pub ifi_obytes: u64,\n    pub ifi_imcasts: u64,\n    pub ifi_omcasts: u64,\n    pub ifi_iqdrops: u64,\n    pub ifi_oqdrops: u64,\n    pub ifi_noproto: u64,\n    pub ifi_hwassist: u64,\n    pub __ifi_epoch: if_data__bindgen_ty_1,\n    pub __ifi_lastchange: if_data__bindgen_ty_2,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union if_data__bindgen_ty_1 {\n    pub tt: time_t,\n    pub ph: u64,\n}\n#[test]\nfn bindgen_test_layout_if_data__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<if_data__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_data__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(if_data__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_data__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(if_data__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tt) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data__bindgen_ty_1),\n            \"::\",\n            stringify!(tt)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ph) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data__bindgen_ty_1),\n            \"::\",\n            stringify!(ph)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union if_data__bindgen_ty_2 {\n    pub tv: timeval,\n    pub ph: if_data__bindgen_ty_2__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct if_data__bindgen_ty_2__bindgen_ty_1 {\n    pub ph1: u64,\n    pub ph2: u64,\n}\n#[test]\nfn bindgen_test_layout_if_data__bindgen_ty_2__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<if_data__bindgen_ty_2__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_data__bindgen_ty_2__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(if_data__bindgen_ty_2__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_data__bindgen_ty_2__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(if_data__bindgen_ty_2__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ph1) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data__bindgen_ty_2__bindgen_ty_1),\n            \"::\",\n            stringify!(ph1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ph2) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data__bindgen_ty_2__bindgen_ty_1),\n            \"::\",\n            stringify!(ph2)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_if_data__bindgen_ty_2() {\n    const UNINIT: ::std::mem::MaybeUninit<if_data__bindgen_ty_2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_data__bindgen_ty_2>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(if_data__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_data__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(if_data__bindgen_ty_2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tv) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data__bindgen_ty_2),\n            \"::\",\n            stringify!(tv)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ph) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data__bindgen_ty_2),\n            \"::\",\n            stringify!(ph)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_if_data() {\n    const UNINIT: ::std::mem::MaybeUninit<if_data> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_data>(),\n        152usize,\n        concat!(\"Size of: \", stringify!(if_data))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_data>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(if_data))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_type) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_type))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_physical) as usize - ptr as usize },\n        1usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_physical))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_addrlen) as usize - ptr as usize },\n        2usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_addrlen))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_hdrlen) as usize - ptr as usize },\n        3usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_hdrlen))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_link_state) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data),\n            \"::\",\n            stringify!(ifi_link_state)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_vhid) as usize - ptr as usize },\n        5usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_vhid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_datalen) as usize - ptr as usize },\n        6usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_datalen))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_mtu) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_mtu))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_metric) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_metric))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_baudrate) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_baudrate))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_ipackets) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_ipackets))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_ierrors) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_ierrors))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_opackets) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_opackets))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_oerrors) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_oerrors))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_collisions) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data),\n            \"::\",\n            stringify!(ifi_collisions)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_ibytes) as usize - ptr as usize },\n        64usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_ibytes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_obytes) as usize - ptr as usize },\n        72usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_obytes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_imcasts) as usize - ptr as usize },\n        80usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_imcasts))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_omcasts) as usize - ptr as usize },\n        88usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_omcasts))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_iqdrops) as usize - ptr as usize },\n        96usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_iqdrops))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_oqdrops) as usize - ptr as usize },\n        104usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_oqdrops))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_noproto) as usize - ptr as usize },\n        112usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_noproto))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_hwassist) as usize - ptr as usize },\n        120usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_hwassist))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ifi_epoch) as usize - ptr as usize },\n        128usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(__ifi_epoch))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ifi_lastchange) as usize - ptr as usize },\n        136usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data),\n            \"::\",\n            stringify!(__ifi_lastchange)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct if_msghdr {\n    pub ifm_msglen: u_short,\n    pub ifm_version: u_char,\n    pub ifm_type: u_char,\n    pub ifm_addrs: ::std::os::raw::c_int,\n    pub ifm_flags: ::std::os::raw::c_int,\n    pub ifm_index: u_short,\n    pub _ifm_spare1: u_short,\n    pub ifm_data: if_data,\n}\n#[test]\nfn bindgen_test_layout_if_msghdr() {\n    const UNINIT: ::std::mem::MaybeUninit<if_msghdr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_msghdr>(),\n        168usize,\n        concat!(\"Size of: \", stringify!(if_msghdr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_msghdr>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(if_msghdr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_msglen) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(if_msghdr), \"::\", stringify!(ifm_msglen))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_version) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_msghdr),\n            \"::\",\n            stringify!(ifm_version)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_type) as usize - ptr as usize },\n        3usize,\n        concat!(\"Offset of field: \", stringify!(if_msghdr), \"::\", stringify!(ifm_type))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_addrs) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(if_msghdr), \"::\", stringify!(ifm_addrs))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_flags) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(if_msghdr), \"::\", stringify!(ifm_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_index) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(if_msghdr), \"::\", stringify!(ifm_index))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._ifm_spare1) as usize - ptr as usize },\n        14usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_msghdr),\n            \"::\",\n            stringify!(_ifm_spare1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_data) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(if_msghdr), \"::\", stringify!(ifm_data))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct if_msghdrl {\n    pub ifm_msglen: u_short,\n    pub ifm_version: u_char,\n    pub ifm_type: u_char,\n    pub ifm_addrs: ::std::os::raw::c_int,\n    pub ifm_flags: ::std::os::raw::c_int,\n    pub ifm_index: u_short,\n    pub _ifm_spare1: u_short,\n    pub ifm_len: u_short,\n    pub ifm_data_off: u_short,\n    pub _ifm_spare2: ::std::os::raw::c_int,\n    pub ifm_data: if_data,\n}\n#[test]\nfn bindgen_test_layout_if_msghdrl() {\n    const UNINIT: ::std::mem::MaybeUninit<if_msghdrl> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_msghdrl>(),\n        176usize,\n        concat!(\"Size of: \", stringify!(if_msghdrl))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_msghdrl>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(if_msghdrl))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_msglen) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_msghdrl),\n            \"::\",\n            stringify!(ifm_msglen)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_version) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_msghdrl),\n            \"::\",\n            stringify!(ifm_version)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_type) as usize - ptr as usize },\n        3usize,\n        concat!(\"Offset of field: \", stringify!(if_msghdrl), \"::\", stringify!(ifm_type))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_addrs) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(if_msghdrl), \"::\", stringify!(ifm_addrs))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_flags) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(if_msghdrl), \"::\", stringify!(ifm_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_index) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(if_msghdrl), \"::\", stringify!(ifm_index))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._ifm_spare1) as usize - ptr as usize },\n        14usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_msghdrl),\n            \"::\",\n            stringify!(_ifm_spare1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_len) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(if_msghdrl), \"::\", stringify!(ifm_len))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_data_off) as usize - ptr as usize },\n        18usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_msghdrl),\n            \"::\",\n            stringify!(ifm_data_off)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._ifm_spare2) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_msghdrl),\n            \"::\",\n            stringify!(_ifm_spare2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_data) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(if_msghdrl), \"::\", stringify!(ifm_data))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ifa_msghdr {\n    pub ifam_msglen: u_short,\n    pub ifam_version: u_char,\n    pub ifam_type: u_char,\n    pub ifam_addrs: ::std::os::raw::c_int,\n    pub ifam_flags: ::std::os::raw::c_int,\n    pub ifam_index: u_short,\n    pub _ifam_spare1: u_short,\n    pub ifam_metric: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_ifa_msghdr() {\n    const UNINIT: ::std::mem::MaybeUninit<ifa_msghdr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifa_msghdr>(),\n        20usize,\n        concat!(\"Size of: \", stringify!(ifa_msghdr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifa_msghdr>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(ifa_msghdr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifam_msglen) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifa_msghdr),\n            \"::\",\n            stringify!(ifam_msglen)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifam_version) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifa_msghdr),\n            \"::\",\n            stringify!(ifam_version)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifam_type) as usize - ptr as usize },\n        3usize,\n        concat!(\"Offset of field: \", stringify!(ifa_msghdr), \"::\", stringify!(ifam_type))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifam_addrs) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifa_msghdr),\n            \"::\",\n            stringify!(ifam_addrs)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifam_flags) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifa_msghdr),\n            \"::\",\n            stringify!(ifam_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifam_index) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifa_msghdr),\n            \"::\",\n            stringify!(ifam_index)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._ifam_spare1) as usize - ptr as usize },\n        14usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifa_msghdr),\n            \"::\",\n            stringify!(_ifam_spare1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifam_metric) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifa_msghdr),\n            \"::\",\n            stringify!(ifam_metric)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct ifa_msghdrl {\n    pub ifam_msglen: u_short,\n    pub ifam_version: u_char,\n    pub ifam_type: u_char,\n    pub ifam_addrs: ::std::os::raw::c_int,\n    pub ifam_flags: ::std::os::raw::c_int,\n    pub ifam_index: u_short,\n    pub _ifam_spare1: u_short,\n    pub ifam_len: u_short,\n    pub ifam_data_off: u_short,\n    pub ifam_metric: ::std::os::raw::c_int,\n    pub ifam_data: if_data,\n}\n#[test]\nfn bindgen_test_layout_ifa_msghdrl() {\n    const UNINIT: ::std::mem::MaybeUninit<ifa_msghdrl> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifa_msghdrl>(),\n        176usize,\n        concat!(\"Size of: \", stringify!(ifa_msghdrl))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifa_msghdrl>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(ifa_msghdrl))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifam_msglen) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifa_msghdrl),\n            \"::\",\n            stringify!(ifam_msglen)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifam_version) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifa_msghdrl),\n            \"::\",\n            stringify!(ifam_version)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifam_type) as usize - ptr as usize },\n        3usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifa_msghdrl),\n            \"::\",\n            stringify!(ifam_type)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifam_addrs) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifa_msghdrl),\n            \"::\",\n            stringify!(ifam_addrs)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifam_flags) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifa_msghdrl),\n            \"::\",\n            stringify!(ifam_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifam_index) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifa_msghdrl),\n            \"::\",\n            stringify!(ifam_index)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._ifam_spare1) as usize - ptr as usize },\n        14usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifa_msghdrl),\n            \"::\",\n            stringify!(_ifam_spare1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifam_len) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(ifa_msghdrl), \"::\", stringify!(ifam_len))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifam_data_off) as usize - ptr as usize },\n        18usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifa_msghdrl),\n            \"::\",\n            stringify!(ifam_data_off)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifam_metric) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifa_msghdrl),\n            \"::\",\n            stringify!(ifam_metric)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifam_data) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifa_msghdrl),\n            \"::\",\n            stringify!(ifam_data)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ifma_msghdr {\n    pub ifmam_msglen: u_short,\n    pub ifmam_version: u_char,\n    pub ifmam_type: u_char,\n    pub ifmam_addrs: ::std::os::raw::c_int,\n    pub ifmam_flags: ::std::os::raw::c_int,\n    pub ifmam_index: u_short,\n    pub _ifmam_spare1: u_short,\n}\n#[test]\nfn bindgen_test_layout_ifma_msghdr() {\n    const UNINIT: ::std::mem::MaybeUninit<ifma_msghdr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifma_msghdr>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(ifma_msghdr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifma_msghdr>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(ifma_msghdr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifmam_msglen) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifma_msghdr),\n            \"::\",\n            stringify!(ifmam_msglen)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifmam_version) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifma_msghdr),\n            \"::\",\n            stringify!(ifmam_version)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifmam_type) as usize - ptr as usize },\n        3usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifma_msghdr),\n            \"::\",\n            stringify!(ifmam_type)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifmam_addrs) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifma_msghdr),\n            \"::\",\n            stringify!(ifmam_addrs)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifmam_flags) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifma_msghdr),\n            \"::\",\n            stringify!(ifmam_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifmam_index) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifma_msghdr),\n            \"::\",\n            stringify!(ifmam_index)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._ifmam_spare1) as usize - ptr as usize },\n        14usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifma_msghdr),\n            \"::\",\n            stringify!(_ifmam_spare1)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct if_announcemsghdr {\n    pub ifan_msglen: u_short,\n    pub ifan_version: u_char,\n    pub ifan_type: u_char,\n    pub ifan_index: u_short,\n    pub ifan_name: [::std::os::raw::c_char; 16usize],\n    pub ifan_what: u_short,\n}\n#[test]\nfn bindgen_test_layout_if_announcemsghdr() {\n    const UNINIT: ::std::mem::MaybeUninit<if_announcemsghdr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_announcemsghdr>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(if_announcemsghdr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_announcemsghdr>(),\n        2usize,\n        concat!(\"Alignment of \", stringify!(if_announcemsghdr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifan_msglen) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_announcemsghdr),\n            \"::\",\n            stringify!(ifan_msglen)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifan_version) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_announcemsghdr),\n            \"::\",\n            stringify!(ifan_version)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifan_type) as usize - ptr as usize },\n        3usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_announcemsghdr),\n            \"::\",\n            stringify!(ifan_type)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifan_index) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_announcemsghdr),\n            \"::\",\n            stringify!(ifan_index)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifan_name) as usize - ptr as usize },\n        6usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_announcemsghdr),\n            \"::\",\n            stringify!(ifan_name)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifan_what) as usize - ptr as usize },\n        22usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_announcemsghdr),\n            \"::\",\n            stringify!(ifan_what)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ifreq_buffer {\n    pub length: usize,\n    pub buffer: *mut ::std::os::raw::c_void,\n}\n#[test]\nfn bindgen_test_layout_ifreq_buffer() {\n    const UNINIT: ::std::mem::MaybeUninit<ifreq_buffer> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifreq_buffer>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(ifreq_buffer))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifreq_buffer>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(ifreq_buffer))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).length) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(ifreq_buffer), \"::\", stringify!(length))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).buffer) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(ifreq_buffer), \"::\", stringify!(buffer))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ifreq_nv_req {\n    pub buf_length: u_int,\n    pub length: u_int,\n    pub buffer: *mut ::std::os::raw::c_void,\n}\n#[test]\nfn bindgen_test_layout_ifreq_nv_req() {\n    const UNINIT: ::std::mem::MaybeUninit<ifreq_nv_req> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifreq_nv_req>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(ifreq_nv_req))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifreq_nv_req>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(ifreq_nv_req))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).buf_length) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifreq_nv_req),\n            \"::\",\n            stringify!(buf_length)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).length) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(ifreq_nv_req), \"::\", stringify!(length))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).buffer) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(ifreq_nv_req), \"::\", stringify!(buffer))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct ifreq {\n    pub ifr_name: [::std::os::raw::c_char; 16usize],\n    pub ifr_ifru: ifreq__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union ifreq__bindgen_ty_1 {\n    pub ifru_addr: sockaddr,\n    pub ifru_dstaddr: sockaddr,\n    pub ifru_broadaddr: sockaddr,\n    pub ifru_buffer: ifreq_buffer,\n    pub ifru_flags: [::std::os::raw::c_short; 2usize],\n    pub ifru_index: ::std::os::raw::c_short,\n    pub ifru_jid: ::std::os::raw::c_int,\n    pub ifru_metric: ::std::os::raw::c_int,\n    pub ifru_mtu: ::std::os::raw::c_int,\n    pub ifru_phys: ::std::os::raw::c_int,\n    pub ifru_media: ::std::os::raw::c_int,\n    pub ifru_data: caddr_t,\n    pub ifru_cap: [::std::os::raw::c_int; 2usize],\n    pub ifru_fib: u_int,\n    pub ifru_vlan_pcp: u_char,\n    pub ifru_nv: ifreq_nv_req,\n}\n#[test]\nfn bindgen_test_layout_ifreq__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<ifreq__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifreq__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(ifreq__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifreq__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(ifreq__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifru_addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifru_addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifru_dstaddr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifru_dstaddr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifru_broadaddr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifru_broadaddr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifru_buffer) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifru_buffer)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifru_flags) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifru_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifru_index) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifru_index)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifru_jid) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifru_jid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifru_metric) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifru_metric)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifru_mtu) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifru_mtu)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifru_phys) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifru_phys)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifru_media) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifru_media)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifru_data) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifru_data)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifru_cap) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifru_cap)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifru_fib) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifru_fib)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifru_vlan_pcp) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifru_vlan_pcp)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifru_nv) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifru_nv)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_ifreq() {\n    const UNINIT: ::std::mem::MaybeUninit<ifreq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifreq>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(ifreq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifreq>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(ifreq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifr_name) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(ifreq), \"::\", stringify!(ifr_name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifr_ifru) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(ifreq), \"::\", stringify!(ifr_ifru))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ifaliasreq {\n    pub ifra_name: [::std::os::raw::c_char; 16usize],\n    pub ifra_addr: sockaddr,\n    pub ifra_broadaddr: sockaddr,\n    pub ifra_mask: sockaddr,\n    pub ifra_vhid: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_ifaliasreq() {\n    const UNINIT: ::std::mem::MaybeUninit<ifaliasreq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifaliasreq>(),\n        68usize,\n        concat!(\"Size of: \", stringify!(ifaliasreq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifaliasreq>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(ifaliasreq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifra_name) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(ifaliasreq), \"::\", stringify!(ifra_name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifra_addr) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(ifaliasreq), \"::\", stringify!(ifra_addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifra_broadaddr) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifaliasreq),\n            \"::\",\n            stringify!(ifra_broadaddr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifra_mask) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(ifaliasreq), \"::\", stringify!(ifra_mask))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifra_vhid) as usize - ptr as usize },\n        64usize,\n        concat!(\"Offset of field: \", stringify!(ifaliasreq), \"::\", stringify!(ifra_vhid))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct oifaliasreq {\n    pub ifra_name: [::std::os::raw::c_char; 16usize],\n    pub ifra_addr: sockaddr,\n    pub ifra_broadaddr: sockaddr,\n    pub ifra_mask: sockaddr,\n}\n#[test]\nfn bindgen_test_layout_oifaliasreq() {\n    const UNINIT: ::std::mem::MaybeUninit<oifaliasreq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<oifaliasreq>(),\n        64usize,\n        concat!(\"Size of: \", stringify!(oifaliasreq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<oifaliasreq>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(oifaliasreq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifra_name) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(oifaliasreq),\n            \"::\",\n            stringify!(ifra_name)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifra_addr) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(oifaliasreq),\n            \"::\",\n            stringify!(ifra_addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifra_broadaddr) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(oifaliasreq),\n            \"::\",\n            stringify!(ifra_broadaddr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifra_mask) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(oifaliasreq),\n            \"::\",\n            stringify!(ifra_mask)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ifmediareq {\n    pub ifm_name: [::std::os::raw::c_char; 16usize],\n    pub ifm_current: ::std::os::raw::c_int,\n    pub ifm_mask: ::std::os::raw::c_int,\n    pub ifm_status: ::std::os::raw::c_int,\n    pub ifm_active: ::std::os::raw::c_int,\n    pub ifm_count: ::std::os::raw::c_int,\n    pub ifm_ulist: *mut ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_ifmediareq() {\n    const UNINIT: ::std::mem::MaybeUninit<ifmediareq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifmediareq>(),\n        48usize,\n        concat!(\"Size of: \", stringify!(ifmediareq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifmediareq>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(ifmediareq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_name) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(ifmediareq), \"::\", stringify!(ifm_name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_current) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifmediareq),\n            \"::\",\n            stringify!(ifm_current)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_mask) as usize - ptr as usize },\n        20usize,\n        concat!(\"Offset of field: \", stringify!(ifmediareq), \"::\", stringify!(ifm_mask))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_status) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifmediareq),\n            \"::\",\n            stringify!(ifm_status)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_active) as usize - ptr as usize },\n        28usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifmediareq),\n            \"::\",\n            stringify!(ifm_active)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_count) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(ifmediareq), \"::\", stringify!(ifm_count))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_ulist) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(ifmediareq), \"::\", stringify!(ifm_ulist))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ifdrv {\n    pub ifd_name: [::std::os::raw::c_char; 16usize],\n    pub ifd_cmd: ::std::os::raw::c_ulong,\n    pub ifd_len: usize,\n    pub ifd_data: *mut ::std::os::raw::c_void,\n}\n#[test]\nfn bindgen_test_layout_ifdrv() {\n    const UNINIT: ::std::mem::MaybeUninit<ifdrv> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifdrv>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(ifdrv))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifdrv>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(ifdrv))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifd_name) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(ifdrv), \"::\", stringify!(ifd_name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifd_cmd) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(ifdrv), \"::\", stringify!(ifd_cmd))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifd_len) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(ifdrv), \"::\", stringify!(ifd_len))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifd_data) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(ifdrv), \"::\", stringify!(ifd_data))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ifstat {\n    pub ifs_name: [::std::os::raw::c_char; 16usize],\n    pub ascii: [::std::os::raw::c_char; 801usize],\n}\n#[test]\nfn bindgen_test_layout_ifstat() {\n    const UNINIT: ::std::mem::MaybeUninit<ifstat> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifstat>(),\n        817usize,\n        concat!(\"Size of: \", stringify!(ifstat))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifstat>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(ifstat))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifs_name) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(ifstat), \"::\", stringify!(ifs_name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ascii) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(ifstat), \"::\", stringify!(ascii))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct ifconf {\n    pub ifc_len: ::std::os::raw::c_int,\n    pub ifc_ifcu: ifconf__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union ifconf__bindgen_ty_1 {\n    pub ifcu_buf: caddr_t,\n    pub ifcu_req: *mut ifreq,\n}\n#[test]\nfn bindgen_test_layout_ifconf__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<ifconf__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifconf__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(ifconf__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifconf__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(ifconf__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifcu_buf) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifconf__bindgen_ty_1),\n            \"::\",\n            stringify!(ifcu_buf)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifcu_req) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifconf__bindgen_ty_1),\n            \"::\",\n            stringify!(ifcu_req)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_ifconf() {\n    const UNINIT: ::std::mem::MaybeUninit<ifconf> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifconf>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(ifconf))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifconf>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(ifconf))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifc_len) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(ifconf), \"::\", stringify!(ifc_len))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifc_ifcu) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(ifconf), \"::\", stringify!(ifc_ifcu))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct ifg_req {\n    pub ifgrq_ifgrqu: ifg_req__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union ifg_req__bindgen_ty_1 {\n    pub ifgrqu_group: [::std::os::raw::c_char; 16usize],\n    pub ifgrqu_member: [::std::os::raw::c_char; 16usize],\n}\n#[test]\nfn bindgen_test_layout_ifg_req__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<ifg_req__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifg_req__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(ifg_req__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifg_req__bindgen_ty_1>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(ifg_req__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifgrqu_group) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifg_req__bindgen_ty_1),\n            \"::\",\n            stringify!(ifgrqu_group)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifgrqu_member) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifg_req__bindgen_ty_1),\n            \"::\",\n            stringify!(ifgrqu_member)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_ifg_req() {\n    const UNINIT: ::std::mem::MaybeUninit<ifg_req> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifg_req>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(ifg_req))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifg_req>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(ifg_req))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifgrq_ifgrqu) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(ifg_req), \"::\", stringify!(ifgrq_ifgrqu))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct ifgroupreq {\n    pub ifgr_name: [::std::os::raw::c_char; 16usize],\n    pub ifgr_len: u_int,\n    pub ifgr_ifgru: ifgroupreq__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union ifgroupreq__bindgen_ty_1 {\n    pub ifgru_group: [::std::os::raw::c_char; 16usize],\n    pub ifgru_groups: *mut ifg_req,\n}\n#[test]\nfn bindgen_test_layout_ifgroupreq__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<ifgroupreq__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifgroupreq__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(ifgroupreq__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifgroupreq__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(ifgroupreq__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifgru_group) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifgroupreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifgru_group)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifgru_groups) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifgroupreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifgru_groups)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_ifgroupreq() {\n    const UNINIT: ::std::mem::MaybeUninit<ifgroupreq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifgroupreq>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(ifgroupreq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifgroupreq>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(ifgroupreq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifgr_name) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(ifgroupreq), \"::\", stringify!(ifgr_name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifgr_len) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(ifgroupreq), \"::\", stringify!(ifgr_len))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifgr_ifgru) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifgroupreq),\n            \"::\",\n            stringify!(ifgr_ifgru)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ifi2creq {\n    pub dev_addr: u8,\n    pub offset: u8,\n    pub len: u8,\n    pub spare0: u8,\n    pub spare1: u32,\n    pub data: [u8; 8usize],\n}\n#[test]\nfn bindgen_test_layout_ifi2creq() {\n    const UNINIT: ::std::mem::MaybeUninit<ifi2creq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifi2creq>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(ifi2creq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifi2creq>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(ifi2creq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dev_addr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(ifi2creq), \"::\", stringify!(dev_addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).offset) as usize - ptr as usize },\n        1usize,\n        concat!(\"Offset of field: \", stringify!(ifi2creq), \"::\", stringify!(offset))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).len) as usize - ptr as usize },\n        2usize,\n        concat!(\"Offset of field: \", stringify!(ifi2creq), \"::\", stringify!(len))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).spare0) as usize - ptr as usize },\n        3usize,\n        concat!(\"Offset of field: \", stringify!(ifi2creq), \"::\", stringify!(spare0))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).spare1) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(ifi2creq), \"::\", stringify!(spare1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).data) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(ifi2creq), \"::\", stringify!(data))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ifrsskey {\n    pub ifrk_name: [::std::os::raw::c_char; 16usize],\n    pub ifrk_func: u8,\n    pub ifrk_spare0: u8,\n    pub ifrk_keylen: u16,\n    pub ifrk_key: [u8; 128usize],\n}\n#[test]\nfn bindgen_test_layout_ifrsskey() {\n    const UNINIT: ::std::mem::MaybeUninit<ifrsskey> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifrsskey>(),\n        148usize,\n        concat!(\"Size of: \", stringify!(ifrsskey))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifrsskey>(),\n        2usize,\n        concat!(\"Alignment of \", stringify!(ifrsskey))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifrk_name) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(ifrsskey), \"::\", stringify!(ifrk_name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifrk_func) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(ifrsskey), \"::\", stringify!(ifrk_func))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifrk_spare0) as usize - ptr as usize },\n        17usize,\n        concat!(\"Offset of field: \", stringify!(ifrsskey), \"::\", stringify!(ifrk_spare0))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifrk_keylen) as usize - ptr as usize },\n        18usize,\n        concat!(\"Offset of field: \", stringify!(ifrsskey), \"::\", stringify!(ifrk_keylen))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifrk_key) as usize - ptr as usize },\n        20usize,\n        concat!(\"Offset of field: \", stringify!(ifrsskey), \"::\", stringify!(ifrk_key))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ifrsshash {\n    pub ifrh_name: [::std::os::raw::c_char; 16usize],\n    pub ifrh_func: u8,\n    pub ifrh_spare0: u8,\n    pub ifrh_spare1: u16,\n    pub ifrh_types: u32,\n}\n#[test]\nfn bindgen_test_layout_ifrsshash() {\n    const UNINIT: ::std::mem::MaybeUninit<ifrsshash> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifrsshash>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(ifrsshash))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifrsshash>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(ifrsshash))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifrh_name) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(ifrsshash), \"::\", stringify!(ifrh_name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifrh_func) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(ifrsshash), \"::\", stringify!(ifrh_func))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifrh_spare0) as usize - ptr as usize },\n        17usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifrsshash),\n            \"::\",\n            stringify!(ifrh_spare0)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifrh_spare1) as usize - ptr as usize },\n        18usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifrsshash),\n            \"::\",\n            stringify!(ifrh_spare1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifrh_types) as usize - ptr as usize },\n        20usize,\n        concat!(\"Offset of field: \", stringify!(ifrsshash), \"::\", stringify!(ifrh_types))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ifdownreason {\n    pub ifdr_name: [::std::os::raw::c_char; 16usize],\n    pub ifdr_reason: u32,\n    pub ifdr_vendor: u32,\n    pub ifdr_msg: [::std::os::raw::c_char; 64usize],\n}\n#[test]\nfn bindgen_test_layout_ifdownreason() {\n    const UNINIT: ::std::mem::MaybeUninit<ifdownreason> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifdownreason>(),\n        88usize,\n        concat!(\"Size of: \", stringify!(ifdownreason))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifdownreason>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(ifdownreason))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifdr_name) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifdownreason),\n            \"::\",\n            stringify!(ifdr_name)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifdr_reason) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifdownreason),\n            \"::\",\n            stringify!(ifdr_reason)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifdr_vendor) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifdownreason),\n            \"::\",\n            stringify!(ifdr_vendor)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifdr_msg) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifdownreason),\n            \"::\",\n            stringify!(ifdr_msg)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ifnet {\n    _unused: [u8; 0],\n}\npub type if_t = *mut ifnet;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct if_nameindex {\n    pub if_index: ::std::os::raw::c_uint,\n    pub if_name: *mut ::std::os::raw::c_char,\n}\n#[test]\nfn bindgen_test_layout_if_nameindex() {\n    const UNINIT: ::std::mem::MaybeUninit<if_nameindex> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_nameindex>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(if_nameindex))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_nameindex>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(if_nameindex))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).if_index) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_nameindex),\n            \"::\",\n            stringify!(if_index)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).if_name) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(if_nameindex), \"::\", stringify!(if_name))\n    );\n}\nunsafe extern \"C\" {\n    pub fn if_freenameindex(arg1: *mut if_nameindex);\n}\nunsafe extern \"C\" {\n    pub fn if_indextoname(\n        arg1: ::std::os::raw::c_uint,\n        arg2: *mut ::std::os::raw::c_char,\n    ) -> *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn if_nameindex() -> *mut if_nameindex;\n}\nunsafe extern \"C\" {\n    pub fn if_nametoindex(arg1: *const ::std::os::raw::c_char) -> ::std::os::raw::c_uint;\n}\n#[repr(C, packed)]\n#[derive(Debug, Copy, Clone)]\npub struct ether_header {\n    pub ether_dhost: [u_char; 6usize],\n    pub ether_shost: [u_char; 6usize],\n    pub ether_type: u_short,\n}\n#[test]\nfn bindgen_test_layout_ether_header() {\n    const UNINIT: ::std::mem::MaybeUninit<ether_header> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ether_header>(),\n        14usize,\n        concat!(\"Size of: \", stringify!(ether_header))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ether_header>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(ether_header))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ether_dhost) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ether_header),\n            \"::\",\n            stringify!(ether_dhost)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ether_shost) as usize - ptr as usize },\n        6usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ether_header),\n            \"::\",\n            stringify!(ether_shost)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ether_type) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ether_header),\n            \"::\",\n            stringify!(ether_type)\n        )\n    );\n}\n#[repr(C, packed)]\n#[derive(Debug, Copy, Clone)]\npub struct ether_addr {\n    pub octet: [u_char; 6usize],\n}\n#[test]\nfn bindgen_test_layout_ether_addr() {\n    const UNINIT: ::std::mem::MaybeUninit<ether_addr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ether_addr>(),\n        6usize,\n        concat!(\"Size of: \", stringify!(ether_addr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ether_addr>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(ether_addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).octet) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(ether_addr), \"::\", stringify!(octet))\n    );\n}\n#[repr(C, packed)]\n#[derive(Debug, Copy, Clone)]\npub struct ether_vlan_header {\n    pub evl_dhost: [u8; 6usize],\n    pub evl_shost: [u8; 6usize],\n    pub evl_encap_proto: u16,\n    pub evl_tag: u16,\n    pub evl_proto: u16,\n}\n#[test]\nfn bindgen_test_layout_ether_vlan_header() {\n    const UNINIT: ::std::mem::MaybeUninit<ether_vlan_header> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ether_vlan_header>(),\n        18usize,\n        concat!(\"Size of: \", stringify!(ether_vlan_header))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ether_vlan_header>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(ether_vlan_header))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).evl_dhost) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ether_vlan_header),\n            \"::\",\n            stringify!(evl_dhost)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).evl_shost) as usize - ptr as usize },\n        6usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ether_vlan_header),\n            \"::\",\n            stringify!(evl_shost)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).evl_encap_proto) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ether_vlan_header),\n            \"::\",\n            stringify!(evl_encap_proto)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).evl_tag) as usize - ptr as usize },\n        14usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ether_vlan_header),\n            \"::\",\n            stringify!(evl_tag)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).evl_proto) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ether_vlan_header),\n            \"::\",\n            stringify!(evl_proto)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct mbuf {\n    _unused: [u8; 0],\n}\nunsafe extern \"C\" {\n    pub fn ether_bpf_mtap_if(ifp: *mut ifnet, m: *mut mbuf);\n}\nunsafe extern \"C\" {\n    pub fn ether_aton(arg1: *const ::std::os::raw::c_char) -> *mut ether_addr;\n}\nunsafe extern \"C\" {\n    pub fn ether_aton_r(arg1: *const ::std::os::raw::c_char, arg2: *mut ether_addr) -> *mut ether_addr;\n}\nunsafe extern \"C\" {\n    pub fn ether_hostton(arg1: *const ::std::os::raw::c_char, arg2: *mut ether_addr) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn ether_line(\n        arg1: *const ::std::os::raw::c_char,\n        arg2: *mut ether_addr,\n        arg3: *mut ::std::os::raw::c_char,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn ether_ntoa(arg1: *const ether_addr) -> *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn ether_ntoa_r(arg1: *const ether_addr, arg2: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn ether_ntohost(arg1: *mut ::std::os::raw::c_char, arg2: *const ether_addr) -> ::std::os::raw::c_int;\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct radix_node {\n    pub rn_mklist: *mut radix_mask,\n    pub rn_parent: *mut radix_node,\n    pub rn_bit: ::std::os::raw::c_short,\n    pub rn_bmask: ::std::os::raw::c_char,\n    pub rn_flags: u_char,\n    pub rn_u: radix_node__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union radix_node__bindgen_ty_1 {\n    pub rn_leaf: radix_node__bindgen_ty_1__bindgen_ty_1,\n    pub rn_node: radix_node__bindgen_ty_1__bindgen_ty_2,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct radix_node__bindgen_ty_1__bindgen_ty_1 {\n    pub rn_Key: caddr_t,\n    pub rn_Mask: caddr_t,\n    pub rn_Dupedkey: *mut radix_node,\n}\n#[test]\nfn bindgen_test_layout_radix_node__bindgen_ty_1__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<radix_node__bindgen_ty_1__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<radix_node__bindgen_ty_1__bindgen_ty_1>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(radix_node__bindgen_ty_1__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<radix_node__bindgen_ty_1__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(radix_node__bindgen_ty_1__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_Key) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(rn_Key)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_Mask) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(rn_Mask)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_Dupedkey) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(rn_Dupedkey)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct radix_node__bindgen_ty_1__bindgen_ty_2 {\n    pub rn_Off: ::std::os::raw::c_int,\n    pub rn_L: *mut radix_node,\n    pub rn_R: *mut radix_node,\n}\n#[test]\nfn bindgen_test_layout_radix_node__bindgen_ty_1__bindgen_ty_2() {\n    const UNINIT: ::std::mem::MaybeUninit<radix_node__bindgen_ty_1__bindgen_ty_2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<radix_node__bindgen_ty_1__bindgen_ty_2>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(radix_node__bindgen_ty_1__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<radix_node__bindgen_ty_1__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(radix_node__bindgen_ty_1__bindgen_ty_2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_Off) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node__bindgen_ty_1__bindgen_ty_2),\n            \"::\",\n            stringify!(rn_Off)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_L) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node__bindgen_ty_1__bindgen_ty_2),\n            \"::\",\n            stringify!(rn_L)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_R) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node__bindgen_ty_1__bindgen_ty_2),\n            \"::\",\n            stringify!(rn_R)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_radix_node__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<radix_node__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<radix_node__bindgen_ty_1>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(radix_node__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<radix_node__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(radix_node__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_leaf) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node__bindgen_ty_1),\n            \"::\",\n            stringify!(rn_leaf)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_node) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node__bindgen_ty_1),\n            \"::\",\n            stringify!(rn_node)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_radix_node() {\n    const UNINIT: ::std::mem::MaybeUninit<radix_node> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<radix_node>(),\n        48usize,\n        concat!(\"Size of: \", stringify!(radix_node))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<radix_node>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(radix_node))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_mklist) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(radix_node), \"::\", stringify!(rn_mklist))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_parent) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(radix_node), \"::\", stringify!(rn_parent))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_bit) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(radix_node), \"::\", stringify!(rn_bit))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_bmask) as usize - ptr as usize },\n        18usize,\n        concat!(\"Offset of field: \", stringify!(radix_node), \"::\", stringify!(rn_bmask))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_flags) as usize - ptr as usize },\n        19usize,\n        concat!(\"Offset of field: \", stringify!(radix_node), \"::\", stringify!(rn_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_u) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(radix_node), \"::\", stringify!(rn_u))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct radix_mask {\n    pub rm_bit: ::std::os::raw::c_short,\n    pub rm_unused: ::std::os::raw::c_char,\n    pub rm_flags: u_char,\n    pub rm_mklist: *mut radix_mask,\n    pub rm_rmu: radix_mask__bindgen_ty_1,\n    pub rm_refs: ::std::os::raw::c_int,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union radix_mask__bindgen_ty_1 {\n    pub rmu_mask: caddr_t,\n    pub rmu_leaf: *mut radix_node,\n}\n#[test]\nfn bindgen_test_layout_radix_mask__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<radix_mask__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<radix_mask__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(radix_mask__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<radix_mask__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(radix_mask__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmu_mask) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_mask__bindgen_ty_1),\n            \"::\",\n            stringify!(rmu_mask)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmu_leaf) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_mask__bindgen_ty_1),\n            \"::\",\n            stringify!(rmu_leaf)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_radix_mask() {\n    const UNINIT: ::std::mem::MaybeUninit<radix_mask> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<radix_mask>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(radix_mask))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<radix_mask>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(radix_mask))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rm_bit) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(radix_mask), \"::\", stringify!(rm_bit))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rm_unused) as usize - ptr as usize },\n        2usize,\n        concat!(\"Offset of field: \", stringify!(radix_mask), \"::\", stringify!(rm_unused))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rm_flags) as usize - ptr as usize },\n        3usize,\n        concat!(\"Offset of field: \", stringify!(radix_mask), \"::\", stringify!(rm_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rm_mklist) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(radix_mask), \"::\", stringify!(rm_mklist))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rm_rmu) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(radix_mask), \"::\", stringify!(rm_rmu))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rm_refs) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(radix_mask), \"::\", stringify!(rm_refs))\n    );\n}\npub type walktree_f_t = ::std::option::Option<\n    unsafe extern \"C\" fn(arg1: *mut radix_node, arg2: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int,\n>;\npub type rn_matchaddr_f_t = ::std::option::Option<\n    unsafe extern \"C\" fn(v: *const ::std::os::raw::c_void, head: *mut radix_head) -> *mut radix_node,\n>;\npub type rn_addaddr_f_t = ::std::option::Option<\n    unsafe extern \"C\" fn(\n        v: *mut ::std::os::raw::c_void,\n        mask: *const ::std::os::raw::c_void,\n        head: *mut radix_head,\n        nodes: *mut radix_node,\n    ) -> *mut radix_node,\n>;\npub type rn_deladdr_f_t = ::std::option::Option<\n    unsafe extern \"C\" fn(\n        v: *const ::std::os::raw::c_void,\n        mask: *const ::std::os::raw::c_void,\n        head: *mut radix_head,\n    ) -> *mut radix_node,\n>;\npub type rn_lookup_f_t = ::std::option::Option<\n    unsafe extern \"C\" fn(\n        v: *const ::std::os::raw::c_void,\n        mask: *const ::std::os::raw::c_void,\n        head: *mut radix_head,\n    ) -> *mut radix_node,\n>;\npub type rn_walktree_t = ::std::option::Option<\n    unsafe extern \"C\" fn(\n        head: *mut radix_head,\n        f: walktree_f_t,\n        w: *mut ::std::os::raw::c_void,\n    ) -> ::std::os::raw::c_int,\n>;\npub type rn_walktree_from_t = ::std::option::Option<\n    unsafe extern \"C\" fn(\n        head: *mut radix_head,\n        a: *mut ::std::os::raw::c_void,\n        m: *mut ::std::os::raw::c_void,\n        f: walktree_f_t,\n        w: *mut ::std::os::raw::c_void,\n    ) -> ::std::os::raw::c_int,\n>;\npub type rn_close_t = ::std::option::Option<unsafe extern \"C\" fn(rn: *mut radix_node, head: *mut radix_head)>;\nunsafe extern \"C\" {\n    pub fn rn_nextprefix(rn: *mut radix_node) -> *mut radix_node;\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct radix_head {\n    pub rnh_treetop: *mut radix_node,\n    pub rnh_masks: *mut radix_mask_head,\n}\n#[test]\nfn bindgen_test_layout_radix_head() {\n    const UNINIT: ::std::mem::MaybeUninit<radix_head> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<radix_head>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(radix_head))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<radix_head>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(radix_head))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_treetop) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_head),\n            \"::\",\n            stringify!(rnh_treetop)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_masks) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(radix_head), \"::\", stringify!(rnh_masks))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct radix_node_head {\n    pub rh: radix_head,\n    pub rnh_matchaddr: rn_matchaddr_f_t,\n    pub rnh_addaddr: rn_addaddr_f_t,\n    pub rnh_deladdr: rn_deladdr_f_t,\n    pub rnh_lookup: rn_lookup_f_t,\n    pub rnh_walktree: rn_walktree_t,\n    pub rnh_walktree_from: rn_walktree_from_t,\n    pub rnh_close: rn_close_t,\n    pub rnh_nodes: [radix_node; 3usize],\n}\n#[test]\nfn bindgen_test_layout_radix_node_head() {\n    const UNINIT: ::std::mem::MaybeUninit<radix_node_head> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<radix_node_head>(),\n        216usize,\n        concat!(\"Size of: \", stringify!(radix_node_head))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<radix_node_head>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(radix_node_head))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rh) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(radix_node_head), \"::\", stringify!(rh))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_matchaddr) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_matchaddr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_addaddr) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_addaddr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_deladdr) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_deladdr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_lookup) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_lookup)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_walktree) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_walktree)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_walktree_from) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_walktree_from)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_close) as usize - ptr as usize },\n        64usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_close)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_nodes) as usize - ptr as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_nodes)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct radix_mask_head {\n    pub head: radix_head,\n    pub mask_nodes: [radix_node; 3usize],\n}\n#[test]\nfn bindgen_test_layout_radix_mask_head() {\n    const UNINIT: ::std::mem::MaybeUninit<radix_mask_head> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<radix_mask_head>(),\n        160usize,\n        concat!(\"Size of: \", stringify!(radix_mask_head))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<radix_mask_head>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(radix_mask_head))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).head) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(radix_mask_head), \"::\", stringify!(head))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mask_nodes) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_mask_head),\n            \"::\",\n            stringify!(mask_nodes)\n        )\n    );\n}\nunsafe extern \"C\" {\n    pub fn rn_inithead_internal(rh: *mut radix_head, base_nodes: *mut radix_node, off: ::std::os::raw::c_int);\n}\nunsafe extern \"C\" {\n    pub fn rn_inithead(arg1: *mut *mut ::std::os::raw::c_void, arg2: ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn rn_detachhead(arg1: *mut *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn rn_refines(\n        arg1: *const ::std::os::raw::c_void,\n        arg2: *const ::std::os::raw::c_void,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn rn_addroute(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: *const ::std::os::raw::c_void,\n        arg3: *mut radix_head,\n        arg4: *mut radix_node,\n    ) -> *mut radix_node;\n}\nunsafe extern \"C\" {\n    pub fn rn_delete(\n        arg1: *const ::std::os::raw::c_void,\n        arg2: *const ::std::os::raw::c_void,\n        arg3: *mut radix_head,\n    ) -> *mut radix_node;\n}\nunsafe extern \"C\" {\n    pub fn rn_lookup(\n        v_arg: *const ::std::os::raw::c_void,\n        m_arg: *const ::std::os::raw::c_void,\n        head: *mut radix_head,\n    ) -> *mut radix_node;\n}\nunsafe extern \"C\" {\n    pub fn rn_match(arg1: *const ::std::os::raw::c_void, arg2: *mut radix_head) -> *mut radix_node;\n}\nunsafe extern \"C\" {\n    pub fn rn_walktree_from(\n        h: *mut radix_head,\n        a: *mut ::std::os::raw::c_void,\n        m: *mut ::std::os::raw::c_void,\n        f: walktree_f_t,\n        w: *mut ::std::os::raw::c_void,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn rn_walktree(\n        arg1: *mut radix_head,\n        arg2: walktree_f_t,\n        arg3: *mut ::std::os::raw::c_void,\n    ) -> ::std::os::raw::c_int;\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct in_addr {\n    pub s_addr: in_addr_t,\n}\n#[test]\nfn bindgen_test_layout_in_addr() {\n    const UNINIT: ::std::mem::MaybeUninit<in_addr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<in_addr>(),\n        4usize,\n        concat!(\"Size of: \", stringify!(in_addr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<in_addr>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(in_addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).s_addr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(in_addr), \"::\", stringify!(s_addr))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sockaddr_in {\n    pub sin_len: u8,\n    pub sin_family: sa_family_t,\n    pub sin_port: in_port_t,\n    pub sin_addr: in_addr,\n    pub sin_zero: [::std::os::raw::c_char; 8usize],\n}\n#[test]\nfn bindgen_test_layout_sockaddr_in() {\n    const UNINIT: ::std::mem::MaybeUninit<sockaddr_in> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sockaddr_in>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(sockaddr_in))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sockaddr_in>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(sockaddr_in))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin_len) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr_in), \"::\", stringify!(sin_len))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin_family) as usize - ptr as usize },\n        1usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_in),\n            \"::\",\n            stringify!(sin_family)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin_port) as usize - ptr as usize },\n        2usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr_in), \"::\", stringify!(sin_port))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin_addr) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr_in), \"::\", stringify!(sin_addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin_zero) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr_in), \"::\", stringify!(sin_zero))\n    );\n}\nunsafe extern \"C\" {\n    pub fn htonl(arg1: u32) -> u32;\n}\nunsafe extern \"C\" {\n    pub fn htons(arg1: u16) -> u16;\n}\nunsafe extern \"C\" {\n    pub fn ntohl(arg1: u32) -> u32;\n}\nunsafe extern \"C\" {\n    pub fn ntohs(arg1: u16) -> u16;\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ip_mreq {\n    pub imr_multiaddr: in_addr,\n    pub imr_interface: in_addr,\n}\n#[test]\nfn bindgen_test_layout_ip_mreq() {\n    const UNINIT: ::std::mem::MaybeUninit<ip_mreq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ip_mreq>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(ip_mreq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ip_mreq>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(ip_mreq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).imr_multiaddr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ip_mreq),\n            \"::\",\n            stringify!(imr_multiaddr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).imr_interface) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ip_mreq),\n            \"::\",\n            stringify!(imr_interface)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ip_mreqn {\n    pub imr_multiaddr: in_addr,\n    pub imr_address: in_addr,\n    pub imr_ifindex: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_ip_mreqn() {\n    const UNINIT: ::std::mem::MaybeUninit<ip_mreqn> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ip_mreqn>(),\n        12usize,\n        concat!(\"Size of: \", stringify!(ip_mreqn))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ip_mreqn>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(ip_mreqn))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).imr_multiaddr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ip_mreqn),\n            \"::\",\n            stringify!(imr_multiaddr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).imr_address) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(ip_mreqn), \"::\", stringify!(imr_address))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).imr_ifindex) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(ip_mreqn), \"::\", stringify!(imr_ifindex))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ip_mreq_source {\n    pub imr_multiaddr: in_addr,\n    pub imr_sourceaddr: in_addr,\n    pub imr_interface: in_addr,\n}\n#[test]\nfn bindgen_test_layout_ip_mreq_source() {\n    const UNINIT: ::std::mem::MaybeUninit<ip_mreq_source> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ip_mreq_source>(),\n        12usize,\n        concat!(\"Size of: \", stringify!(ip_mreq_source))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ip_mreq_source>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(ip_mreq_source))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).imr_multiaddr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ip_mreq_source),\n            \"::\",\n            stringify!(imr_multiaddr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).imr_sourceaddr) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ip_mreq_source),\n            \"::\",\n            stringify!(imr_sourceaddr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).imr_interface) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ip_mreq_source),\n            \"::\",\n            stringify!(imr_interface)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct group_req {\n    pub gr_interface: u32,\n    pub gr_group: sockaddr_storage,\n}\n#[test]\nfn bindgen_test_layout_group_req() {\n    const UNINIT: ::std::mem::MaybeUninit<group_req> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<group_req>(),\n        136usize,\n        concat!(\"Size of: \", stringify!(group_req))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<group_req>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(group_req))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).gr_interface) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(group_req),\n            \"::\",\n            stringify!(gr_interface)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).gr_group) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(group_req), \"::\", stringify!(gr_group))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct group_source_req {\n    pub gsr_interface: u32,\n    pub gsr_group: sockaddr_storage,\n    pub gsr_source: sockaddr_storage,\n}\n#[test]\nfn bindgen_test_layout_group_source_req() {\n    const UNINIT: ::std::mem::MaybeUninit<group_source_req> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<group_source_req>(),\n        264usize,\n        concat!(\"Size of: \", stringify!(group_source_req))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<group_source_req>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(group_source_req))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).gsr_interface) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(group_source_req),\n            \"::\",\n            stringify!(gsr_interface)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).gsr_group) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(group_source_req),\n            \"::\",\n            stringify!(gsr_group)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).gsr_source) as usize - ptr as usize },\n        136usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(group_source_req),\n            \"::\",\n            stringify!(gsr_source)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __msfilterreq {\n    pub msfr_ifindex: u32,\n    pub msfr_fmode: u32,\n    pub msfr_nsrcs: u32,\n    pub msfr_group: sockaddr_storage,\n    pub msfr_srcs: *mut sockaddr_storage,\n}\n#[test]\nfn bindgen_test_layout___msfilterreq() {\n    const UNINIT: ::std::mem::MaybeUninit<__msfilterreq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__msfilterreq>(),\n        152usize,\n        concat!(\"Size of: \", stringify!(__msfilterreq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__msfilterreq>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__msfilterreq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msfr_ifindex) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__msfilterreq),\n            \"::\",\n            stringify!(msfr_ifindex)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msfr_fmode) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__msfilterreq),\n            \"::\",\n            stringify!(msfr_fmode)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msfr_nsrcs) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__msfilterreq),\n            \"::\",\n            stringify!(msfr_nsrcs)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msfr_group) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__msfilterreq),\n            \"::\",\n            stringify!(msfr_group)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msfr_srcs) as usize - ptr as usize },\n        144usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__msfilterreq),\n            \"::\",\n            stringify!(msfr_srcs)\n        )\n    );\n}\nunsafe extern \"C\" {\n    pub fn setipv4sourcefilter(\n        arg1: ::std::os::raw::c_int,\n        arg2: in_addr,\n        arg3: in_addr,\n        arg4: u32,\n        arg5: u32,\n        arg6: *mut in_addr,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn getipv4sourcefilter(\n        arg1: ::std::os::raw::c_int,\n        arg2: in_addr,\n        arg3: in_addr,\n        arg4: *mut u32,\n        arg5: *mut u32,\n        arg6: *mut in_addr,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn setsourcefilter(\n        arg1: ::std::os::raw::c_int,\n        arg2: u32,\n        arg3: *mut sockaddr,\n        arg4: socklen_t,\n        arg5: u32,\n        arg6: u32,\n        arg7: *mut sockaddr_storage,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn getsourcefilter(\n        arg1: ::std::os::raw::c_int,\n        arg2: u32,\n        arg3: *mut sockaddr,\n        arg4: socklen_t,\n        arg5: *mut u32,\n        arg6: *mut u32,\n        arg7: *mut sockaddr_storage,\n    ) -> ::std::os::raw::c_int;\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct in6_addr {\n    pub __u6_addr: in6_addr__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union in6_addr__bindgen_ty_1 {\n    pub __u6_addr8: [u8; 16usize],\n    pub __u6_addr16: [u16; 8usize],\n    pub __u6_addr32: [u32; 4usize],\n}\n#[test]\nfn bindgen_test_layout_in6_addr__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<in6_addr__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<in6_addr__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(in6_addr__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<in6_addr__bindgen_ty_1>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(in6_addr__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__u6_addr8) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(in6_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(__u6_addr8)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__u6_addr16) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(in6_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(__u6_addr16)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__u6_addr32) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(in6_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(__u6_addr32)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_in6_addr() {\n    const UNINIT: ::std::mem::MaybeUninit<in6_addr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<in6_addr>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(in6_addr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<in6_addr>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(in6_addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__u6_addr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(in6_addr), \"::\", stringify!(__u6_addr))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct sockaddr_in6 {\n    pub sin6_len: u8,\n    pub sin6_family: sa_family_t,\n    pub sin6_port: in_port_t,\n    pub sin6_flowinfo: u32,\n    pub sin6_addr: in6_addr,\n    pub sin6_scope_id: u32,\n}\n#[test]\nfn bindgen_test_layout_sockaddr_in6() {\n    const UNINIT: ::std::mem::MaybeUninit<sockaddr_in6> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sockaddr_in6>(),\n        28usize,\n        concat!(\"Size of: \", stringify!(sockaddr_in6))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sockaddr_in6>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(sockaddr_in6))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin6_len) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_in6),\n            \"::\",\n            stringify!(sin6_len)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin6_family) as usize - ptr as usize },\n        1usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_in6),\n            \"::\",\n            stringify!(sin6_family)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin6_port) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_in6),\n            \"::\",\n            stringify!(sin6_port)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin6_flowinfo) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_in6),\n            \"::\",\n            stringify!(sin6_flowinfo)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin6_addr) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_in6),\n            \"::\",\n            stringify!(sin6_addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin6_scope_id) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_in6),\n            \"::\",\n            stringify!(sin6_scope_id)\n        )\n    );\n}\nunsafe extern \"C\" {\n    pub static in6addr_any: in6_addr;\n}\nunsafe extern \"C\" {\n    pub static in6addr_loopback: in6_addr;\n}\nunsafe extern \"C\" {\n    pub static in6addr_nodelocal_allnodes: in6_addr;\n}\nunsafe extern \"C\" {\n    pub static in6addr_linklocal_allnodes: in6_addr;\n}\nunsafe extern \"C\" {\n    pub static in6addr_linklocal_allrouters: in6_addr;\n}\nunsafe extern \"C\" {\n    pub static in6addr_linklocal_allv2routers: in6_addr;\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct nhop_object {\n    _unused: [u8; 0],\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct route_in6 {\n    pub ro_nh: *mut nhop_object,\n    pub ro_lle: *mut llentry,\n    pub ro_prepend: *mut ::std::os::raw::c_char,\n    pub ro_plen: u16,\n    pub ro_flags: u16,\n    pub ro_mtu: u16,\n    pub spare: u16,\n    pub ro_dst: sockaddr_in6,\n}\n#[test]\nfn bindgen_test_layout_route_in6() {\n    const UNINIT: ::std::mem::MaybeUninit<route_in6> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<route_in6>(),\n        64usize,\n        concat!(\"Size of: \", stringify!(route_in6))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<route_in6>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(route_in6))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ro_nh) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(route_in6), \"::\", stringify!(ro_nh))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ro_lle) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(route_in6), \"::\", stringify!(ro_lle))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ro_prepend) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(route_in6), \"::\", stringify!(ro_prepend))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ro_plen) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(route_in6), \"::\", stringify!(ro_plen))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ro_flags) as usize - ptr as usize },\n        26usize,\n        concat!(\"Offset of field: \", stringify!(route_in6), \"::\", stringify!(ro_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ro_mtu) as usize - ptr as usize },\n        28usize,\n        concat!(\"Offset of field: \", stringify!(route_in6), \"::\", stringify!(ro_mtu))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).spare) as usize - ptr as usize },\n        30usize,\n        concat!(\"Offset of field: \", stringify!(route_in6), \"::\", stringify!(spare))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ro_dst) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(route_in6), \"::\", stringify!(ro_dst))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct ipv6_mreq {\n    pub ipv6mr_multiaddr: in6_addr,\n    pub ipv6mr_interface: ::std::os::raw::c_uint,\n}\n#[test]\nfn bindgen_test_layout_ipv6_mreq() {\n    const UNINIT: ::std::mem::MaybeUninit<ipv6_mreq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ipv6_mreq>(),\n        20usize,\n        concat!(\"Size of: \", stringify!(ipv6_mreq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ipv6_mreq>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(ipv6_mreq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ipv6mr_multiaddr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ipv6_mreq),\n            \"::\",\n            stringify!(ipv6mr_multiaddr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ipv6mr_interface) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ipv6_mreq),\n            \"::\",\n            stringify!(ipv6mr_interface)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct in6_pktinfo {\n    pub ipi6_addr: in6_addr,\n    pub ipi6_ifindex: ::std::os::raw::c_uint,\n}\n#[test]\nfn bindgen_test_layout_in6_pktinfo() {\n    const UNINIT: ::std::mem::MaybeUninit<in6_pktinfo> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<in6_pktinfo>(),\n        20usize,\n        concat!(\"Size of: \", stringify!(in6_pktinfo))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<in6_pktinfo>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(in6_pktinfo))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ipi6_addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(in6_pktinfo),\n            \"::\",\n            stringify!(ipi6_addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ipi6_ifindex) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(in6_pktinfo),\n            \"::\",\n            stringify!(ipi6_ifindex)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct ip6_mtuinfo {\n    pub ip6m_addr: sockaddr_in6,\n    pub ip6m_mtu: u32,\n}\n#[test]\nfn bindgen_test_layout_ip6_mtuinfo() {\n    const UNINIT: ::std::mem::MaybeUninit<ip6_mtuinfo> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ip6_mtuinfo>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(ip6_mtuinfo))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ip6_mtuinfo>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(ip6_mtuinfo))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ip6m_addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ip6_mtuinfo),\n            \"::\",\n            stringify!(ip6m_addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ip6m_mtu) as usize - ptr as usize },\n        28usize,\n        concat!(\"Offset of field: \", stringify!(ip6_mtuinfo), \"::\", stringify!(ip6m_mtu))\n    );\n}\nunsafe extern \"C\" {\n    pub fn inet6_option_space(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_option_init(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: *mut *mut cmsghdr,\n        arg3: ::std::os::raw::c_int,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_option_append(\n        arg1: *mut cmsghdr,\n        arg2: *const u8,\n        arg3: ::std::os::raw::c_int,\n        arg4: ::std::os::raw::c_int,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_option_alloc(\n        arg1: *mut cmsghdr,\n        arg2: ::std::os::raw::c_int,\n        arg3: ::std::os::raw::c_int,\n        arg4: ::std::os::raw::c_int,\n    ) -> *mut u8;\n}\nunsafe extern \"C\" {\n    pub fn inet6_option_next(arg1: *const cmsghdr, arg2: *mut *mut u8) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_option_find(\n        arg1: *const cmsghdr,\n        arg2: *mut *mut u8,\n        arg3: ::std::os::raw::c_int,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rthdr_space(arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int) -> usize;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rthdr_init(arg1: *mut ::std::os::raw::c_void, arg2: ::std::os::raw::c_int) -> *mut cmsghdr;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rthdr_add(\n        arg1: *mut cmsghdr,\n        arg2: *const in6_addr,\n        arg3: ::std::os::raw::c_uint,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rthdr_lasthop(arg1: *mut cmsghdr, arg2: ::std::os::raw::c_uint) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rthdr_segments(arg1: *const cmsghdr) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rthdr_getaddr(arg1: *mut cmsghdr, arg2: ::std::os::raw::c_int) -> *mut in6_addr;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rthdr_getflags(arg1: *const cmsghdr, arg2: ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_opt_init(arg1: *mut ::std::os::raw::c_void, arg2: socklen_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_opt_append(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: socklen_t,\n        arg3: ::std::os::raw::c_int,\n        arg4: u8,\n        arg5: socklen_t,\n        arg6: u8,\n        arg7: *mut *mut ::std::os::raw::c_void,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_opt_finish(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: socklen_t,\n        arg3: ::std::os::raw::c_int,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_opt_set_val(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: ::std::os::raw::c_int,\n        arg3: *mut ::std::os::raw::c_void,\n        arg4: socklen_t,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_opt_next(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: socklen_t,\n        arg3: ::std::os::raw::c_int,\n        arg4: *mut u8,\n        arg5: *mut socklen_t,\n        arg6: *mut *mut ::std::os::raw::c_void,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_opt_find(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: socklen_t,\n        arg3: ::std::os::raw::c_int,\n        arg4: u8,\n        arg5: *mut socklen_t,\n        arg6: *mut *mut ::std::os::raw::c_void,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_opt_get_val(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: ::std::os::raw::c_int,\n        arg3: *mut ::std::os::raw::c_void,\n        arg4: socklen_t,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rth_space(arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int) -> socklen_t;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rth_init(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: socklen_t,\n        arg3: ::std::os::raw::c_int,\n        arg4: ::std::os::raw::c_int,\n    ) -> *mut ::std::os::raw::c_void;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rth_add(arg1: *mut ::std::os::raw::c_void, arg2: *const in6_addr) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rth_reverse(\n        arg1: *const ::std::os::raw::c_void,\n        arg2: *mut ::std::os::raw::c_void,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rth_segments(arg1: *const ::std::os::raw::c_void) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rth_getaddr(arg1: *const ::std::os::raw::c_void, arg2: ::std::os::raw::c_int) -> *mut in6_addr;\n}\npub const PF_INOUT: _bindgen_ty_1 = 0;\npub const PF_IN: _bindgen_ty_1 = 1;\npub const PF_OUT: _bindgen_ty_1 = 2;\npub type _bindgen_ty_1 = ::std::os::raw::c_uint;\npub const PF_PASS: _bindgen_ty_2 = 0;\npub const PF_DROP: _bindgen_ty_2 = 1;\npub const PF_SCRUB: _bindgen_ty_2 = 2;\npub const PF_NOSCRUB: _bindgen_ty_2 = 3;\npub const PF_NAT: _bindgen_ty_2 = 4;\npub const PF_NONAT: _bindgen_ty_2 = 5;\npub const PF_BINAT: _bindgen_ty_2 = 6;\npub const PF_NOBINAT: _bindgen_ty_2 = 7;\npub const PF_RDR: _bindgen_ty_2 = 8;\npub const PF_NORDR: _bindgen_ty_2 = 9;\npub const PF_SYNPROXY_DROP: _bindgen_ty_2 = 10;\npub const PF_DEFER: _bindgen_ty_2 = 11;\npub const PF_MATCH: _bindgen_ty_2 = 12;\npub type _bindgen_ty_2 = ::std::os::raw::c_uint;\npub const PF_RULESET_SCRUB: _bindgen_ty_3 = 0;\npub const PF_RULESET_FILTER: _bindgen_ty_3 = 1;\npub const PF_RULESET_NAT: _bindgen_ty_3 = 2;\npub const PF_RULESET_BINAT: _bindgen_ty_3 = 3;\npub const PF_RULESET_RDR: _bindgen_ty_3 = 4;\npub const PF_RULESET_MAX: _bindgen_ty_3 = 5;\npub type _bindgen_ty_3 = ::std::os::raw::c_uint;\npub const PF_OP_NONE: _bindgen_ty_4 = 0;\npub const PF_OP_IRG: _bindgen_ty_4 = 1;\npub const PF_OP_EQ: _bindgen_ty_4 = 2;\npub const PF_OP_NE: _bindgen_ty_4 = 3;\npub const PF_OP_LT: _bindgen_ty_4 = 4;\npub const PF_OP_LE: _bindgen_ty_4 = 5;\npub const PF_OP_GT: _bindgen_ty_4 = 6;\npub const PF_OP_GE: _bindgen_ty_4 = 7;\npub const PF_OP_XRG: _bindgen_ty_4 = 8;\npub const PF_OP_RRG: _bindgen_ty_4 = 9;\npub type _bindgen_ty_4 = ::std::os::raw::c_uint;\npub const PF_DEBUG_NONE: _bindgen_ty_5 = 0;\npub const PF_DEBUG_URGENT: _bindgen_ty_5 = 1;\npub const PF_DEBUG_MISC: _bindgen_ty_5 = 2;\npub const PF_DEBUG_NOISY: _bindgen_ty_5 = 3;\npub type _bindgen_ty_5 = ::std::os::raw::c_uint;\npub const PF_CHANGE_NONE: _bindgen_ty_6 = 0;\npub const PF_CHANGE_ADD_HEAD: _bindgen_ty_6 = 1;\npub const PF_CHANGE_ADD_TAIL: _bindgen_ty_6 = 2;\npub const PF_CHANGE_ADD_BEFORE: _bindgen_ty_6 = 3;\npub const PF_CHANGE_ADD_AFTER: _bindgen_ty_6 = 4;\npub const PF_CHANGE_REMOVE: _bindgen_ty_6 = 5;\npub const PF_CHANGE_GET_TICKET: _bindgen_ty_6 = 6;\npub type _bindgen_ty_6 = ::std::os::raw::c_uint;\npub const PF_GET_NONE: _bindgen_ty_7 = 0;\npub const PF_GET_CLR_CNTR: _bindgen_ty_7 = 1;\npub type _bindgen_ty_7 = ::std::os::raw::c_uint;\npub const PF_SK_WIRE: _bindgen_ty_8 = 0;\npub const PF_SK_STACK: _bindgen_ty_8 = 1;\npub const PF_SK_BOTH: _bindgen_ty_8 = 2;\npub type _bindgen_ty_8 = ::std::os::raw::c_uint;\npub const PF_PEER_SRC: _bindgen_ty_9 = 0;\npub const PF_PEER_DST: _bindgen_ty_9 = 1;\npub const PF_PEER_BOTH: _bindgen_ty_9 = 2;\npub type _bindgen_ty_9 = ::std::os::raw::c_uint;\npub const PFTM_TCP_FIRST_PACKET: _bindgen_ty_10 = 0;\npub const PFTM_TCP_OPENING: _bindgen_ty_10 = 1;\npub const PFTM_TCP_ESTABLISHED: _bindgen_ty_10 = 2;\npub const PFTM_TCP_CLOSING: _bindgen_ty_10 = 3;\npub const PFTM_TCP_FIN_WAIT: _bindgen_ty_10 = 4;\npub const PFTM_TCP_CLOSED: _bindgen_ty_10 = 5;\npub const PFTM_UDP_FIRST_PACKET: _bindgen_ty_10 = 6;\npub const PFTM_UDP_SINGLE: _bindgen_ty_10 = 7;\npub const PFTM_UDP_MULTIPLE: _bindgen_ty_10 = 8;\npub const PFTM_ICMP_FIRST_PACKET: _bindgen_ty_10 = 9;\npub const PFTM_ICMP_ERROR_REPLY: _bindgen_ty_10 = 10;\npub const PFTM_OTHER_FIRST_PACKET: _bindgen_ty_10 = 11;\npub const PFTM_OTHER_SINGLE: _bindgen_ty_10 = 12;\npub const PFTM_OTHER_MULTIPLE: _bindgen_ty_10 = 13;\npub const PFTM_FRAG: _bindgen_ty_10 = 14;\npub const PFTM_INTERVAL: _bindgen_ty_10 = 15;\npub const PFTM_ADAPTIVE_START: _bindgen_ty_10 = 16;\npub const PFTM_ADAPTIVE_END: _bindgen_ty_10 = 17;\npub const PFTM_SRC_NODE: _bindgen_ty_10 = 18;\npub const PFTM_TS_DIFF: _bindgen_ty_10 = 19;\npub const PFTM_MAX: _bindgen_ty_10 = 20;\npub const PFTM_PURGE: _bindgen_ty_10 = 21;\npub const PFTM_UNLINKED: _bindgen_ty_10 = 22;\npub type _bindgen_ty_10 = ::std::os::raw::c_uint;\npub const PF_NOPFROUTE: _bindgen_ty_11 = 0;\npub const PF_FASTROUTE: _bindgen_ty_11 = 1;\npub const PF_ROUTETO: _bindgen_ty_11 = 2;\npub const PF_DUPTO: _bindgen_ty_11 = 3;\npub const PF_REPLYTO: _bindgen_ty_11 = 4;\npub type _bindgen_ty_11 = ::std::os::raw::c_uint;\npub const PF_LIMIT_STATES: _bindgen_ty_12 = 0;\npub const PF_LIMIT_SRC_NODES: _bindgen_ty_12 = 1;\npub const PF_LIMIT_FRAGS: _bindgen_ty_12 = 2;\npub const PF_LIMIT_TABLE_ENTRIES: _bindgen_ty_12 = 3;\npub const PF_LIMIT_MAX: _bindgen_ty_12 = 4;\npub type _bindgen_ty_12 = ::std::os::raw::c_uint;\npub const PF_POOL_NONE: _bindgen_ty_13 = 0;\npub const PF_POOL_BITMASK: _bindgen_ty_13 = 1;\npub const PF_POOL_RANDOM: _bindgen_ty_13 = 2;\npub const PF_POOL_SRCHASH: _bindgen_ty_13 = 3;\npub const PF_POOL_ROUNDROBIN: _bindgen_ty_13 = 4;\npub type _bindgen_ty_13 = ::std::os::raw::c_uint;\npub const PF_ADDR_ADDRMASK: _bindgen_ty_14 = 0;\npub const PF_ADDR_NOROUTE: _bindgen_ty_14 = 1;\npub const PF_ADDR_DYNIFTL: _bindgen_ty_14 = 2;\npub const PF_ADDR_TABLE: _bindgen_ty_14 = 3;\npub const PF_ADDR_URPFFAILED: _bindgen_ty_14 = 4;\npub const PF_ADDR_RANGE: _bindgen_ty_14 = 5;\npub type _bindgen_ty_14 = ::std::os::raw::c_uint;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_nv {\n    pub data: *mut ::std::os::raw::c_void,\n    pub len: usize,\n    pub size: usize,\n}\n#[test]\nfn bindgen_test_layout_pfioc_nv() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_nv> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_nv>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(pfioc_nv))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_nv>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_nv))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).data) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_nv), \"::\", stringify!(data))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).len) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_nv), \"::\", stringify!(len))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).size) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_nv), \"::\", stringify!(size))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfi_kif_cmp {\n    pub pfik_name: [::std::os::raw::c_char; 16usize],\n}\n#[test]\nfn bindgen_test_layout_pfi_kif_cmp() {\n    const UNINIT: ::std::mem::MaybeUninit<pfi_kif_cmp> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfi_kif_cmp>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pfi_kif_cmp))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfi_kif_cmp>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(pfi_kif_cmp))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_name) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfi_kif_cmp),\n            \"::\",\n            stringify!(pfik_name)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfi_kif {\n    pub pfik_name: [::std::os::raw::c_char; 16usize],\n    pub __bindgen_anon_1: pfi_kif__bindgen_ty_1,\n    pub pfik_packets: [[[u_int64_t; 2usize]; 2usize]; 2usize],\n    pub pfik_bytes: [[[u_int64_t; 2usize]; 2usize]; 2usize],\n    pub pfik_tzero: u_int32_t,\n    pub pfik_flags: u_int,\n    pub pfik_ifp: *mut ifnet,\n    pub pfik_group: *mut ifg_group,\n    pub pfik_rulerefs: u_int,\n    pub pfik_dynaddrs: pfi_kif__bindgen_ty_2,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pfi_kif__bindgen_ty_1 {\n    pub pfik_tree: pfi_kif__bindgen_ty_1__bindgen_ty_1,\n    pub pfik_list: pfi_kif__bindgen_ty_1__bindgen_ty_2,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfi_kif__bindgen_ty_1__bindgen_ty_1 {\n    pub rbe_link: [*mut pfi_kif; 3usize],\n}\n#[test]\nfn bindgen_test_layout_pfi_kif__bindgen_ty_1__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pfi_kif__bindgen_ty_1__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfi_kif__bindgen_ty_1__bindgen_ty_1>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(pfi_kif__bindgen_ty_1__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfi_kif__bindgen_ty_1__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfi_kif__bindgen_ty_1__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_link) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfi_kif__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(rbe_link)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfi_kif__bindgen_ty_1__bindgen_ty_2 {\n    pub le_next: *mut pfi_kif,\n    pub le_prev: *mut *mut pfi_kif,\n}\n#[test]\nfn bindgen_test_layout_pfi_kif__bindgen_ty_1__bindgen_ty_2() {\n    const UNINIT: ::std::mem::MaybeUninit<pfi_kif__bindgen_ty_1__bindgen_ty_2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfi_kif__bindgen_ty_1__bindgen_ty_2>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pfi_kif__bindgen_ty_1__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfi_kif__bindgen_ty_1__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfi_kif__bindgen_ty_1__bindgen_ty_2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).le_next) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfi_kif__bindgen_ty_1__bindgen_ty_2),\n            \"::\",\n            stringify!(le_next)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).le_prev) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfi_kif__bindgen_ty_1__bindgen_ty_2),\n            \"::\",\n            stringify!(le_prev)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pfi_kif__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pfi_kif__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfi_kif__bindgen_ty_1>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(pfi_kif__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfi_kif__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfi_kif__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_tree) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfi_kif__bindgen_ty_1),\n            \"::\",\n            stringify!(pfik_tree)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_list) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfi_kif__bindgen_ty_1),\n            \"::\",\n            stringify!(pfik_list)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfi_kif__bindgen_ty_2 {\n    pub tqh_first: *mut pfi_dynaddr,\n    pub tqh_last: *mut *mut pfi_dynaddr,\n}\n#[test]\nfn bindgen_test_layout_pfi_kif__bindgen_ty_2() {\n    const UNINIT: ::std::mem::MaybeUninit<pfi_kif__bindgen_ty_2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfi_kif__bindgen_ty_2>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pfi_kif__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfi_kif__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfi_kif__bindgen_ty_2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqh_first) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfi_kif__bindgen_ty_2),\n            \"::\",\n            stringify!(tqh_first)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqh_last) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfi_kif__bindgen_ty_2),\n            \"::\",\n            stringify!(tqh_last)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pfi_kif() {\n    const UNINIT: ::std::mem::MaybeUninit<pfi_kif> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfi_kif>(),\n        216usize,\n        concat!(\"Size of: \", stringify!(pfi_kif))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfi_kif>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfi_kif))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_name) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfi_kif), \"::\", stringify!(pfik_name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_packets) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(pfi_kif), \"::\", stringify!(pfik_packets))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_bytes) as usize - ptr as usize },\n        104usize,\n        concat!(\"Offset of field: \", stringify!(pfi_kif), \"::\", stringify!(pfik_bytes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_tzero) as usize - ptr as usize },\n        168usize,\n        concat!(\"Offset of field: \", stringify!(pfi_kif), \"::\", stringify!(pfik_tzero))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_flags) as usize - ptr as usize },\n        172usize,\n        concat!(\"Offset of field: \", stringify!(pfi_kif), \"::\", stringify!(pfik_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_ifp) as usize - ptr as usize },\n        176usize,\n        concat!(\"Offset of field: \", stringify!(pfi_kif), \"::\", stringify!(pfik_ifp))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_group) as usize - ptr as usize },\n        184usize,\n        concat!(\"Offset of field: \", stringify!(pfi_kif), \"::\", stringify!(pfik_group))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_rulerefs) as usize - ptr as usize },\n        192usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfi_kif),\n            \"::\",\n            stringify!(pfik_rulerefs)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_dynaddrs) as usize - ptr as usize },\n        200usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfi_kif),\n            \"::\",\n            stringify!(pfik_dynaddrs)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_status {\n    pub counters: [u64; 16usize],\n    pub lcounters: [u64; 7usize],\n    pub fcounters: [u64; 3usize],\n    pub scounters: [u64; 3usize],\n    pub pcounters: [[[u64; 3usize]; 2usize]; 2usize],\n    pub bcounters: [[u64; 2usize]; 2usize],\n    pub running: u32,\n    pub states: u32,\n    pub src_nodes: u32,\n    pub since: u32,\n    pub debug: u32,\n    pub hostid: u32,\n    pub ifname: [::std::os::raw::c_char; 16usize],\n    pub pf_chksum: [u8; 16usize],\n}\n#[test]\nfn bindgen_test_layout_pf_status() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_status> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_status>(),\n        416usize,\n        concat!(\"Size of: \", stringify!(pf_status))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_status>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_status))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).counters) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(counters))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lcounters) as usize - ptr as usize },\n        128usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(lcounters))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fcounters) as usize - ptr as usize },\n        184usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(fcounters))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scounters) as usize - ptr as usize },\n        208usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(scounters))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pcounters) as usize - ptr as usize },\n        232usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(pcounters))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).bcounters) as usize - ptr as usize },\n        328usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(bcounters))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).running) as usize - ptr as usize },\n        360usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(running))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).states) as usize - ptr as usize },\n        364usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(states))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).src_nodes) as usize - ptr as usize },\n        368usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(src_nodes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).since) as usize - ptr as usize },\n        372usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(since))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).debug) as usize - ptr as usize },\n        376usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(debug))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).hostid) as usize - ptr as usize },\n        380usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(hostid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifname) as usize - ptr as usize },\n        384usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(ifname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pf_chksum) as usize - ptr as usize },\n        400usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(pf_chksum))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_addr {\n    pub pfa: pf_addr__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pf_addr__bindgen_ty_1 {\n    pub v4: in_addr,\n    pub v6: in6_addr,\n    pub addr8: [u_int8_t; 16usize],\n    pub addr16: [u_int16_t; 8usize],\n    pub addr32: [u_int32_t; 4usize],\n}\n#[test]\nfn bindgen_test_layout_pf_addr__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_addr__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_addr__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_addr__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_addr__bindgen_ty_1>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_addr__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).v4) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(v4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).v6) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(v6)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr8) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(addr8)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr16) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(addr16)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr32) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(addr32)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_addr() {\n    assert_eq!(\n        ::std::mem::size_of::<pf_addr>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_addr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_addr>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_addr))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_addr_wrap {\n    pub v: pf_addr_wrap__bindgen_ty_1,\n    pub p: pf_addr_wrap__bindgen_ty_2,\n    pub type_: u_int8_t,\n    pub iflags: u_int8_t,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pf_addr_wrap__bindgen_ty_1 {\n    pub a: pf_addr_wrap__bindgen_ty_1__bindgen_ty_1,\n    pub ifname: [::std::os::raw::c_char; 16usize],\n    pub tblname: [::std::os::raw::c_char; 32usize],\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_addr_wrap__bindgen_ty_1__bindgen_ty_1 {\n    pub addr: pf_addr,\n    pub mask: pf_addr,\n}\n#[test]\nfn bindgen_test_layout_pf_addr_wrap__bindgen_ty_1__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_addr_wrap__bindgen_ty_1__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_addr_wrap__bindgen_ty_1__bindgen_ty_1>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(pf_addr_wrap__bindgen_ty_1__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_addr_wrap__bindgen_ty_1__bindgen_ty_1>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_addr_wrap__bindgen_ty_1__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mask) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(mask)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_addr_wrap__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_addr_wrap__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_addr_wrap__bindgen_ty_1>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(pf_addr_wrap__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_addr_wrap__bindgen_ty_1>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_addr_wrap__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_1),\n            \"::\",\n            stringify!(a)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifname) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_1),\n            \"::\",\n            stringify!(ifname)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tblname) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_1),\n            \"::\",\n            stringify!(tblname)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pf_addr_wrap__bindgen_ty_2 {\n    pub dyn_: *mut pfi_dynaddr,\n    pub tbl: *mut pfr_ktable,\n    pub dyncnt: ::std::os::raw::c_int,\n    pub tblcnt: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_pf_addr_wrap__bindgen_ty_2() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_addr_wrap__bindgen_ty_2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_addr_wrap__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_addr_wrap__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_addr_wrap__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_addr_wrap__bindgen_ty_2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dyn_) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_2),\n            \"::\",\n            stringify!(dyn_)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tbl) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_2),\n            \"::\",\n            stringify!(tbl)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dyncnt) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_2),\n            \"::\",\n            stringify!(dyncnt)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tblcnt) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_2),\n            \"::\",\n            stringify!(tblcnt)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_addr_wrap() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_addr_wrap> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_addr_wrap>(),\n        48usize,\n        concat!(\"Size of: \", stringify!(pf_addr_wrap))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_addr_wrap>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_addr_wrap))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).v) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_addr_wrap), \"::\", stringify!(v))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).p) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(pf_addr_wrap), \"::\", stringify!(p))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).type_) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(pf_addr_wrap), \"::\", stringify!(type_))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).iflags) as usize - ptr as usize },\n        41usize,\n        concat!(\"Offset of field: \", stringify!(pf_addr_wrap), \"::\", stringify!(iflags))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pf_rule_ptr {\n    pub ptr: *mut pf_rule,\n    pub nr: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_pf_rule_ptr() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rule_ptr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rule_ptr>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_rule_ptr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rule_ptr>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_rule_ptr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ptr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_ptr), \"::\", stringify!(ptr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_ptr), \"::\", stringify!(nr))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_rule_uid {\n    pub uid: [uid_t; 2usize],\n    pub op: u_int8_t,\n}\n#[test]\nfn bindgen_test_layout_pf_rule_uid() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rule_uid> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rule_uid>(),\n        12usize,\n        concat!(\"Size of: \", stringify!(pf_rule_uid))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rule_uid>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_rule_uid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uid) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_uid), \"::\", stringify!(uid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).op) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_uid), \"::\", stringify!(op))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_rule_gid {\n    pub gid: [uid_t; 2usize],\n    pub op: u_int8_t,\n}\n#[test]\nfn bindgen_test_layout_pf_rule_gid() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rule_gid> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rule_gid>(),\n        12usize,\n        concat!(\"Size of: \", stringify!(pf_rule_gid))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rule_gid>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_rule_gid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).gid) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_gid), \"::\", stringify!(gid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).op) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_gid), \"::\", stringify!(op))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_rule_addr {\n    pub addr: pf_addr_wrap,\n    pub port: [u_int16_t; 2usize],\n    pub neg: u_int8_t,\n    pub port_op: u_int8_t,\n}\n#[test]\nfn bindgen_test_layout_pf_rule_addr() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rule_addr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rule_addr>(),\n        56usize,\n        concat!(\"Size of: \", stringify!(pf_rule_addr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rule_addr>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_rule_addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_addr), \"::\", stringify!(addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).port) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_addr), \"::\", stringify!(port))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).neg) as usize - ptr as usize },\n        52usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_addr), \"::\", stringify!(neg))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).port_op) as usize - ptr as usize },\n        53usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_addr), \"::\", stringify!(port_op))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_pooladdr {\n    pub addr: pf_addr_wrap,\n    pub entries: pf_pooladdr__bindgen_ty_1,\n    pub ifname: [::std::os::raw::c_char; 16usize],\n    pub kif: *mut pfi_kif,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_pooladdr__bindgen_ty_1 {\n    pub tqe_next: *mut pf_pooladdr,\n    pub tqe_prev: *mut *mut pf_pooladdr,\n}\n#[test]\nfn bindgen_test_layout_pf_pooladdr__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_pooladdr__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_pooladdr__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_pooladdr__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_pooladdr__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_pooladdr__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqe_next) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_pooladdr__bindgen_ty_1),\n            \"::\",\n            stringify!(tqe_next)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqe_prev) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_pooladdr__bindgen_ty_1),\n            \"::\",\n            stringify!(tqe_prev)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_pooladdr() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_pooladdr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_pooladdr>(),\n        88usize,\n        concat!(\"Size of: \", stringify!(pf_pooladdr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_pooladdr>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_pooladdr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_pooladdr), \"::\", stringify!(addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).entries) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(pf_pooladdr), \"::\", stringify!(entries))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifname) as usize - ptr as usize },\n        64usize,\n        concat!(\"Offset of field: \", stringify!(pf_pooladdr), \"::\", stringify!(ifname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).kif) as usize - ptr as usize },\n        80usize,\n        concat!(\"Offset of field: \", stringify!(pf_pooladdr), \"::\", stringify!(kif))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_palist {\n    pub tqh_first: *mut pf_pooladdr,\n    pub tqh_last: *mut *mut pf_pooladdr,\n}\n#[test]\nfn bindgen_test_layout_pf_palist() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_palist> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_palist>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_palist))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_palist>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_palist))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqh_first) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_palist), \"::\", stringify!(tqh_first))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqh_last) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pf_palist), \"::\", stringify!(tqh_last))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_poolhashkey {\n    pub __bindgen_anon_1: pf_poolhashkey__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pf_poolhashkey__bindgen_ty_1 {\n    pub key8: [u_int8_t; 16usize],\n    pub key16: [u_int16_t; 8usize],\n    pub key32: [u_int32_t; 4usize],\n}\n#[test]\nfn bindgen_test_layout_pf_poolhashkey__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_poolhashkey__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_poolhashkey__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_poolhashkey__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_poolhashkey__bindgen_ty_1>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_poolhashkey__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).key8) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_poolhashkey__bindgen_ty_1),\n            \"::\",\n            stringify!(key8)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).key16) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_poolhashkey__bindgen_ty_1),\n            \"::\",\n            stringify!(key16)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).key32) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_poolhashkey__bindgen_ty_1),\n            \"::\",\n            stringify!(key32)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_poolhashkey() {\n    assert_eq!(\n        ::std::mem::size_of::<pf_poolhashkey>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_poolhashkey))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_poolhashkey>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_poolhashkey))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_mape_portset {\n    pub offset: u_int8_t,\n    pub psidlen: u_int8_t,\n    pub psid: u_int16_t,\n}\n#[test]\nfn bindgen_test_layout_pf_mape_portset() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_mape_portset> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_mape_portset>(),\n        4usize,\n        concat!(\"Size of: \", stringify!(pf_mape_portset))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_mape_portset>(),\n        2usize,\n        concat!(\"Alignment of \", stringify!(pf_mape_portset))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).offset) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_mape_portset),\n            \"::\",\n            stringify!(offset)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psidlen) as usize - ptr as usize },\n        1usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_mape_portset),\n            \"::\",\n            stringify!(psidlen)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psid) as usize - ptr as usize },\n        2usize,\n        concat!(\"Offset of field: \", stringify!(pf_mape_portset), \"::\", stringify!(psid))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_pool {\n    pub list: pf_palist,\n    pub cur: *mut pf_pooladdr,\n    pub key: pf_poolhashkey,\n    pub counter: pf_addr,\n    pub tblidx: ::std::os::raw::c_int,\n    pub proxy_port: [u_int16_t; 2usize],\n    pub opts: u_int8_t,\n}\n#[test]\nfn bindgen_test_layout_pf_pool() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_pool> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_pool>(),\n        72usize,\n        concat!(\"Size of: \", stringify!(pf_pool))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_pool>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_pool))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).list) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_pool), \"::\", stringify!(list))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cur) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pf_pool), \"::\", stringify!(cur))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).key) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(pf_pool), \"::\", stringify!(key))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).counter) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(pf_pool), \"::\", stringify!(counter))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tblidx) as usize - ptr as usize },\n        56usize,\n        concat!(\"Offset of field: \", stringify!(pf_pool), \"::\", stringify!(tblidx))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).proxy_port) as usize - ptr as usize },\n        60usize,\n        concat!(\"Offset of field: \", stringify!(pf_pool), \"::\", stringify!(proxy_port))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).opts) as usize - ptr as usize },\n        64usize,\n        concat!(\"Offset of field: \", stringify!(pf_pool), \"::\", stringify!(opts))\n    );\n}\npub type pf_osfp_t = u_int32_t;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_osfp_entry {\n    pub fp_entry: pf_osfp_entry__bindgen_ty_1,\n    pub fp_os: pf_osfp_t,\n    pub fp_enflags: ::std::os::raw::c_int,\n    pub fp_class_nm: [::std::os::raw::c_char; 32usize],\n    pub fp_version_nm: [::std::os::raw::c_char; 32usize],\n    pub fp_subtype_nm: [::std::os::raw::c_char; 32usize],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_osfp_entry__bindgen_ty_1 {\n    pub sle_next: *mut pf_osfp_entry,\n}\n#[test]\nfn bindgen_test_layout_pf_osfp_entry__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_osfp_entry__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_osfp_entry__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_osfp_entry__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_osfp_entry__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_osfp_entry__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sle_next) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_entry__bindgen_ty_1),\n            \"::\",\n            stringify!(sle_next)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_osfp_entry() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_osfp_entry> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_osfp_entry>(),\n        112usize,\n        concat!(\"Size of: \", stringify!(pf_osfp_entry))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_osfp_entry>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_osfp_entry))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_entry) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_entry),\n            \"::\",\n            stringify!(fp_entry)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_os) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pf_osfp_entry), \"::\", stringify!(fp_os))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_enflags) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_entry),\n            \"::\",\n            stringify!(fp_enflags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_class_nm) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_entry),\n            \"::\",\n            stringify!(fp_class_nm)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_version_nm) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_entry),\n            \"::\",\n            stringify!(fp_version_nm)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_subtype_nm) as usize - ptr as usize },\n        80usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_entry),\n            \"::\",\n            stringify!(fp_subtype_nm)\n        )\n    );\n}\npub type pf_tcpopts_t = u_int64_t;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_os_fingerprint {\n    pub fp_oses: pf_os_fingerprint_pf_osfp_enlist,\n    pub fp_tcpopts: pf_tcpopts_t,\n    pub fp_wsize: u_int16_t,\n    pub fp_psize: u_int16_t,\n    pub fp_mss: u_int16_t,\n    pub fp_flags: u_int16_t,\n    pub fp_optcnt: u_int8_t,\n    pub fp_wscale: u_int8_t,\n    pub fp_ttl: u_int8_t,\n    pub fp_next: pf_os_fingerprint__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_os_fingerprint_pf_osfp_enlist {\n    pub slh_first: *mut pf_osfp_entry,\n}\n#[test]\nfn bindgen_test_layout_pf_os_fingerprint_pf_osfp_enlist() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_os_fingerprint_pf_osfp_enlist> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_os_fingerprint_pf_osfp_enlist>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_os_fingerprint_pf_osfp_enlist))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_os_fingerprint_pf_osfp_enlist>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_os_fingerprint_pf_osfp_enlist))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).slh_first) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint_pf_osfp_enlist),\n            \"::\",\n            stringify!(slh_first)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_os_fingerprint__bindgen_ty_1 {\n    pub sle_next: *mut pf_os_fingerprint,\n}\n#[test]\nfn bindgen_test_layout_pf_os_fingerprint__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_os_fingerprint__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_os_fingerprint__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_os_fingerprint__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_os_fingerprint__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_os_fingerprint__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sle_next) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint__bindgen_ty_1),\n            \"::\",\n            stringify!(sle_next)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_os_fingerprint() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_os_fingerprint> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_os_fingerprint>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(pf_os_fingerprint))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_os_fingerprint>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_os_fingerprint))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_oses) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_oses)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_tcpopts) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_tcpopts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_wsize) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_wsize)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_psize) as usize - ptr as usize },\n        18usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_psize)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_mss) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_mss)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_flags) as usize - ptr as usize },\n        22usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_optcnt) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_optcnt)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_wscale) as usize - ptr as usize },\n        25usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_wscale)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_ttl) as usize - ptr as usize },\n        26usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_ttl)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_next) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_next)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_osfp_ioctl {\n    pub fp_os: pf_osfp_entry,\n    pub fp_tcpopts: pf_tcpopts_t,\n    pub fp_wsize: u_int16_t,\n    pub fp_psize: u_int16_t,\n    pub fp_mss: u_int16_t,\n    pub fp_flags: u_int16_t,\n    pub fp_optcnt: u_int8_t,\n    pub fp_wscale: u_int8_t,\n    pub fp_ttl: u_int8_t,\n    pub fp_getnum: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_pf_osfp_ioctl() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_osfp_ioctl> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_osfp_ioctl>(),\n        136usize,\n        concat!(\"Size of: \", stringify!(pf_osfp_ioctl))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_osfp_ioctl>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_osfp_ioctl))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_os) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_osfp_ioctl), \"::\", stringify!(fp_os))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_tcpopts) as usize - ptr as usize },\n        112usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_ioctl),\n            \"::\",\n            stringify!(fp_tcpopts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_wsize) as usize - ptr as usize },\n        120usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_ioctl),\n            \"::\",\n            stringify!(fp_wsize)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_psize) as usize - ptr as usize },\n        122usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_ioctl),\n            \"::\",\n            stringify!(fp_psize)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_mss) as usize - ptr as usize },\n        124usize,\n        concat!(\"Offset of field: \", stringify!(pf_osfp_ioctl), \"::\", stringify!(fp_mss))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_flags) as usize - ptr as usize },\n        126usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_ioctl),\n            \"::\",\n            stringify!(fp_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_optcnt) as usize - ptr as usize },\n        128usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_ioctl),\n            \"::\",\n            stringify!(fp_optcnt)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_wscale) as usize - ptr as usize },\n        129usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_ioctl),\n            \"::\",\n            stringify!(fp_wscale)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_ttl) as usize - ptr as usize },\n        130usize,\n        concat!(\"Offset of field: \", stringify!(pf_osfp_ioctl), \"::\", stringify!(fp_ttl))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_getnum) as usize - ptr as usize },\n        132usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_ioctl),\n            \"::\",\n            stringify!(fp_getnum)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_rule {\n    pub src: pf_rule_addr,\n    pub dst: pf_rule_addr,\n    pub skip: [pf_rule_ptr; 8usize],\n    pub label: [::std::os::raw::c_char; 64usize],\n    pub ifname: [::std::os::raw::c_char; 16usize],\n    pub qname: [::std::os::raw::c_char; 64usize],\n    pub pqname: [::std::os::raw::c_char; 64usize],\n    pub tagname: [::std::os::raw::c_char; 64usize],\n    pub match_tagname: [::std::os::raw::c_char; 64usize],\n    pub overload_tblname: [::std::os::raw::c_char; 32usize],\n    pub entries: pf_rule__bindgen_ty_1,\n    pub rpool: pf_pool,\n    pub evaluations: u_int64_t,\n    pub packets: [u_int64_t; 2usize],\n    pub bytes: [u_int64_t; 2usize],\n    pub kif: *mut pfi_kif,\n    pub anchor: *mut pf_anchor,\n    pub overload_tbl: *mut pfr_ktable,\n    pub os_fingerprint: pf_osfp_t,\n    pub rtableid: ::std::os::raw::c_int,\n    pub timeout: [u_int32_t; 20usize],\n    pub max_states: u_int32_t,\n    pub max_src_nodes: u_int32_t,\n    pub max_src_states: u_int32_t,\n    pub max_src_conn: u_int32_t,\n    pub max_src_conn_rate: pf_rule__bindgen_ty_2,\n    pub qid: u_int32_t,\n    pub pqid: u_int32_t,\n    pub rt_listid: u_int32_t,\n    pub nr: u_int32_t,\n    pub prob: u_int32_t,\n    pub cuid: uid_t,\n    pub cpid: pid_t,\n    pub states_cur: counter_u64_t,\n    pub states_tot: counter_u64_t,\n    pub src_nodes: counter_u64_t,\n    pub return_icmp: u_int16_t,\n    pub return_icmp6: u_int16_t,\n    pub max_mss: u_int16_t,\n    pub tag: u_int16_t,\n    pub match_tag: u_int16_t,\n    pub scrub_flags: u_int16_t,\n    pub uid: pf_rule_uid,\n    pub gid: pf_rule_gid,\n    pub rule_flag: u_int32_t,\n    pub action: u_int8_t,\n    pub direction: u_int8_t,\n    pub log: u_int8_t,\n    pub logif: u_int8_t,\n    pub quick: u_int8_t,\n    pub ifnot: u_int8_t,\n    pub match_tag_not: u_int8_t,\n    pub natpass: u_int8_t,\n    pub keep_state: u_int8_t,\n    pub af: sa_family_t,\n    pub proto: u_int8_t,\n    pub type_: u_int8_t,\n    pub code: u_int8_t,\n    pub flags: u_int8_t,\n    pub flagset: u_int8_t,\n    pub min_ttl: u_int8_t,\n    pub allow_opts: u_int8_t,\n    pub rt: u_int8_t,\n    pub return_ttl: u_int8_t,\n    pub tos: u_int8_t,\n    pub set_tos: u_int8_t,\n    pub anchor_relative: u_int8_t,\n    pub anchor_wildcard: u_int8_t,\n    pub flush: u_int8_t,\n    pub prio: u_int8_t,\n    pub set_prio: [u_int8_t; 2usize],\n    pub divert: pf_rule__bindgen_ty_3,\n    pub u_states_cur: u64,\n    pub u_states_tot: u64,\n    pub u_src_nodes: u64,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_rule__bindgen_ty_1 {\n    pub tqe_next: *mut pf_rule,\n    pub tqe_prev: *mut *mut pf_rule,\n}\n#[test]\nfn bindgen_test_layout_pf_rule__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rule__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rule__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_rule__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rule__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_rule__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqe_next) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule__bindgen_ty_1),\n            \"::\",\n            stringify!(tqe_next)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqe_prev) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule__bindgen_ty_1),\n            \"::\",\n            stringify!(tqe_prev)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_rule__bindgen_ty_2 {\n    pub limit: u_int32_t,\n    pub seconds: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_pf_rule__bindgen_ty_2() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rule__bindgen_ty_2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rule__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_rule__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rule__bindgen_ty_2>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_rule__bindgen_ty_2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).limit) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule__bindgen_ty_2),\n            \"::\",\n            stringify!(limit)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).seconds) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule__bindgen_ty_2),\n            \"::\",\n            stringify!(seconds)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_rule__bindgen_ty_3 {\n    pub addr: pf_addr,\n    pub port: u_int16_t,\n}\n#[test]\nfn bindgen_test_layout_pf_rule__bindgen_ty_3() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rule__bindgen_ty_3> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rule__bindgen_ty_3>(),\n        20usize,\n        concat!(\"Size of: \", stringify!(pf_rule__bindgen_ty_3))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rule__bindgen_ty_3>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_rule__bindgen_ty_3))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule__bindgen_ty_3),\n            \"::\",\n            stringify!(addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).port) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule__bindgen_ty_3),\n            \"::\",\n            stringify!(port)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_rule() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rule> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rule>(),\n        976usize,\n        concat!(\"Size of: \", stringify!(pf_rule))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rule>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_rule))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).src) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(src))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dst) as usize - ptr as usize },\n        56usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(dst))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).skip) as usize - ptr as usize },\n        112usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(skip))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).label) as usize - ptr as usize },\n        176usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(label))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifname) as usize - ptr as usize },\n        240usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(ifname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).qname) as usize - ptr as usize },\n        256usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(qname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pqname) as usize - ptr as usize },\n        320usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(pqname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tagname) as usize - ptr as usize },\n        384usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(tagname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).match_tagname) as usize - ptr as usize },\n        448usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule),\n            \"::\",\n            stringify!(match_tagname)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).overload_tblname) as usize - ptr as usize },\n        512usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule),\n            \"::\",\n            stringify!(overload_tblname)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).entries) as usize - ptr as usize },\n        544usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(entries))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rpool) as usize - ptr as usize },\n        560usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(rpool))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).evaluations) as usize - ptr as usize },\n        632usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(evaluations))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).packets) as usize - ptr as usize },\n        640usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(packets))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).bytes) as usize - ptr as usize },\n        656usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(bytes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).kif) as usize - ptr as usize },\n        672usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(kif))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor) as usize - ptr as usize },\n        680usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(anchor))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).overload_tbl) as usize - ptr as usize },\n        688usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(overload_tbl))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).os_fingerprint) as usize - ptr as usize },\n        696usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule),\n            \"::\",\n            stringify!(os_fingerprint)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtableid) as usize - ptr as usize },\n        700usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(rtableid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).timeout) as usize - ptr as usize },\n        704usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(timeout))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_states) as usize - ptr as usize },\n        784usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(max_states))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_src_nodes) as usize - ptr as usize },\n        788usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule),\n            \"::\",\n            stringify!(max_src_nodes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_src_states) as usize - ptr as usize },\n        792usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule),\n            \"::\",\n            stringify!(max_src_states)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_src_conn) as usize - ptr as usize },\n        796usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(max_src_conn))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_src_conn_rate) as usize - ptr as usize },\n        800usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule),\n            \"::\",\n            stringify!(max_src_conn_rate)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).qid) as usize - ptr as usize },\n        808usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(qid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pqid) as usize - ptr as usize },\n        812usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(pqid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rt_listid) as usize - ptr as usize },\n        816usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(rt_listid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nr) as usize - ptr as usize },\n        820usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(nr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).prob) as usize - ptr as usize },\n        824usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(prob))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cuid) as usize - ptr as usize },\n        828usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(cuid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cpid) as usize - ptr as usize },\n        832usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(cpid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).states_cur) as usize - ptr as usize },\n        840usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(states_cur))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).states_tot) as usize - ptr as usize },\n        848usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(states_tot))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).src_nodes) as usize - ptr as usize },\n        856usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(src_nodes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).return_icmp) as usize - ptr as usize },\n        864usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(return_icmp))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).return_icmp6) as usize - ptr as usize },\n        866usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(return_icmp6))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_mss) as usize - ptr as usize },\n        868usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(max_mss))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tag) as usize - ptr as usize },\n        870usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(tag))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).match_tag) as usize - ptr as usize },\n        872usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(match_tag))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scrub_flags) as usize - ptr as usize },\n        874usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(scrub_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uid) as usize - ptr as usize },\n        876usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(uid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).gid) as usize - ptr as usize },\n        888usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(gid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rule_flag) as usize - ptr as usize },\n        900usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(rule_flag))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).action) as usize - ptr as usize },\n        904usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(action))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).direction) as usize - ptr as usize },\n        905usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(direction))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).log) as usize - ptr as usize },\n        906usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(log))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).logif) as usize - ptr as usize },\n        907usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(logif))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).quick) as usize - ptr as usize },\n        908usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(quick))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifnot) as usize - ptr as usize },\n        909usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(ifnot))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).match_tag_not) as usize - ptr as usize },\n        910usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule),\n            \"::\",\n            stringify!(match_tag_not)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).natpass) as usize - ptr as usize },\n        911usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(natpass))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).keep_state) as usize - ptr as usize },\n        912usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(keep_state))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).af) as usize - ptr as usize },\n        913usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(af))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).proto) as usize - ptr as usize },\n        914usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(proto))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).type_) as usize - ptr as usize },\n        915usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(type_))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).code) as usize - ptr as usize },\n        916usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(code))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flags) as usize - ptr as usize },\n        917usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flagset) as usize - ptr as usize },\n        918usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(flagset))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).min_ttl) as usize - ptr as usize },\n        919usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(min_ttl))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).allow_opts) as usize - ptr as usize },\n        920usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(allow_opts))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rt) as usize - ptr as usize },\n        921usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(rt))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).return_ttl) as usize - ptr as usize },\n        922usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(return_ttl))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tos) as usize - ptr as usize },\n        923usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(tos))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).set_tos) as usize - ptr as usize },\n        924usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(set_tos))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor_relative) as usize - ptr as usize },\n        925usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule),\n            \"::\",\n            stringify!(anchor_relative)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor_wildcard) as usize - ptr as usize },\n        926usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule),\n            \"::\",\n            stringify!(anchor_wildcard)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flush) as usize - ptr as usize },\n        927usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(flush))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).prio) as usize - ptr as usize },\n        928usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(prio))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).set_prio) as usize - ptr as usize },\n        929usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(set_prio))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).divert) as usize - ptr as usize },\n        932usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(divert))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).u_states_cur) as usize - ptr as usize },\n        952usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(u_states_cur))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).u_states_tot) as usize - ptr as usize },\n        960usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(u_states_tot))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).u_src_nodes) as usize - ptr as usize },\n        968usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(u_src_nodes))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_threshold {\n    pub limit: u_int32_t,\n    pub seconds: u_int32_t,\n    pub count: u_int32_t,\n    pub last: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_pf_threshold() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_threshold> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_threshold>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_threshold))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_threshold>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_threshold))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).limit) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_threshold), \"::\", stringify!(limit))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).seconds) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(pf_threshold), \"::\", stringify!(seconds))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).count) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pf_threshold), \"::\", stringify!(count))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).last) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(pf_threshold), \"::\", stringify!(last))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_src_node {\n    pub entry: pf_src_node__bindgen_ty_1,\n    pub addr: pf_addr,\n    pub raddr: pf_addr,\n    pub rule: pf_rule_ptr,\n    pub kif: *mut pfi_kif,\n    pub bytes: [u_int64_t; 2usize],\n    pub packets: [u_int64_t; 2usize],\n    pub states: u_int32_t,\n    pub conn: u_int32_t,\n    pub conn_rate: pf_threshold,\n    pub creation: u_int32_t,\n    pub expire: u_int32_t,\n    pub af: sa_family_t,\n    pub ruletype: u_int8_t,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_src_node__bindgen_ty_1 {\n    pub le_next: *mut pf_src_node,\n    pub le_prev: *mut *mut pf_src_node,\n}\n#[test]\nfn bindgen_test_layout_pf_src_node__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_src_node__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_src_node__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_src_node__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_src_node__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_src_node__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).le_next) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_src_node__bindgen_ty_1),\n            \"::\",\n            stringify!(le_next)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).le_prev) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_src_node__bindgen_ty_1),\n            \"::\",\n            stringify!(le_prev)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_src_node() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_src_node> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_src_node>(),\n        136usize,\n        concat!(\"Size of: \", stringify!(pf_src_node))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_src_node>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_src_node))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).entry) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(entry))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).raddr) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(raddr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rule) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(rule))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).kif) as usize - ptr as usize },\n        56usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(kif))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).bytes) as usize - ptr as usize },\n        64usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(bytes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).packets) as usize - ptr as usize },\n        80usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(packets))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).states) as usize - ptr as usize },\n        96usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(states))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).conn) as usize - ptr as usize },\n        100usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(conn))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).conn_rate) as usize - ptr as usize },\n        104usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_src_node),\n            \"::\",\n            stringify!(conn_rate)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).creation) as usize - ptr as usize },\n        120usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(creation))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).expire) as usize - ptr as usize },\n        124usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(expire))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).af) as usize - ptr as usize },\n        128usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(af))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ruletype) as usize - ptr as usize },\n        129usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(ruletype))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_rulequeue {\n    pub tqh_first: *mut pf_rule,\n    pub tqh_last: *mut *mut pf_rule,\n}\n#[test]\nfn bindgen_test_layout_pf_rulequeue() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rulequeue> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rulequeue>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_rulequeue))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rulequeue>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_rulequeue))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqh_first) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rulequeue),\n            \"::\",\n            stringify!(tqh_first)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqh_last) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rulequeue),\n            \"::\",\n            stringify!(tqh_last)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_ruleset {\n    pub rules: [pf_ruleset__bindgen_ty_1; 5usize],\n    pub anchor: *mut pf_anchor,\n    pub tticket: u_int32_t,\n    pub tables: ::std::os::raw::c_int,\n    pub topen: ::std::os::raw::c_int,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_ruleset__bindgen_ty_1 {\n    pub queues: [pf_rulequeue; 2usize],\n    pub active: pf_ruleset__bindgen_ty_1__bindgen_ty_1,\n    pub inactive: pf_ruleset__bindgen_ty_1__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_ruleset__bindgen_ty_1__bindgen_ty_1 {\n    pub ptr: *mut pf_rulequeue,\n    pub ptr_array: *mut *mut pf_rule,\n    pub rcount: u_int32_t,\n    pub ticket: u_int32_t,\n    pub open: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_pf_ruleset__bindgen_ty_1__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_ruleset__bindgen_ty_1__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_ruleset__bindgen_ty_1__bindgen_ty_1>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(pf_ruleset__bindgen_ty_1__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_ruleset__bindgen_ty_1__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_ruleset__bindgen_ty_1__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ptr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_ruleset__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(ptr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ptr_array) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_ruleset__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(ptr_array)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rcount) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_ruleset__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(rcount)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ticket) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_ruleset__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(ticket)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).open) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_ruleset__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(open)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_ruleset__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_ruleset__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_ruleset__bindgen_ty_1>(),\n        96usize,\n        concat!(\"Size of: \", stringify!(pf_ruleset__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_ruleset__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_ruleset__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).queues) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_ruleset__bindgen_ty_1),\n            \"::\",\n            stringify!(queues)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).active) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_ruleset__bindgen_ty_1),\n            \"::\",\n            stringify!(active)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).inactive) as usize - ptr as usize },\n        64usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_ruleset__bindgen_ty_1),\n            \"::\",\n            stringify!(inactive)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_ruleset() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_ruleset> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_ruleset>(),\n        504usize,\n        concat!(\"Size of: \", stringify!(pf_ruleset))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_ruleset>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_ruleset))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rules) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_ruleset), \"::\", stringify!(rules))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor) as usize - ptr as usize },\n        480usize,\n        concat!(\"Offset of field: \", stringify!(pf_ruleset), \"::\", stringify!(anchor))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tticket) as usize - ptr as usize },\n        488usize,\n        concat!(\"Offset of field: \", stringify!(pf_ruleset), \"::\", stringify!(tticket))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tables) as usize - ptr as usize },\n        492usize,\n        concat!(\"Offset of field: \", stringify!(pf_ruleset), \"::\", stringify!(tables))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).topen) as usize - ptr as usize },\n        496usize,\n        concat!(\"Offset of field: \", stringify!(pf_ruleset), \"::\", stringify!(topen))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_anchor_global {\n    pub rbh_root: *mut pf_anchor,\n}\n#[test]\nfn bindgen_test_layout_pf_anchor_global() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_anchor_global> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_anchor_global>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_anchor_global))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_anchor_global>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_anchor_global))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbh_root) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_anchor_global),\n            \"::\",\n            stringify!(rbh_root)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_anchor_node {\n    pub rbh_root: *mut pf_anchor,\n}\n#[test]\nfn bindgen_test_layout_pf_anchor_node() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_anchor_node> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_anchor_node>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_anchor_node))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_anchor_node>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_anchor_node))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbh_root) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_anchor_node),\n            \"::\",\n            stringify!(rbh_root)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_anchor {\n    pub entry_global: pf_anchor__bindgen_ty_1,\n    pub entry_node: pf_anchor__bindgen_ty_2,\n    pub parent: *mut pf_anchor,\n    pub children: pf_anchor_node,\n    pub name: [::std::os::raw::c_char; 64usize],\n    pub path: [::std::os::raw::c_char; 1024usize],\n    pub ruleset: pf_ruleset,\n    pub refcnt: ::std::os::raw::c_int,\n    pub match_: ::std::os::raw::c_int,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_anchor__bindgen_ty_1 {\n    pub rbe_link: [*mut pf_anchor; 3usize],\n}\n#[test]\nfn bindgen_test_layout_pf_anchor__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_anchor__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_anchor__bindgen_ty_1>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(pf_anchor__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_anchor__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_anchor__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_link) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_anchor__bindgen_ty_1),\n            \"::\",\n            stringify!(rbe_link)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_anchor__bindgen_ty_2 {\n    pub rbe_link: [*mut pf_anchor; 3usize],\n}\n#[test]\nfn bindgen_test_layout_pf_anchor__bindgen_ty_2() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_anchor__bindgen_ty_2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_anchor__bindgen_ty_2>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(pf_anchor__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_anchor__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_anchor__bindgen_ty_2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_link) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_anchor__bindgen_ty_2),\n            \"::\",\n            stringify!(rbe_link)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_anchor() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_anchor> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_anchor>(),\n        1664usize,\n        concat!(\"Size of: \", stringify!(pf_anchor))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_anchor>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_anchor))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).entry_global) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_anchor),\n            \"::\",\n            stringify!(entry_global)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).entry_node) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(pf_anchor), \"::\", stringify!(entry_node))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).parent) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(pf_anchor), \"::\", stringify!(parent))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).children) as usize - ptr as usize },\n        56usize,\n        concat!(\"Offset of field: \", stringify!(pf_anchor), \"::\", stringify!(children))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).name) as usize - ptr as usize },\n        64usize,\n        concat!(\"Offset of field: \", stringify!(pf_anchor), \"::\", stringify!(name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).path) as usize - ptr as usize },\n        128usize,\n        concat!(\"Offset of field: \", stringify!(pf_anchor), \"::\", stringify!(path))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ruleset) as usize - ptr as usize },\n        1152usize,\n        concat!(\"Offset of field: \", stringify!(pf_anchor), \"::\", stringify!(ruleset))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).refcnt) as usize - ptr as usize },\n        1656usize,\n        concat!(\"Offset of field: \", stringify!(pf_anchor), \"::\", stringify!(refcnt))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).match_) as usize - ptr as usize },\n        1660usize,\n        concat!(\"Offset of field: \", stringify!(pf_anchor), \"::\", stringify!(match_))\n    );\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_INSERT_COLOR(\n        arg1: *mut pf_anchor_global,\n        arg2: *mut pf_anchor,\n        arg3: *mut pf_anchor,\n    ) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_REMOVE_COLOR(\n        arg1: *mut pf_anchor_global,\n        arg2: *mut pf_anchor,\n        arg3: *mut pf_anchor,\n    ) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_INSERT_FINISH(\n        arg1: *mut pf_anchor_global,\n        arg2: *mut pf_anchor,\n        arg3: *mut *mut pf_anchor,\n        arg4: *mut pf_anchor,\n    ) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_INSERT(arg1: *mut pf_anchor_global, arg2: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_REMOVE(arg1: *mut pf_anchor_global, arg2: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_FIND(arg1: *mut pf_anchor_global, arg2: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_NFIND(arg1: *mut pf_anchor_global, arg2: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_NEXT(arg1: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_INSERT_NEXT(\n        arg1: *mut pf_anchor_global,\n        arg2: *mut pf_anchor,\n        arg3: *mut pf_anchor,\n    ) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_PREV(arg1: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_INSERT_PREV(\n        arg1: *mut pf_anchor_global,\n        arg2: *mut pf_anchor,\n        arg3: *mut pf_anchor,\n    ) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_MINMAX(arg1: *mut pf_anchor_global, arg2: ::std::os::raw::c_int) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_REINSERT(arg1: *mut pf_anchor_global, arg2: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_INSERT_COLOR(\n        arg1: *mut pf_anchor_node,\n        arg2: *mut pf_anchor,\n        arg3: *mut pf_anchor,\n    ) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_REMOVE_COLOR(\n        arg1: *mut pf_anchor_node,\n        arg2: *mut pf_anchor,\n        arg3: *mut pf_anchor,\n    ) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_INSERT_FINISH(\n        arg1: *mut pf_anchor_node,\n        arg2: *mut pf_anchor,\n        arg3: *mut *mut pf_anchor,\n        arg4: *mut pf_anchor,\n    ) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_INSERT(arg1: *mut pf_anchor_node, arg2: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_REMOVE(arg1: *mut pf_anchor_node, arg2: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_FIND(arg1: *mut pf_anchor_node, arg2: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_NFIND(arg1: *mut pf_anchor_node, arg2: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_NEXT(arg1: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_INSERT_NEXT(\n        arg1: *mut pf_anchor_node,\n        arg2: *mut pf_anchor,\n        arg3: *mut pf_anchor,\n    ) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_PREV(arg1: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_INSERT_PREV(\n        arg1: *mut pf_anchor_node,\n        arg2: *mut pf_anchor,\n        arg3: *mut pf_anchor,\n    ) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_MINMAX(arg1: *mut pf_anchor_node, arg2: ::std::os::raw::c_int) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_REINSERT(arg1: *mut pf_anchor_node, arg2: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_get_ruleset_number(arg1: u_int8_t) -> ::std::os::raw::c_int;\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct cbq_opts {\n    pub minburst: u_int,\n    pub maxburst: u_int,\n    pub pktsize: u_int,\n    pub maxpktsize: u_int,\n    pub ns_per_byte: u_int,\n    pub maxidle: u_int,\n    pub minidle: ::std::os::raw::c_int,\n    pub offtime: u_int,\n    pub flags: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_cbq_opts() {\n    const UNINIT: ::std::mem::MaybeUninit<cbq_opts> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<cbq_opts>(),\n        36usize,\n        concat!(\"Size of: \", stringify!(cbq_opts))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<cbq_opts>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(cbq_opts))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).minburst) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(cbq_opts), \"::\", stringify!(minburst))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).maxburst) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(cbq_opts), \"::\", stringify!(maxburst))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pktsize) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(cbq_opts), \"::\", stringify!(pktsize))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).maxpktsize) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(cbq_opts), \"::\", stringify!(maxpktsize))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ns_per_byte) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(cbq_opts), \"::\", stringify!(ns_per_byte))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).maxidle) as usize - ptr as usize },\n        20usize,\n        concat!(\"Offset of field: \", stringify!(cbq_opts), \"::\", stringify!(maxidle))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).minidle) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(cbq_opts), \"::\", stringify!(minidle))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).offtime) as usize - ptr as usize },\n        28usize,\n        concat!(\"Offset of field: \", stringify!(cbq_opts), \"::\", stringify!(offtime))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flags) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(cbq_opts), \"::\", stringify!(flags))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct codel_opts {\n    pub target: u_int,\n    pub interval: u_int,\n    pub ecn: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_codel_opts() {\n    const UNINIT: ::std::mem::MaybeUninit<codel_opts> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<codel_opts>(),\n        12usize,\n        concat!(\"Size of: \", stringify!(codel_opts))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<codel_opts>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(codel_opts))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).target) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(codel_opts), \"::\", stringify!(target))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).interval) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(codel_opts), \"::\", stringify!(interval))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ecn) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(codel_opts), \"::\", stringify!(ecn))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct priq_opts {\n    pub flags: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_priq_opts() {\n    const UNINIT: ::std::mem::MaybeUninit<priq_opts> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<priq_opts>(),\n        4usize,\n        concat!(\"Size of: \", stringify!(priq_opts))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<priq_opts>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(priq_opts))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flags) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(priq_opts), \"::\", stringify!(flags))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct hfsc_opts_v0 {\n    pub rtsc_m1: u_int,\n    pub rtsc_d: u_int,\n    pub rtsc_m2: u_int,\n    pub lssc_m1: u_int,\n    pub lssc_d: u_int,\n    pub lssc_m2: u_int,\n    pub ulsc_m1: u_int,\n    pub ulsc_d: u_int,\n    pub ulsc_m2: u_int,\n    pub flags: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_hfsc_opts_v0() {\n    const UNINIT: ::std::mem::MaybeUninit<hfsc_opts_v0> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<hfsc_opts_v0>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(hfsc_opts_v0))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<hfsc_opts_v0>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(hfsc_opts_v0))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtsc_m1) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts_v0), \"::\", stringify!(rtsc_m1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtsc_d) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts_v0), \"::\", stringify!(rtsc_d))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtsc_m2) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts_v0), \"::\", stringify!(rtsc_m2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lssc_m1) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts_v0), \"::\", stringify!(lssc_m1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lssc_d) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts_v0), \"::\", stringify!(lssc_d))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lssc_m2) as usize - ptr as usize },\n        20usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts_v0), \"::\", stringify!(lssc_m2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ulsc_m1) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts_v0), \"::\", stringify!(ulsc_m1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ulsc_d) as usize - ptr as usize },\n        28usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts_v0), \"::\", stringify!(ulsc_d))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ulsc_m2) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts_v0), \"::\", stringify!(ulsc_m2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flags) as usize - ptr as usize },\n        36usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts_v0), \"::\", stringify!(flags))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct hfsc_opts_v1 {\n    pub rtsc_m1: u_int64_t,\n    pub rtsc_d: u_int,\n    pub rtsc_m2: u_int64_t,\n    pub lssc_m1: u_int64_t,\n    pub lssc_d: u_int,\n    pub lssc_m2: u_int64_t,\n    pub ulsc_m1: u_int64_t,\n    pub ulsc_d: u_int,\n    pub ulsc_m2: u_int64_t,\n    pub flags: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_hfsc_opts_v1() {\n    const UNINIT: ::std::mem::MaybeUninit<hfsc_opts_v1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<hfsc_opts_v1>(),\n        80usize,\n        concat!(\"Size of: \", stringify!(hfsc_opts_v1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<hfsc_opts_v1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(hfsc_opts_v1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtsc_m1) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts_v1), \"::\", stringify!(rtsc_m1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtsc_d) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts_v1), \"::\", stringify!(rtsc_d))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtsc_m2) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts_v1), \"::\", stringify!(rtsc_m2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lssc_m1) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts_v1), \"::\", stringify!(lssc_m1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lssc_d) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts_v1), \"::\", stringify!(lssc_d))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lssc_m2) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts_v1), \"::\", stringify!(lssc_m2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ulsc_m1) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts_v1), \"::\", stringify!(ulsc_m1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ulsc_d) as usize - ptr as usize },\n        56usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts_v1), \"::\", stringify!(ulsc_d))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ulsc_m2) as usize - ptr as usize },\n        64usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts_v1), \"::\", stringify!(ulsc_m2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flags) as usize - ptr as usize },\n        72usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts_v1), \"::\", stringify!(flags))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct fairq_opts {\n    pub nbuckets: u_int,\n    pub hogs_m1: u_int,\n    pub flags: ::std::os::raw::c_int,\n    pub lssc_m1: u_int,\n    pub lssc_d: u_int,\n    pub lssc_m2: u_int,\n}\n#[test]\nfn bindgen_test_layout_fairq_opts() {\n    const UNINIT: ::std::mem::MaybeUninit<fairq_opts> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<fairq_opts>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(fairq_opts))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<fairq_opts>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(fairq_opts))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nbuckets) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(fairq_opts), \"::\", stringify!(nbuckets))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).hogs_m1) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(fairq_opts), \"::\", stringify!(hogs_m1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flags) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(fairq_opts), \"::\", stringify!(flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lssc_m1) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(fairq_opts), \"::\", stringify!(lssc_m1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lssc_d) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(fairq_opts), \"::\", stringify!(lssc_d))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lssc_m2) as usize - ptr as usize },\n        20usize,\n        concat!(\"Offset of field: \", stringify!(fairq_opts), \"::\", stringify!(lssc_m2))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_altq_v0 {\n    pub ifname: [::std::os::raw::c_char; 16usize],\n    pub unused1: *mut ::std::os::raw::c_void,\n    pub entries: pf_altq_v0__bindgen_ty_1,\n    pub scheduler: u8,\n    pub tbrsize: u16,\n    pub ifbandwidth: u32,\n    pub qname: [::std::os::raw::c_char; 64usize],\n    pub parent: [::std::os::raw::c_char; 64usize],\n    pub parent_qid: u32,\n    pub bandwidth: u32,\n    pub priority: u8,\n    pub local_flags: u8,\n    pub qlimit: u16,\n    pub flags: u16,\n    pub pq_u: pf_altq_v0__bindgen_ty_2,\n    pub qid: u32,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_altq_v0__bindgen_ty_1 {\n    pub tqe_next: *mut pf_altq_v0,\n    pub tqe_prev: *mut *mut pf_altq_v0,\n}\n#[test]\nfn bindgen_test_layout_pf_altq_v0__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_altq_v0__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_altq_v0__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_altq_v0__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_altq_v0__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_altq_v0__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqe_next) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_altq_v0__bindgen_ty_1),\n            \"::\",\n            stringify!(tqe_next)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqe_prev) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_altq_v0__bindgen_ty_1),\n            \"::\",\n            stringify!(tqe_prev)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pf_altq_v0__bindgen_ty_2 {\n    pub cbq_opts: cbq_opts,\n    pub codel_opts: codel_opts,\n    pub priq_opts: priq_opts,\n    pub hfsc_opts: hfsc_opts_v0,\n    pub fairq_opts: fairq_opts,\n}\n#[test]\nfn bindgen_test_layout_pf_altq_v0__bindgen_ty_2() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_altq_v0__bindgen_ty_2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_altq_v0__bindgen_ty_2>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(pf_altq_v0__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_altq_v0__bindgen_ty_2>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_altq_v0__bindgen_ty_2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cbq_opts) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_altq_v0__bindgen_ty_2),\n            \"::\",\n            stringify!(cbq_opts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).codel_opts) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_altq_v0__bindgen_ty_2),\n            \"::\",\n            stringify!(codel_opts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).priq_opts) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_altq_v0__bindgen_ty_2),\n            \"::\",\n            stringify!(priq_opts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).hfsc_opts) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_altq_v0__bindgen_ty_2),\n            \"::\",\n            stringify!(hfsc_opts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fairq_opts) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_altq_v0__bindgen_ty_2),\n            \"::\",\n            stringify!(fairq_opts)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_altq_v0() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_altq_v0> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_altq_v0>(),\n        240usize,\n        concat!(\"Size of: \", stringify!(pf_altq_v0))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_altq_v0>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_altq_v0))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifname) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq_v0), \"::\", stringify!(ifname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).unused1) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq_v0), \"::\", stringify!(unused1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).entries) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq_v0), \"::\", stringify!(entries))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scheduler) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq_v0), \"::\", stringify!(scheduler))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tbrsize) as usize - ptr as usize },\n        42usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq_v0), \"::\", stringify!(tbrsize))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifbandwidth) as usize - ptr as usize },\n        44usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_altq_v0),\n            \"::\",\n            stringify!(ifbandwidth)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).qname) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq_v0), \"::\", stringify!(qname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).parent) as usize - ptr as usize },\n        112usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq_v0), \"::\", stringify!(parent))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).parent_qid) as usize - ptr as usize },\n        176usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_altq_v0),\n            \"::\",\n            stringify!(parent_qid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).bandwidth) as usize - ptr as usize },\n        180usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq_v0), \"::\", stringify!(bandwidth))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).priority) as usize - ptr as usize },\n        184usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq_v0), \"::\", stringify!(priority))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).local_flags) as usize - ptr as usize },\n        185usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_altq_v0),\n            \"::\",\n            stringify!(local_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).qlimit) as usize - ptr as usize },\n        186usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq_v0), \"::\", stringify!(qlimit))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flags) as usize - ptr as usize },\n        188usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq_v0), \"::\", stringify!(flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pq_u) as usize - ptr as usize },\n        192usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq_v0), \"::\", stringify!(pq_u))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).qid) as usize - ptr as usize },\n        232usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq_v0), \"::\", stringify!(qid))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_altq_v1 {\n    pub ifname: [::std::os::raw::c_char; 16usize],\n    pub entries: pf_altq_v1__bindgen_ty_1,\n    pub scheduler: u8,\n    pub tbrsize: u32,\n    pub ifbandwidth: u64,\n    pub qname: [::std::os::raw::c_char; 64usize],\n    pub parent: [::std::os::raw::c_char; 64usize],\n    pub parent_qid: u32,\n    pub bandwidth: u64,\n    pub priority: u8,\n    pub local_flags: u8,\n    pub qlimit: u16,\n    pub flags: u16,\n    pub pq_u: pf_altq_v1__bindgen_ty_2,\n    pub qid: u32,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_altq_v1__bindgen_ty_1 {\n    pub tqe_next: *mut pf_altq_v1,\n    pub tqe_prev: *mut *mut pf_altq_v1,\n}\n#[test]\nfn bindgen_test_layout_pf_altq_v1__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_altq_v1__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_altq_v1__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_altq_v1__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_altq_v1__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_altq_v1__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqe_next) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_altq_v1__bindgen_ty_1),\n            \"::\",\n            stringify!(tqe_next)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqe_prev) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_altq_v1__bindgen_ty_1),\n            \"::\",\n            stringify!(tqe_prev)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pf_altq_v1__bindgen_ty_2 {\n    pub cbq_opts: cbq_opts,\n    pub codel_opts: codel_opts,\n    pub priq_opts: priq_opts,\n    pub hfsc_opts: hfsc_opts_v1,\n    pub fairq_opts: fairq_opts,\n}\n#[test]\nfn bindgen_test_layout_pf_altq_v1__bindgen_ty_2() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_altq_v1__bindgen_ty_2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_altq_v1__bindgen_ty_2>(),\n        80usize,\n        concat!(\"Size of: \", stringify!(pf_altq_v1__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_altq_v1__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_altq_v1__bindgen_ty_2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cbq_opts) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_altq_v1__bindgen_ty_2),\n            \"::\",\n            stringify!(cbq_opts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).codel_opts) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_altq_v1__bindgen_ty_2),\n            \"::\",\n            stringify!(codel_opts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).priq_opts) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_altq_v1__bindgen_ty_2),\n            \"::\",\n            stringify!(priq_opts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).hfsc_opts) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_altq_v1__bindgen_ty_2),\n            \"::\",\n            stringify!(hfsc_opts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fairq_opts) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_altq_v1__bindgen_ty_2),\n            \"::\",\n            stringify!(fairq_opts)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_altq_v1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_altq_v1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_altq_v1>(),\n        288usize,\n        concat!(\"Size of: \", stringify!(pf_altq_v1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_altq_v1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_altq_v1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifname) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq_v1), \"::\", stringify!(ifname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).entries) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq_v1), \"::\", stringify!(entries))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scheduler) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq_v1), \"::\", stringify!(scheduler))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tbrsize) as usize - ptr as usize },\n        36usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq_v1), \"::\", stringify!(tbrsize))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifbandwidth) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_altq_v1),\n            \"::\",\n            stringify!(ifbandwidth)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).qname) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq_v1), \"::\", stringify!(qname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).parent) as usize - ptr as usize },\n        112usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq_v1), \"::\", stringify!(parent))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).parent_qid) as usize - ptr as usize },\n        176usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_altq_v1),\n            \"::\",\n            stringify!(parent_qid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).bandwidth) as usize - ptr as usize },\n        184usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq_v1), \"::\", stringify!(bandwidth))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).priority) as usize - ptr as usize },\n        192usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq_v1), \"::\", stringify!(priority))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).local_flags) as usize - ptr as usize },\n        193usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_altq_v1),\n            \"::\",\n            stringify!(local_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).qlimit) as usize - ptr as usize },\n        194usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq_v1), \"::\", stringify!(qlimit))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flags) as usize - ptr as usize },\n        196usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq_v1), \"::\", stringify!(flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pq_u) as usize - ptr as usize },\n        200usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq_v1), \"::\", stringify!(pq_u))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).qid) as usize - ptr as usize },\n        280usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq_v1), \"::\", stringify!(qid))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_state_scrub {\n    pub pfss_last: timeval,\n    pub pfss_tsecr: u_int32_t,\n    pub pfss_tsval: u_int32_t,\n    pub pfss_tsval0: u_int32_t,\n    pub pfss_flags: u_int16_t,\n    pub pfss_ttl: u_int8_t,\n    pub pad: u_int8_t,\n    pub pfss_ts_mod: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_pf_state_scrub() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_state_scrub> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_state_scrub>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(pf_state_scrub))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_state_scrub>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_state_scrub))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfss_last) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_scrub),\n            \"::\",\n            stringify!(pfss_last)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfss_tsecr) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_scrub),\n            \"::\",\n            stringify!(pfss_tsecr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfss_tsval) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_scrub),\n            \"::\",\n            stringify!(pfss_tsval)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfss_tsval0) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_scrub),\n            \"::\",\n            stringify!(pfss_tsval0)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfss_flags) as usize - ptr as usize },\n        28usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_scrub),\n            \"::\",\n            stringify!(pfss_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfss_ttl) as usize - ptr as usize },\n        30usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_scrub),\n            \"::\",\n            stringify!(pfss_ttl)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pad) as usize - ptr as usize },\n        31usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_scrub), \"::\", stringify!(pad))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfss_ts_mod) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_scrub),\n            \"::\",\n            stringify!(pfss_ts_mod)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_state_host {\n    pub addr: pf_addr,\n    pub port: u_int16_t,\n    pub pad: u_int16_t,\n}\n#[test]\nfn bindgen_test_layout_pf_state_host() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_state_host> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_state_host>(),\n        20usize,\n        concat!(\"Size of: \", stringify!(pf_state_host))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_state_host>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_state_host))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_host), \"::\", stringify!(addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).port) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_host), \"::\", stringify!(port))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pad) as usize - ptr as usize },\n        18usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_host), \"::\", stringify!(pad))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_state_peer {\n    pub scrub: *mut pf_state_scrub,\n    pub seqlo: u_int32_t,\n    pub seqhi: u_int32_t,\n    pub seqdiff: u_int32_t,\n    pub max_win: u_int16_t,\n    pub mss: u_int16_t,\n    pub state: u_int8_t,\n    pub wscale: u_int8_t,\n    pub tcp_est: u_int8_t,\n    pub pad: [u_int8_t; 1usize],\n}\n#[test]\nfn bindgen_test_layout_pf_state_peer() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_state_peer> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_state_peer>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(pf_state_peer))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_state_peer>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_state_peer))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scrub) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_peer), \"::\", stringify!(scrub))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).seqlo) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_peer), \"::\", stringify!(seqlo))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).seqhi) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_peer), \"::\", stringify!(seqhi))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).seqdiff) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_peer),\n            \"::\",\n            stringify!(seqdiff)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_win) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_peer),\n            \"::\",\n            stringify!(max_win)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mss) as usize - ptr as usize },\n        22usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_peer), \"::\", stringify!(mss))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).state) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_peer), \"::\", stringify!(state))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).wscale) as usize - ptr as usize },\n        25usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_peer), \"::\", stringify!(wscale))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tcp_est) as usize - ptr as usize },\n        26usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_peer),\n            \"::\",\n            stringify!(tcp_est)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pad) as usize - ptr as usize },\n        27usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_peer), \"::\", stringify!(pad))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_state_key_cmp {\n    pub addr: [pf_addr; 2usize],\n    pub port: [u_int16_t; 2usize],\n    pub af: sa_family_t,\n    pub proto: u_int8_t,\n    pub pad: [u_int8_t; 2usize],\n}\n#[test]\nfn bindgen_test_layout_pf_state_key_cmp() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_state_key_cmp> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_state_key_cmp>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(pf_state_key_cmp))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_state_key_cmp>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_state_key_cmp))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_key_cmp),\n            \"::\",\n            stringify!(addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).port) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_key_cmp),\n            \"::\",\n            stringify!(port)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).af) as usize - ptr as usize },\n        36usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_key_cmp), \"::\", stringify!(af))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).proto) as usize - ptr as usize },\n        37usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_key_cmp),\n            \"::\",\n            stringify!(proto)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pad) as usize - ptr as usize },\n        38usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_key_cmp), \"::\", stringify!(pad))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_state_key {\n    pub addr: [pf_addr; 2usize],\n    pub port: [u_int16_t; 2usize],\n    pub af: sa_family_t,\n    pub proto: u_int8_t,\n    pub pad: [u_int8_t; 2usize],\n    pub entry: pf_state_key__bindgen_ty_1,\n    pub states: [pf_state_key__bindgen_ty_2; 2usize],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_state_key__bindgen_ty_1 {\n    pub le_next: *mut pf_state_key,\n    pub le_prev: *mut *mut pf_state_key,\n}\n#[test]\nfn bindgen_test_layout_pf_state_key__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_state_key__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_state_key__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_state_key__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_state_key__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_state_key__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).le_next) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_key__bindgen_ty_1),\n            \"::\",\n            stringify!(le_next)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).le_prev) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_key__bindgen_ty_1),\n            \"::\",\n            stringify!(le_prev)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_state_key__bindgen_ty_2 {\n    pub tqh_first: *mut pf_kstate,\n    pub tqh_last: *mut *mut pf_kstate,\n}\n#[test]\nfn bindgen_test_layout_pf_state_key__bindgen_ty_2() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_state_key__bindgen_ty_2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_state_key__bindgen_ty_2>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_state_key__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_state_key__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_state_key__bindgen_ty_2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqh_first) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_key__bindgen_ty_2),\n            \"::\",\n            stringify!(tqh_first)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqh_last) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_key__bindgen_ty_2),\n            \"::\",\n            stringify!(tqh_last)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_state_key() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_state_key> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_state_key>(),\n        88usize,\n        concat!(\"Size of: \", stringify!(pf_state_key))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_state_key>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_state_key))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_key), \"::\", stringify!(addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).port) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_key), \"::\", stringify!(port))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).af) as usize - ptr as usize },\n        36usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_key), \"::\", stringify!(af))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).proto) as usize - ptr as usize },\n        37usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_key), \"::\", stringify!(proto))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pad) as usize - ptr as usize },\n        38usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_key), \"::\", stringify!(pad))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).entry) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_key), \"::\", stringify!(entry))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).states) as usize - ptr as usize },\n        56usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_key), \"::\", stringify!(states))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_state_cmp {\n    pub id: u_int64_t,\n    pub creatorid: u_int32_t,\n    pub direction: u_int8_t,\n    pub pad: [u_int8_t; 3usize],\n}\n#[test]\nfn bindgen_test_layout_pf_state_cmp() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_state_cmp> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_state_cmp>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_state_cmp))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_state_cmp>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_state_cmp))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).id) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_cmp), \"::\", stringify!(id))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).creatorid) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_cmp),\n            \"::\",\n            stringify!(creatorid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).direction) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_cmp),\n            \"::\",\n            stringify!(direction)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pad) as usize - ptr as usize },\n        13usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_cmp), \"::\", stringify!(pad))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_state_scrub_export {\n    pub pfss_flags: u16,\n    pub pfss_ttl: u8,\n    pub scrub_flag: u8,\n    pub pfss_ts_mod: u32,\n}\n#[test]\nfn bindgen_test_layout_pf_state_scrub_export() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_state_scrub_export> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_state_scrub_export>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_state_scrub_export))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_state_scrub_export>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_state_scrub_export))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfss_flags) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_scrub_export),\n            \"::\",\n            stringify!(pfss_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfss_ttl) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_scrub_export),\n            \"::\",\n            stringify!(pfss_ttl)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scrub_flag) as usize - ptr as usize },\n        3usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_scrub_export),\n            \"::\",\n            stringify!(scrub_flag)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfss_ts_mod) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_scrub_export),\n            \"::\",\n            stringify!(pfss_ts_mod)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_state_key_export {\n    pub addr: [pf_addr; 2usize],\n    pub port: [u16; 2usize],\n}\n#[test]\nfn bindgen_test_layout_pf_state_key_export() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_state_key_export> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_state_key_export>(),\n        36usize,\n        concat!(\"Size of: \", stringify!(pf_state_key_export))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_state_key_export>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_state_key_export))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_key_export),\n            \"::\",\n            stringify!(addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).port) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_key_export),\n            \"::\",\n            stringify!(port)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_state_peer_export {\n    pub scrub: pf_state_scrub_export,\n    pub seqlo: u32,\n    pub seqhi: u32,\n    pub seqdiff: u32,\n    pub max_win: u16,\n    pub mss: u16,\n    pub state: u8,\n    pub wscale: u8,\n    pub dummy: [u8; 6usize],\n}\n#[test]\nfn bindgen_test_layout_pf_state_peer_export() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_state_peer_export> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_state_peer_export>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(pf_state_peer_export))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_state_peer_export>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_state_peer_export))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scrub) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_peer_export),\n            \"::\",\n            stringify!(scrub)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).seqlo) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_peer_export),\n            \"::\",\n            stringify!(seqlo)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).seqhi) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_peer_export),\n            \"::\",\n            stringify!(seqhi)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).seqdiff) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_peer_export),\n            \"::\",\n            stringify!(seqdiff)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_win) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_peer_export),\n            \"::\",\n            stringify!(max_win)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mss) as usize - ptr as usize },\n        22usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_peer_export),\n            \"::\",\n            stringify!(mss)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).state) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_peer_export),\n            \"::\",\n            stringify!(state)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).wscale) as usize - ptr as usize },\n        25usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_peer_export),\n            \"::\",\n            stringify!(wscale)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dummy) as usize - ptr as usize },\n        26usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_peer_export),\n            \"::\",\n            stringify!(dummy)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_state_export {\n    pub version: u64,\n    pub id: u64,\n    pub ifname: [::std::os::raw::c_char; 16usize],\n    pub orig_ifname: [::std::os::raw::c_char; 16usize],\n    pub key: [pf_state_key_export; 2usize],\n    pub src: pf_state_peer_export,\n    pub dst: pf_state_peer_export,\n    pub rt_addr: pf_addr,\n    pub rule: u32,\n    pub anchor: u32,\n    pub nat_rule: u32,\n    pub creation: u32,\n    pub expire: u32,\n    pub spare0: u32,\n    pub packets: [u64; 2usize],\n    pub bytes: [u64; 2usize],\n    pub creatorid: u32,\n    pub spare1: u32,\n    pub af: sa_family_t,\n    pub proto: u8,\n    pub direction: u8,\n    pub log: u8,\n    pub state_flags_compat: u8,\n    pub timeout: u8,\n    pub sync_flags: u8,\n    pub updates: u8,\n    pub state_flags: u16,\n    pub qid: u16,\n    pub pqid: u16,\n    pub dnpipe: u16,\n    pub dnrpipe: u16,\n    pub rtableid: i32,\n    pub min_ttl: u8,\n    pub set_tos: u8,\n    pub max_mss: u16,\n    pub set_prio: [u8; 2usize],\n    pub rt: u8,\n    pub rt_ifname: [::std::os::raw::c_char; 16usize],\n    pub spare: [u8; 72usize],\n}\n#[test]\nfn bindgen_test_layout_pf_state_export() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_state_export> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_state_export>(),\n        384usize,\n        concat!(\"Size of: \", stringify!(pf_state_export))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_state_export>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_state_export))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).version) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(version)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).id) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_export), \"::\", stringify!(id))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifname) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(ifname)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).orig_ifname) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(orig_ifname)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).key) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_export), \"::\", stringify!(key))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).src) as usize - ptr as usize },\n        120usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_export), \"::\", stringify!(src))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dst) as usize - ptr as usize },\n        152usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_export), \"::\", stringify!(dst))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rt_addr) as usize - ptr as usize },\n        184usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(rt_addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rule) as usize - ptr as usize },\n        200usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_export), \"::\", stringify!(rule))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor) as usize - ptr as usize },\n        204usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(anchor)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nat_rule) as usize - ptr as usize },\n        208usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(nat_rule)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).creation) as usize - ptr as usize },\n        212usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(creation)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).expire) as usize - ptr as usize },\n        216usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(expire)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).spare0) as usize - ptr as usize },\n        220usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(spare0)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).packets) as usize - ptr as usize },\n        224usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(packets)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).bytes) as usize - ptr as usize },\n        240usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(bytes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).creatorid) as usize - ptr as usize },\n        256usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(creatorid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).spare1) as usize - ptr as usize },\n        260usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(spare1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).af) as usize - ptr as usize },\n        264usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_export), \"::\", stringify!(af))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).proto) as usize - ptr as usize },\n        265usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(proto)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).direction) as usize - ptr as usize },\n        266usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(direction)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).log) as usize - ptr as usize },\n        267usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_export), \"::\", stringify!(log))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).state_flags_compat) as usize - ptr as usize },\n        268usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(state_flags_compat)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).timeout) as usize - ptr as usize },\n        269usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(timeout)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sync_flags) as usize - ptr as usize },\n        270usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(sync_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).updates) as usize - ptr as usize },\n        271usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(updates)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).state_flags) as usize - ptr as usize },\n        272usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(state_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).qid) as usize - ptr as usize },\n        274usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_export), \"::\", stringify!(qid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pqid) as usize - ptr as usize },\n        276usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_export), \"::\", stringify!(pqid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dnpipe) as usize - ptr as usize },\n        278usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(dnpipe)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dnrpipe) as usize - ptr as usize },\n        280usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(dnrpipe)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtableid) as usize - ptr as usize },\n        284usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(rtableid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).min_ttl) as usize - ptr as usize },\n        288usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(min_ttl)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).set_tos) as usize - ptr as usize },\n        289usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(set_tos)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_mss) as usize - ptr as usize },\n        290usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(max_mss)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).set_prio) as usize - ptr as usize },\n        292usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(set_prio)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rt) as usize - ptr as usize },\n        294usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_export), \"::\", stringify!(rt))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rt_ifname) as usize - ptr as usize },\n        295usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(rt_ifname)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).spare) as usize - ptr as usize },\n        311usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_export),\n            \"::\",\n            stringify!(spare)\n        )\n    );\n}\n#[repr(C, packed)]\n#[derive(Debug, Copy, Clone)]\npub struct pfsync_state_scrub {\n    pub pfss_flags: u_int16_t,\n    pub pfss_ttl: u_int8_t,\n    pub scrub_flag: u_int8_t,\n    pub pfss_ts_mod: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_pfsync_state_scrub() {\n    const UNINIT: ::std::mem::MaybeUninit<pfsync_state_scrub> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfsync_state_scrub>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pfsync_state_scrub))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfsync_state_scrub>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(pfsync_state_scrub))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfss_flags) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_scrub),\n            \"::\",\n            stringify!(pfss_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfss_ttl) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_scrub),\n            \"::\",\n            stringify!(pfss_ttl)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scrub_flag) as usize - ptr as usize },\n        3usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_scrub),\n            \"::\",\n            stringify!(scrub_flag)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfss_ts_mod) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_scrub),\n            \"::\",\n            stringify!(pfss_ts_mod)\n        )\n    );\n}\n#[repr(C, packed)]\n#[derive(Debug, Copy, Clone)]\npub struct pfsync_state_peer {\n    pub scrub: pfsync_state_scrub,\n    pub seqlo: u_int32_t,\n    pub seqhi: u_int32_t,\n    pub seqdiff: u_int32_t,\n    pub max_win: u_int16_t,\n    pub mss: u_int16_t,\n    pub state: u_int8_t,\n    pub wscale: u_int8_t,\n    pub pad: [u_int8_t; 6usize],\n}\n#[test]\nfn bindgen_test_layout_pfsync_state_peer() {\n    const UNINIT: ::std::mem::MaybeUninit<pfsync_state_peer> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfsync_state_peer>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(pfsync_state_peer))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfsync_state_peer>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(pfsync_state_peer))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scrub) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_peer),\n            \"::\",\n            stringify!(scrub)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).seqlo) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_peer),\n            \"::\",\n            stringify!(seqlo)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).seqhi) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_peer),\n            \"::\",\n            stringify!(seqhi)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).seqdiff) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_peer),\n            \"::\",\n            stringify!(seqdiff)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_win) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_peer),\n            \"::\",\n            stringify!(max_win)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mss) as usize - ptr as usize },\n        22usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_peer),\n            \"::\",\n            stringify!(mss)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).state) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_peer),\n            \"::\",\n            stringify!(state)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).wscale) as usize - ptr as usize },\n        25usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_peer),\n            \"::\",\n            stringify!(wscale)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pad) as usize - ptr as usize },\n        26usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_peer),\n            \"::\",\n            stringify!(pad)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfsync_state_key {\n    pub addr: [pf_addr; 2usize],\n    pub port: [u_int16_t; 2usize],\n}\n#[test]\nfn bindgen_test_layout_pfsync_state_key() {\n    const UNINIT: ::std::mem::MaybeUninit<pfsync_state_key> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfsync_state_key>(),\n        36usize,\n        concat!(\"Size of: \", stringify!(pfsync_state_key))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfsync_state_key>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pfsync_state_key))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_key),\n            \"::\",\n            stringify!(addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).port) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_key),\n            \"::\",\n            stringify!(port)\n        )\n    );\n}\n#[repr(C, packed)]\n#[derive(Copy, Clone)]\npub struct pfsync_state_1301 {\n    pub id: u_int64_t,\n    pub ifname: [::std::os::raw::c_char; 16usize],\n    pub key: [pfsync_state_key; 2usize],\n    pub src: pfsync_state_peer,\n    pub dst: pfsync_state_peer,\n    pub rt_addr: pf_addr,\n    pub rule: u_int32_t,\n    pub anchor: u_int32_t,\n    pub nat_rule: u_int32_t,\n    pub creation: u_int32_t,\n    pub expire: u_int32_t,\n    pub packets: [[u_int32_t; 2usize]; 2usize],\n    pub bytes: [[u_int32_t; 2usize]; 2usize],\n    pub creatorid: u_int32_t,\n    pub af: sa_family_t,\n    pub proto: u_int8_t,\n    pub direction: u_int8_t,\n    pub __spare: [u_int8_t; 2usize],\n    pub log: u_int8_t,\n    pub state_flags: u_int8_t,\n    pub timeout: u_int8_t,\n    pub sync_flags: u_int8_t,\n    pub updates: u_int8_t,\n}\n#[test]\nfn bindgen_test_layout_pfsync_state_1301() {\n    const UNINIT: ::std::mem::MaybeUninit<pfsync_state_1301> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfsync_state_1301>(),\n        242usize,\n        concat!(\"Size of: \", stringify!(pfsync_state_1301))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfsync_state_1301>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(pfsync_state_1301))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).id) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state_1301), \"::\", stringify!(id))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifname) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1301),\n            \"::\",\n            stringify!(ifname)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).key) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1301),\n            \"::\",\n            stringify!(key)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).src) as usize - ptr as usize },\n        96usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1301),\n            \"::\",\n            stringify!(src)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dst) as usize - ptr as usize },\n        128usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1301),\n            \"::\",\n            stringify!(dst)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rt_addr) as usize - ptr as usize },\n        160usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1301),\n            \"::\",\n            stringify!(rt_addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rule) as usize - ptr as usize },\n        176usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1301),\n            \"::\",\n            stringify!(rule)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor) as usize - ptr as usize },\n        180usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1301),\n            \"::\",\n            stringify!(anchor)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nat_rule) as usize - ptr as usize },\n        184usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1301),\n            \"::\",\n            stringify!(nat_rule)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).creation) as usize - ptr as usize },\n        188usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1301),\n            \"::\",\n            stringify!(creation)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).expire) as usize - ptr as usize },\n        192usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1301),\n            \"::\",\n            stringify!(expire)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).packets) as usize - ptr as usize },\n        196usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1301),\n            \"::\",\n            stringify!(packets)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).bytes) as usize - ptr as usize },\n        212usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1301),\n            \"::\",\n            stringify!(bytes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).creatorid) as usize - ptr as usize },\n        228usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1301),\n            \"::\",\n            stringify!(creatorid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).af) as usize - ptr as usize },\n        232usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state_1301), \"::\", stringify!(af))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).proto) as usize - ptr as usize },\n        233usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1301),\n            \"::\",\n            stringify!(proto)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).direction) as usize - ptr as usize },\n        234usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1301),\n            \"::\",\n            stringify!(direction)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__spare) as usize - ptr as usize },\n        235usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1301),\n            \"::\",\n            stringify!(__spare)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).log) as usize - ptr as usize },\n        237usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1301),\n            \"::\",\n            stringify!(log)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).state_flags) as usize - ptr as usize },\n        238usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1301),\n            \"::\",\n            stringify!(state_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).timeout) as usize - ptr as usize },\n        239usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1301),\n            \"::\",\n            stringify!(timeout)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sync_flags) as usize - ptr as usize },\n        240usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1301),\n            \"::\",\n            stringify!(sync_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).updates) as usize - ptr as usize },\n        241usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1301),\n            \"::\",\n            stringify!(updates)\n        )\n    );\n}\n#[repr(C, packed)]\n#[derive(Copy, Clone)]\npub struct pfsync_state_1400 {\n    pub id: u_int64_t,\n    pub ifname: [::std::os::raw::c_char; 16usize],\n    pub key: [pfsync_state_key; 2usize],\n    pub src: pfsync_state_peer,\n    pub dst: pfsync_state_peer,\n    pub rt_addr: pf_addr,\n    pub rule: u_int32_t,\n    pub anchor: u_int32_t,\n    pub nat_rule: u_int32_t,\n    pub creation: u_int32_t,\n    pub expire: u_int32_t,\n    pub packets: [[u_int32_t; 2usize]; 2usize],\n    pub bytes: [[u_int32_t; 2usize]; 2usize],\n    pub creatorid: u_int32_t,\n    pub af: sa_family_t,\n    pub proto: u_int8_t,\n    pub direction: u_int8_t,\n    pub state_flags: u_int16_t,\n    pub log: u_int8_t,\n    pub __spare: u_int8_t,\n    pub timeout: u_int8_t,\n    pub sync_flags: u_int8_t,\n    pub updates: u_int8_t,\n    pub qid: u_int16_t,\n    pub pqid: u_int16_t,\n    pub dnpipe: u_int16_t,\n    pub dnrpipe: u_int16_t,\n    pub rtableid: i32,\n    pub min_ttl: u_int8_t,\n    pub set_tos: u_int8_t,\n    pub max_mss: u_int16_t,\n    pub set_prio: [u_int8_t; 2usize],\n    pub rt: u_int8_t,\n    pub rt_ifname: [::std::os::raw::c_char; 16usize],\n}\n#[test]\nfn bindgen_test_layout_pfsync_state_1400() {\n    const UNINIT: ::std::mem::MaybeUninit<pfsync_state_1400> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfsync_state_1400>(),\n        277usize,\n        concat!(\"Size of: \", stringify!(pfsync_state_1400))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfsync_state_1400>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(pfsync_state_1400))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).id) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state_1400), \"::\", stringify!(id))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifname) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(ifname)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).key) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(key)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).src) as usize - ptr as usize },\n        96usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(src)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dst) as usize - ptr as usize },\n        128usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(dst)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rt_addr) as usize - ptr as usize },\n        160usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(rt_addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rule) as usize - ptr as usize },\n        176usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(rule)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor) as usize - ptr as usize },\n        180usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(anchor)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nat_rule) as usize - ptr as usize },\n        184usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(nat_rule)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).creation) as usize - ptr as usize },\n        188usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(creation)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).expire) as usize - ptr as usize },\n        192usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(expire)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).packets) as usize - ptr as usize },\n        196usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(packets)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).bytes) as usize - ptr as usize },\n        212usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(bytes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).creatorid) as usize - ptr as usize },\n        228usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(creatorid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).af) as usize - ptr as usize },\n        232usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state_1400), \"::\", stringify!(af))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).proto) as usize - ptr as usize },\n        233usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(proto)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).direction) as usize - ptr as usize },\n        234usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(direction)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).state_flags) as usize - ptr as usize },\n        235usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(state_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).log) as usize - ptr as usize },\n        237usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(log)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__spare) as usize - ptr as usize },\n        238usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(__spare)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).timeout) as usize - ptr as usize },\n        239usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(timeout)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sync_flags) as usize - ptr as usize },\n        240usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(sync_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).updates) as usize - ptr as usize },\n        241usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(updates)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).qid) as usize - ptr as usize },\n        242usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(qid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pqid) as usize - ptr as usize },\n        244usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(pqid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dnpipe) as usize - ptr as usize },\n        246usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(dnpipe)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dnrpipe) as usize - ptr as usize },\n        248usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(dnrpipe)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtableid) as usize - ptr as usize },\n        250usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(rtableid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).min_ttl) as usize - ptr as usize },\n        254usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(min_ttl)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).set_tos) as usize - ptr as usize },\n        255usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(set_tos)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_mss) as usize - ptr as usize },\n        256usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(max_mss)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).set_prio) as usize - ptr as usize },\n        258usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(set_prio)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rt) as usize - ptr as usize },\n        260usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state_1400), \"::\", stringify!(rt))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rt_ifname) as usize - ptr as usize },\n        261usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_1400),\n            \"::\",\n            stringify!(rt_ifname)\n        )\n    );\n}\n#[repr(C, packed)]\n#[derive(Copy, Clone)]\npub union pfsync_state_union {\n    pub pfs_1301: pfsync_state_1301,\n    pub pfs_1400: pfsync_state_1400,\n}\n#[test]\nfn bindgen_test_layout_pfsync_state_union() {\n    const UNINIT: ::std::mem::MaybeUninit<pfsync_state_union> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfsync_state_union>(),\n        277usize,\n        concat!(\"Size of: \", stringify!(pfsync_state_union))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfsync_state_union>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(pfsync_state_union))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfs_1301) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_union),\n            \"::\",\n            stringify!(pfs_1301)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfs_1400) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_union),\n            \"::\",\n            stringify!(pfs_1400)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_krulequeue {\n    pub tqh_first: *mut pf_krule,\n    pub tqh_last: *mut *mut pf_krule,\n}\n#[test]\nfn bindgen_test_layout_pf_krulequeue() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_krulequeue> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_krulequeue>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_krulequeue))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_krulequeue>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_krulequeue))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqh_first) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_krulequeue),\n            \"::\",\n            stringify!(tqh_first)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqh_last) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_krulequeue),\n            \"::\",\n            stringify!(tqh_last)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_kruleset {\n    pub rules: [pf_kruleset__bindgen_ty_1; 5usize],\n    pub anchor: *mut pf_kanchor,\n    pub tticket: u_int32_t,\n    pub tables: ::std::os::raw::c_int,\n    pub topen: ::std::os::raw::c_int,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_kruleset__bindgen_ty_1 {\n    pub queues: [pf_krulequeue; 2usize],\n    pub active: pf_kruleset__bindgen_ty_1__bindgen_ty_1,\n    pub inactive: pf_kruleset__bindgen_ty_1__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_kruleset__bindgen_ty_1__bindgen_ty_1 {\n    pub ptr: *mut pf_krulequeue,\n    pub ptr_array: *mut *mut pf_krule,\n    pub rcount: u_int32_t,\n    pub ticket: u_int32_t,\n    pub open: ::std::os::raw::c_int,\n    pub tree: *mut pf_krule_global,\n}\n#[test]\nfn bindgen_test_layout_pf_kruleset__bindgen_ty_1__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_kruleset__bindgen_ty_1__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_kruleset__bindgen_ty_1__bindgen_ty_1>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(pf_kruleset__bindgen_ty_1__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_kruleset__bindgen_ty_1__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_kruleset__bindgen_ty_1__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ptr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_kruleset__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(ptr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ptr_array) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_kruleset__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(ptr_array)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rcount) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_kruleset__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(rcount)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ticket) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_kruleset__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(ticket)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).open) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_kruleset__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(open)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tree) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_kruleset__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(tree)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_kruleset__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_kruleset__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_kruleset__bindgen_ty_1>(),\n        112usize,\n        concat!(\"Size of: \", stringify!(pf_kruleset__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_kruleset__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_kruleset__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).queues) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_kruleset__bindgen_ty_1),\n            \"::\",\n            stringify!(queues)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).active) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_kruleset__bindgen_ty_1),\n            \"::\",\n            stringify!(active)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).inactive) as usize - ptr as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_kruleset__bindgen_ty_1),\n            \"::\",\n            stringify!(inactive)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_kruleset() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_kruleset> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_kruleset>(),\n        584usize,\n        concat!(\"Size of: \", stringify!(pf_kruleset))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_kruleset>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_kruleset))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rules) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_kruleset), \"::\", stringify!(rules))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor) as usize - ptr as usize },\n        560usize,\n        concat!(\"Offset of field: \", stringify!(pf_kruleset), \"::\", stringify!(anchor))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tticket) as usize - ptr as usize },\n        568usize,\n        concat!(\"Offset of field: \", stringify!(pf_kruleset), \"::\", stringify!(tticket))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tables) as usize - ptr as usize },\n        572usize,\n        concat!(\"Offset of field: \", stringify!(pf_kruleset), \"::\", stringify!(tables))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).topen) as usize - ptr as usize },\n        576usize,\n        concat!(\"Offset of field: \", stringify!(pf_kruleset), \"::\", stringify!(topen))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_kanchor_global {\n    pub rbh_root: *mut pf_kanchor,\n}\n#[test]\nfn bindgen_test_layout_pf_kanchor_global() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_kanchor_global> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_kanchor_global>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_kanchor_global))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_kanchor_global>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_kanchor_global))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbh_root) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_kanchor_global),\n            \"::\",\n            stringify!(rbh_root)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_kanchor_node {\n    pub rbh_root: *mut pf_kanchor,\n}\n#[test]\nfn bindgen_test_layout_pf_kanchor_node() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_kanchor_node> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_kanchor_node>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_kanchor_node))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_kanchor_node>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_kanchor_node))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbh_root) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_kanchor_node),\n            \"::\",\n            stringify!(rbh_root)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_kanchor {\n    pub entry_global: pf_kanchor__bindgen_ty_1,\n    pub entry_node: pf_kanchor__bindgen_ty_2,\n    pub parent: *mut pf_kanchor,\n    pub children: pf_kanchor_node,\n    pub name: [::std::os::raw::c_char; 64usize],\n    pub path: [::std::os::raw::c_char; 1024usize],\n    pub ruleset: pf_kruleset,\n    pub refcnt: ::std::os::raw::c_int,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_kanchor__bindgen_ty_1 {\n    pub rbe_link: [*mut pf_kanchor; 3usize],\n}\n#[test]\nfn bindgen_test_layout_pf_kanchor__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_kanchor__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_kanchor__bindgen_ty_1>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(pf_kanchor__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_kanchor__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_kanchor__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_link) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_kanchor__bindgen_ty_1),\n            \"::\",\n            stringify!(rbe_link)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_kanchor__bindgen_ty_2 {\n    pub rbe_link: [*mut pf_kanchor; 3usize],\n}\n#[test]\nfn bindgen_test_layout_pf_kanchor__bindgen_ty_2() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_kanchor__bindgen_ty_2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_kanchor__bindgen_ty_2>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(pf_kanchor__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_kanchor__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_kanchor__bindgen_ty_2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_link) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_kanchor__bindgen_ty_2),\n            \"::\",\n            stringify!(rbe_link)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_kanchor() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_kanchor> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_kanchor>(),\n        1744usize,\n        concat!(\"Size of: \", stringify!(pf_kanchor))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_kanchor>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_kanchor))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).entry_global) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_kanchor),\n            \"::\",\n            stringify!(entry_global)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).entry_node) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_kanchor),\n            \"::\",\n            stringify!(entry_node)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).parent) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(pf_kanchor), \"::\", stringify!(parent))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).children) as usize - ptr as usize },\n        56usize,\n        concat!(\"Offset of field: \", stringify!(pf_kanchor), \"::\", stringify!(children))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).name) as usize - ptr as usize },\n        64usize,\n        concat!(\"Offset of field: \", stringify!(pf_kanchor), \"::\", stringify!(name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).path) as usize - ptr as usize },\n        128usize,\n        concat!(\"Offset of field: \", stringify!(pf_kanchor), \"::\", stringify!(path))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ruleset) as usize - ptr as usize },\n        1152usize,\n        concat!(\"Offset of field: \", stringify!(pf_kanchor), \"::\", stringify!(ruleset))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).refcnt) as usize - ptr as usize },\n        1736usize,\n        concat!(\"Offset of field: \", stringify!(pf_kanchor), \"::\", stringify!(refcnt))\n    );\n}\nunsafe extern \"C\" {\n    pub fn pf_kanchor_global_RB_INSERT_COLOR(\n        arg1: *mut pf_kanchor_global,\n        arg2: *mut pf_kanchor,\n        arg3: *mut pf_kanchor,\n    ) -> *mut pf_kanchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_kanchor_global_RB_REMOVE_COLOR(\n        arg1: *mut pf_kanchor_global,\n        arg2: *mut pf_kanchor,\n        arg3: *mut pf_kanchor,\n    ) -> *mut pf_kanchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_kanchor_global_RB_INSERT_FINISH(\n        arg1: *mut pf_kanchor_global,\n        arg2: *mut pf_kanchor,\n        arg3: *mut *mut pf_kanchor,\n        arg4: *mut pf_kanchor,\n    ) -> *mut pf_kanchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_kanchor_global_RB_INSERT(arg1: *mut pf_kanchor_global, arg2: *mut pf_kanchor) -> *mut pf_kanchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_kanchor_global_RB_REMOVE(arg1: *mut pf_kanchor_global, arg2: *mut pf_kanchor) -> *mut pf_kanchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_kanchor_global_RB_FIND(arg1: *mut pf_kanchor_global, arg2: *mut pf_kanchor) -> *mut pf_kanchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_kanchor_global_RB_NFIND(arg1: *mut pf_kanchor_global, arg2: *mut pf_kanchor) -> *mut pf_kanchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_kanchor_global_RB_NEXT(arg1: *mut pf_kanchor) -> *mut pf_kanchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_kanchor_global_RB_INSERT_NEXT(\n        arg1: *mut pf_kanchor_global,\n        arg2: *mut pf_kanchor,\n        arg3: *mut pf_kanchor,\n    ) -> *mut pf_kanchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_kanchor_global_RB_PREV(arg1: *mut pf_kanchor) -> *mut pf_kanchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_kanchor_global_RB_INSERT_PREV(\n        arg1: *mut pf_kanchor_global,\n        arg2: *mut pf_kanchor,\n        arg3: *mut pf_kanchor,\n    ) -> *mut pf_kanchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_kanchor_global_RB_MINMAX(arg1: *mut pf_kanchor_global, arg2: ::std::os::raw::c_int) -> *mut pf_kanchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_kanchor_global_RB_REINSERT(arg1: *mut pf_kanchor_global, arg2: *mut pf_kanchor) -> *mut pf_kanchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_kanchor_node_RB_INSERT_COLOR(\n        arg1: *mut pf_kanchor_node,\n        arg2: *mut pf_kanchor,\n        arg3: *mut pf_kanchor,\n    ) -> *mut pf_kanchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_kanchor_node_RB_REMOVE_COLOR(\n        arg1: *mut pf_kanchor_node,\n        arg2: *mut pf_kanchor,\n        arg3: *mut pf_kanchor,\n    ) -> *mut pf_kanchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_kanchor_node_RB_INSERT_FINISH(\n        arg1: *mut pf_kanchor_node,\n        arg2: *mut pf_kanchor,\n        arg3: *mut *mut pf_kanchor,\n        arg4: *mut pf_kanchor,\n    ) -> *mut pf_kanchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_kanchor_node_RB_INSERT(arg1: *mut pf_kanchor_node, arg2: *mut pf_kanchor) -> *mut pf_kanchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_kanchor_node_RB_REMOVE(arg1: *mut pf_kanchor_node, arg2: *mut pf_kanchor) -> *mut pf_kanchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_kanchor_node_RB_FIND(arg1: *mut pf_kanchor_node, arg2: *mut pf_kanchor) -> *mut pf_kanchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_kanchor_node_RB_NFIND(arg1: *mut pf_kanchor_node, arg2: *mut pf_kanchor) -> *mut pf_kanchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_kanchor_node_RB_NEXT(arg1: *mut pf_kanchor) -> *mut pf_kanchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_kanchor_node_RB_INSERT_NEXT(\n        arg1: *mut pf_kanchor_node,\n        arg2: *mut pf_kanchor,\n        arg3: *mut pf_kanchor,\n    ) -> *mut pf_kanchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_kanchor_node_RB_PREV(arg1: *mut pf_kanchor) -> *mut pf_kanchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_kanchor_node_RB_INSERT_PREV(\n        arg1: *mut pf_kanchor_node,\n        arg2: *mut pf_kanchor,\n        arg3: *mut pf_kanchor,\n    ) -> *mut pf_kanchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_kanchor_node_RB_MINMAX(arg1: *mut pf_kanchor_node, arg2: ::std::os::raw::c_int) -> *mut pf_kanchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_kanchor_node_RB_REINSERT(arg1: *mut pf_kanchor_node, arg2: *mut pf_kanchor) -> *mut pf_kanchor;\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_kanchor_stackframe {\n    _unused: [u8; 0],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_keth_anchor_stackframe {\n    _unused: [u8; 0],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfr_table {\n    pub pfrt_anchor: [::std::os::raw::c_char; 1024usize],\n    pub pfrt_name: [::std::os::raw::c_char; 32usize],\n    pub pfrt_flags: u_int32_t,\n    pub pfrt_fback: u_int8_t,\n}\n#[test]\nfn bindgen_test_layout_pfr_table() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_table> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_table>(),\n        1064usize,\n        concat!(\"Size of: \", stringify!(pfr_table))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_table>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pfr_table))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrt_anchor) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_table),\n            \"::\",\n            stringify!(pfrt_anchor)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrt_name) as usize - ptr as usize },\n        1024usize,\n        concat!(\"Offset of field: \", stringify!(pfr_table), \"::\", stringify!(pfrt_name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrt_flags) as usize - ptr as usize },\n        1056usize,\n        concat!(\"Offset of field: \", stringify!(pfr_table), \"::\", stringify!(pfrt_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrt_fback) as usize - ptr as usize },\n        1060usize,\n        concat!(\"Offset of field: \", stringify!(pfr_table), \"::\", stringify!(pfrt_fback))\n    );\n}\npub const PFR_FB_NONE: _bindgen_ty_15 = 0;\npub const PFR_FB_MATCH: _bindgen_ty_15 = 1;\npub const PFR_FB_ADDED: _bindgen_ty_15 = 2;\npub const PFR_FB_DELETED: _bindgen_ty_15 = 3;\npub const PFR_FB_CHANGED: _bindgen_ty_15 = 4;\npub const PFR_FB_CLEARED: _bindgen_ty_15 = 5;\npub const PFR_FB_DUPLICATE: _bindgen_ty_15 = 6;\npub const PFR_FB_NOTMATCH: _bindgen_ty_15 = 7;\npub const PFR_FB_CONFLICT: _bindgen_ty_15 = 8;\npub const PFR_FB_NOCOUNT: _bindgen_ty_15 = 9;\npub const PFR_FB_MAX: _bindgen_ty_15 = 10;\npub type _bindgen_ty_15 = ::std::os::raw::c_uint;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfr_addr {\n    pub pfra_u: pfr_addr__bindgen_ty_1,\n    pub pfra_af: u_int8_t,\n    pub pfra_net: u_int8_t,\n    pub pfra_not: u_int8_t,\n    pub pfra_fback: u_int8_t,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pfr_addr__bindgen_ty_1 {\n    pub _pfra_ip4addr: in_addr,\n    pub _pfra_ip6addr: in6_addr,\n}\n#[test]\nfn bindgen_test_layout_pfr_addr__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_addr__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_addr__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pfr_addr__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_addr__bindgen_ty_1>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pfr_addr__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._pfra_ip4addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(_pfra_ip4addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._pfra_ip6addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(_pfra_ip6addr)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pfr_addr() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_addr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_addr>(),\n        20usize,\n        concat!(\"Size of: \", stringify!(pfr_addr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_addr>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pfr_addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfra_u) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfr_addr), \"::\", stringify!(pfra_u))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfra_af) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pfr_addr), \"::\", stringify!(pfra_af))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfra_net) as usize - ptr as usize },\n        17usize,\n        concat!(\"Offset of field: \", stringify!(pfr_addr), \"::\", stringify!(pfra_net))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfra_not) as usize - ptr as usize },\n        18usize,\n        concat!(\"Offset of field: \", stringify!(pfr_addr), \"::\", stringify!(pfra_not))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfra_fback) as usize - ptr as usize },\n        19usize,\n        concat!(\"Offset of field: \", stringify!(pfr_addr), \"::\", stringify!(pfra_fback))\n    );\n}\npub const PFR_DIR_IN: _bindgen_ty_16 = 0;\npub const PFR_DIR_OUT: _bindgen_ty_16 = 1;\npub const PFR_DIR_MAX: _bindgen_ty_16 = 2;\npub type _bindgen_ty_16 = ::std::os::raw::c_uint;\npub const PFR_OP_BLOCK: _bindgen_ty_17 = 0;\npub const PFR_OP_PASS: _bindgen_ty_17 = 1;\npub const PFR_OP_ADDR_MAX: _bindgen_ty_17 = 2;\npub const PFR_OP_TABLE_MAX: _bindgen_ty_17 = 3;\npub type _bindgen_ty_17 = ::std::os::raw::c_uint;\npub const PFR_TYPE_PACKETS: _bindgen_ty_18 = 0;\npub const PFR_TYPE_BYTES: _bindgen_ty_18 = 1;\npub const PFR_TYPE_MAX: _bindgen_ty_18 = 2;\npub type _bindgen_ty_18 = ::std::os::raw::c_uint;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfr_astats {\n    pub pfras_a: pfr_addr,\n    pub pfras_packets: [[u_int64_t; 2usize]; 2usize],\n    pub pfras_bytes: [[u_int64_t; 2usize]; 2usize],\n    pub pfras_tzero: ::std::os::raw::c_long,\n}\n#[test]\nfn bindgen_test_layout_pfr_astats() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_astats> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_astats>(),\n        96usize,\n        concat!(\"Size of: \", stringify!(pfr_astats))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_astats>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfr_astats))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfras_a) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfr_astats), \"::\", stringify!(pfras_a))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfras_packets) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_astats),\n            \"::\",\n            stringify!(pfras_packets)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfras_bytes) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_astats),\n            \"::\",\n            stringify!(pfras_bytes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfras_tzero) as usize - ptr as usize },\n        88usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_astats),\n            \"::\",\n            stringify!(pfras_tzero)\n        )\n    );\n}\npub const PFR_REFCNT_RULE: _bindgen_ty_19 = 0;\npub const PFR_REFCNT_ANCHOR: _bindgen_ty_19 = 1;\npub const PFR_REFCNT_MAX: _bindgen_ty_19 = 2;\npub type _bindgen_ty_19 = ::std::os::raw::c_uint;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfr_tstats {\n    pub pfrts_t: pfr_table,\n    pub pfrts_packets: [[u_int64_t; 3usize]; 2usize],\n    pub pfrts_bytes: [[u_int64_t; 3usize]; 2usize],\n    pub pfrts_match: u_int64_t,\n    pub pfrts_nomatch: u_int64_t,\n    pub pfrts_tzero: ::std::os::raw::c_long,\n    pub pfrts_cnt: ::std::os::raw::c_int,\n    pub pfrts_refcnt: [::std::os::raw::c_int; 2usize],\n}\n#[test]\nfn bindgen_test_layout_pfr_tstats() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_tstats> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_tstats>(),\n        1200usize,\n        concat!(\"Size of: \", stringify!(pfr_tstats))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_tstats>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfr_tstats))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrts_t) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfr_tstats), \"::\", stringify!(pfrts_t))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrts_packets) as usize - ptr as usize },\n        1064usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_tstats),\n            \"::\",\n            stringify!(pfrts_packets)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrts_bytes) as usize - ptr as usize },\n        1112usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_tstats),\n            \"::\",\n            stringify!(pfrts_bytes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrts_match) as usize - ptr as usize },\n        1160usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_tstats),\n            \"::\",\n            stringify!(pfrts_match)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrts_nomatch) as usize - ptr as usize },\n        1168usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_tstats),\n            \"::\",\n            stringify!(pfrts_nomatch)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrts_tzero) as usize - ptr as usize },\n        1176usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_tstats),\n            \"::\",\n            stringify!(pfrts_tzero)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrts_cnt) as usize - ptr as usize },\n        1184usize,\n        concat!(\"Offset of field: \", stringify!(pfr_tstats), \"::\", stringify!(pfrts_cnt))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrts_refcnt) as usize - ptr as usize },\n        1188usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_tstats),\n            \"::\",\n            stringify!(pfrts_refcnt)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union sockaddr_union {\n    pub sa: sockaddr,\n    pub sin: sockaddr_in,\n    pub sin6: sockaddr_in6,\n}\n#[test]\nfn bindgen_test_layout_sockaddr_union() {\n    const UNINIT: ::std::mem::MaybeUninit<sockaddr_union> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sockaddr_union>(),\n        28usize,\n        concat!(\"Size of: \", stringify!(sockaddr_union))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sockaddr_union>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(sockaddr_union))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sa) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr_union), \"::\", stringify!(sa))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr_union), \"::\", stringify!(sin))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin6) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr_union), \"::\", stringify!(sin6))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfr_kcounters {\n    pub pfrkc_counters: counter_u64_t,\n    pub pfrkc_tzero: ::std::os::raw::c_long,\n}\n#[test]\nfn bindgen_test_layout_pfr_kcounters() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_kcounters> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_kcounters>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pfr_kcounters))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_kcounters>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfr_kcounters))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrkc_counters) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_kcounters),\n            \"::\",\n            stringify!(pfrkc_counters)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrkc_tzero) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_kcounters),\n            \"::\",\n            stringify!(pfrkc_tzero)\n        )\n    );\n}\npub const pf_syncookies_mode_PF_SYNCOOKIES_NEVER: pf_syncookies_mode = 0;\npub const pf_syncookies_mode_PF_SYNCOOKIES_ALWAYS: pf_syncookies_mode = 1;\npub const pf_syncookies_mode_PF_SYNCOOKIES_ADAPTIVE: pf_syncookies_mode = 2;\npub const pf_syncookies_mode_PF_SYNCOOKIES_MODE_MAX: pf_syncookies_mode = 2;\npub type pf_syncookies_mode = ::std::os::raw::c_uint;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_divert {\n    pub addr: pf_divert__bindgen_ty_1,\n    pub port: u_int16_t,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pf_divert__bindgen_ty_1 {\n    pub ipv4: in_addr,\n    pub ipv6: in6_addr,\n}\n#[test]\nfn bindgen_test_layout_pf_divert__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_divert__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_divert__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_divert__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_divert__bindgen_ty_1>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_divert__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ipv4) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_divert__bindgen_ty_1),\n            \"::\",\n            stringify!(ipv4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ipv6) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_divert__bindgen_ty_1),\n            \"::\",\n            stringify!(ipv6)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_divert() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_divert> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_divert>(),\n        20usize,\n        concat!(\"Size of: \", stringify!(pf_divert))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_divert>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_divert))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_divert), \"::\", stringify!(addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).port) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pf_divert), \"::\", stringify!(port))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_pooladdr {\n    pub action: u_int32_t,\n    pub ticket: u_int32_t,\n    pub nr: u_int32_t,\n    pub r_num: u_int32_t,\n    pub r_action: u_int8_t,\n    pub r_last: u_int8_t,\n    pub af: u_int8_t,\n    pub anchor: [::std::os::raw::c_char; 1024usize],\n    pub addr: pf_pooladdr,\n}\n#[test]\nfn bindgen_test_layout_pfioc_pooladdr() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_pooladdr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_pooladdr>(),\n        1136usize,\n        concat!(\"Size of: \", stringify!(pfioc_pooladdr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_pooladdr>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_pooladdr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).action) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_pooladdr),\n            \"::\",\n            stringify!(action)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ticket) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_pooladdr),\n            \"::\",\n            stringify!(ticket)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nr) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_pooladdr), \"::\", stringify!(nr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).r_num) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_pooladdr), \"::\", stringify!(r_num))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).r_action) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_pooladdr),\n            \"::\",\n            stringify!(r_action)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).r_last) as usize - ptr as usize },\n        17usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_pooladdr),\n            \"::\",\n            stringify!(r_last)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).af) as usize - ptr as usize },\n        18usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_pooladdr), \"::\", stringify!(af))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor) as usize - ptr as usize },\n        19usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_pooladdr),\n            \"::\",\n            stringify!(anchor)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        1048usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_pooladdr), \"::\", stringify!(addr))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_rule {\n    pub action: u_int32_t,\n    pub ticket: u_int32_t,\n    pub pool_ticket: u_int32_t,\n    pub nr: u_int32_t,\n    pub anchor: [::std::os::raw::c_char; 1024usize],\n    pub anchor_call: [::std::os::raw::c_char; 1024usize],\n    pub rule: pf_rule,\n}\n#[test]\nfn bindgen_test_layout_pfioc_rule() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_rule> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_rule>(),\n        3040usize,\n        concat!(\"Size of: \", stringify!(pfioc_rule))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_rule>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_rule))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).action) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_rule), \"::\", stringify!(action))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ticket) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_rule), \"::\", stringify!(ticket))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pool_ticket) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_rule),\n            \"::\",\n            stringify!(pool_ticket)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nr) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_rule), \"::\", stringify!(nr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_rule), \"::\", stringify!(anchor))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor_call) as usize - ptr as usize },\n        1040usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_rule),\n            \"::\",\n            stringify!(anchor_call)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rule) as usize - ptr as usize },\n        2064usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_rule), \"::\", stringify!(rule))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_natlook {\n    pub saddr: pf_addr,\n    pub daddr: pf_addr,\n    pub rsaddr: pf_addr,\n    pub rdaddr: pf_addr,\n    pub sport: u_int16_t,\n    pub dport: u_int16_t,\n    pub rsport: u_int16_t,\n    pub rdport: u_int16_t,\n    pub af: sa_family_t,\n    pub proto: u_int8_t,\n    pub direction: u_int8_t,\n}\n#[test]\nfn bindgen_test_layout_pfioc_natlook() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_natlook> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_natlook>(),\n        76usize,\n        concat!(\"Size of: \", stringify!(pfioc_natlook))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_natlook>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pfioc_natlook))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).saddr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_natlook), \"::\", stringify!(saddr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).daddr) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_natlook), \"::\", stringify!(daddr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rsaddr) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_natlook), \"::\", stringify!(rsaddr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rdaddr) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_natlook), \"::\", stringify!(rdaddr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sport) as usize - ptr as usize },\n        64usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_natlook), \"::\", stringify!(sport))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dport) as usize - ptr as usize },\n        66usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_natlook), \"::\", stringify!(dport))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rsport) as usize - ptr as usize },\n        68usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_natlook), \"::\", stringify!(rsport))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rdport) as usize - ptr as usize },\n        70usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_natlook), \"::\", stringify!(rdport))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).af) as usize - ptr as usize },\n        72usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_natlook), \"::\", stringify!(af))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).proto) as usize - ptr as usize },\n        73usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_natlook), \"::\", stringify!(proto))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).direction) as usize - ptr as usize },\n        74usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_natlook),\n            \"::\",\n            stringify!(direction)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_state {\n    pub state: pfsync_state_1301,\n}\n#[test]\nfn bindgen_test_layout_pfioc_state() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_state> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_state>(),\n        242usize,\n        concat!(\"Size of: \", stringify!(pfioc_state))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_state>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(pfioc_state))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).state) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_state), \"::\", stringify!(state))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_src_node_kill {\n    pub psnk_af: sa_family_t,\n    pub psnk_src: pf_rule_addr,\n    pub psnk_dst: pf_rule_addr,\n    pub psnk_killed: u_int,\n}\n#[test]\nfn bindgen_test_layout_pfioc_src_node_kill() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_src_node_kill> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_src_node_kill>(),\n        128usize,\n        concat!(\"Size of: \", stringify!(pfioc_src_node_kill))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_src_node_kill>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_src_node_kill))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psnk_af) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_src_node_kill),\n            \"::\",\n            stringify!(psnk_af)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psnk_src) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_src_node_kill),\n            \"::\",\n            stringify!(psnk_src)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psnk_dst) as usize - ptr as usize },\n        64usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_src_node_kill),\n            \"::\",\n            stringify!(psnk_dst)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psnk_killed) as usize - ptr as usize },\n        120usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_src_node_kill),\n            \"::\",\n            stringify!(psnk_killed)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_state_kill {\n    pub psk_pfcmp: pf_state_cmp,\n    pub psk_af: sa_family_t,\n    pub psk_proto: ::std::os::raw::c_int,\n    pub psk_src: pf_rule_addr,\n    pub psk_dst: pf_rule_addr,\n    pub psk_ifname: [::std::os::raw::c_char; 16usize],\n    pub psk_label: [::std::os::raw::c_char; 64usize],\n    pub psk_killed: u_int,\n}\n#[test]\nfn bindgen_test_layout_pfioc_state_kill() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_state_kill> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_state_kill>(),\n        224usize,\n        concat!(\"Size of: \", stringify!(pfioc_state_kill))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_state_kill>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_state_kill))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psk_pfcmp) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_kill),\n            \"::\",\n            stringify!(psk_pfcmp)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psk_af) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_kill),\n            \"::\",\n            stringify!(psk_af)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psk_proto) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_kill),\n            \"::\",\n            stringify!(psk_proto)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psk_src) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_kill),\n            \"::\",\n            stringify!(psk_src)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psk_dst) as usize - ptr as usize },\n        80usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_kill),\n            \"::\",\n            stringify!(psk_dst)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psk_ifname) as usize - ptr as usize },\n        136usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_kill),\n            \"::\",\n            stringify!(psk_ifname)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psk_label) as usize - ptr as usize },\n        152usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_kill),\n            \"::\",\n            stringify!(psk_label)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psk_killed) as usize - ptr as usize },\n        216usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_kill),\n            \"::\",\n            stringify!(psk_killed)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_states {\n    pub ps_len: ::std::os::raw::c_int,\n    pub __bindgen_anon_1: pfioc_states__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pfioc_states__bindgen_ty_1 {\n    pub ps_buf: *mut ::std::os::raw::c_void,\n    pub ps_states: *mut pfsync_state_1301,\n}\n#[test]\nfn bindgen_test_layout_pfioc_states__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_states__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_states__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pfioc_states__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_states__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_states__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ps_buf) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_states__bindgen_ty_1),\n            \"::\",\n            stringify!(ps_buf)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ps_states) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_states__bindgen_ty_1),\n            \"::\",\n            stringify!(ps_states)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pfioc_states() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_states> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_states>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pfioc_states))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_states>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_states))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ps_len) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_states), \"::\", stringify!(ps_len))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_states_v2 {\n    pub ps_len: ::std::os::raw::c_int,\n    pub ps_req_version: u64,\n    pub __bindgen_anon_1: pfioc_states_v2__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pfioc_states_v2__bindgen_ty_1 {\n    pub ps_buf: *mut ::std::os::raw::c_void,\n    pub ps_states: *mut pf_state_export,\n}\n#[test]\nfn bindgen_test_layout_pfioc_states_v2__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_states_v2__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_states_v2__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pfioc_states_v2__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_states_v2__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_states_v2__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ps_buf) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_states_v2__bindgen_ty_1),\n            \"::\",\n            stringify!(ps_buf)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ps_states) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_states_v2__bindgen_ty_1),\n            \"::\",\n            stringify!(ps_states)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pfioc_states_v2() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_states_v2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_states_v2>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(pfioc_states_v2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_states_v2>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_states_v2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ps_len) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_states_v2),\n            \"::\",\n            stringify!(ps_len)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ps_req_version) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_states_v2),\n            \"::\",\n            stringify!(ps_req_version)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_src_nodes {\n    pub psn_len: ::std::os::raw::c_int,\n    pub __bindgen_anon_1: pfioc_src_nodes__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pfioc_src_nodes__bindgen_ty_1 {\n    pub psn_buf: *mut ::std::os::raw::c_void,\n    pub psn_src_nodes: *mut pf_src_node,\n}\n#[test]\nfn bindgen_test_layout_pfioc_src_nodes__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_src_nodes__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_src_nodes__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pfioc_src_nodes__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_src_nodes__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_src_nodes__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psn_buf) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_src_nodes__bindgen_ty_1),\n            \"::\",\n            stringify!(psn_buf)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psn_src_nodes) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_src_nodes__bindgen_ty_1),\n            \"::\",\n            stringify!(psn_src_nodes)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pfioc_src_nodes() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_src_nodes> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_src_nodes>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pfioc_src_nodes))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_src_nodes>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_src_nodes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psn_len) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_src_nodes),\n            \"::\",\n            stringify!(psn_len)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_if {\n    pub ifname: [::std::os::raw::c_char; 16usize],\n}\n#[test]\nfn bindgen_test_layout_pfioc_if() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_if> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_if>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pfioc_if))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_if>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(pfioc_if))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifname) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_if), \"::\", stringify!(ifname))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_tm {\n    pub timeout: ::std::os::raw::c_int,\n    pub seconds: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_pfioc_tm() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_tm> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_tm>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pfioc_tm))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_tm>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pfioc_tm))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).timeout) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_tm), \"::\", stringify!(timeout))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).seconds) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_tm), \"::\", stringify!(seconds))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_limit {\n    pub index: ::std::os::raw::c_int,\n    pub limit: ::std::os::raw::c_uint,\n}\n#[test]\nfn bindgen_test_layout_pfioc_limit() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_limit> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_limit>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pfioc_limit))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_limit>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pfioc_limit))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).index) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_limit), \"::\", stringify!(index))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).limit) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_limit), \"::\", stringify!(limit))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_altq_v0 {\n    pub action: u_int32_t,\n    pub ticket: u_int32_t,\n    pub nr: u_int32_t,\n    pub altq: pf_altq_v0,\n}\n#[test]\nfn bindgen_test_layout_pfioc_altq_v0() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_altq_v0> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_altq_v0>(),\n        256usize,\n        concat!(\"Size of: \", stringify!(pfioc_altq_v0))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_altq_v0>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_altq_v0))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).action) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_altq_v0), \"::\", stringify!(action))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ticket) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_altq_v0), \"::\", stringify!(ticket))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nr) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_altq_v0), \"::\", stringify!(nr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).altq) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_altq_v0), \"::\", stringify!(altq))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_altq_v1 {\n    pub action: u_int32_t,\n    pub ticket: u_int32_t,\n    pub nr: u_int32_t,\n    pub version: u_int32_t,\n    pub altq: pf_altq_v1,\n}\n#[test]\nfn bindgen_test_layout_pfioc_altq_v1() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_altq_v1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_altq_v1>(),\n        304usize,\n        concat!(\"Size of: \", stringify!(pfioc_altq_v1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_altq_v1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_altq_v1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).action) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_altq_v1), \"::\", stringify!(action))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ticket) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_altq_v1), \"::\", stringify!(ticket))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nr) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_altq_v1), \"::\", stringify!(nr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).version) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_altq_v1),\n            \"::\",\n            stringify!(version)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).altq) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_altq_v1), \"::\", stringify!(altq))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_qstats_v0 {\n    pub ticket: u_int32_t,\n    pub nr: u_int32_t,\n    pub buf: *mut ::std::os::raw::c_void,\n    pub nbytes: ::std::os::raw::c_int,\n    pub scheduler: u_int8_t,\n}\n#[test]\nfn bindgen_test_layout_pfioc_qstats_v0() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_qstats_v0> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_qstats_v0>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(pfioc_qstats_v0))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_qstats_v0>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_qstats_v0))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ticket) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_qstats_v0),\n            \"::\",\n            stringify!(ticket)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nr) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_qstats_v0), \"::\", stringify!(nr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).buf) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_qstats_v0), \"::\", stringify!(buf))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nbytes) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_qstats_v0),\n            \"::\",\n            stringify!(nbytes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scheduler) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_qstats_v0),\n            \"::\",\n            stringify!(scheduler)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_qstats_v1 {\n    pub ticket: u_int32_t,\n    pub nr: u_int32_t,\n    pub buf: *mut ::std::os::raw::c_void,\n    pub nbytes: ::std::os::raw::c_int,\n    pub scheduler: u_int8_t,\n    pub version: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_pfioc_qstats_v1() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_qstats_v1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_qstats_v1>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(pfioc_qstats_v1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_qstats_v1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_qstats_v1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ticket) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_qstats_v1),\n            \"::\",\n            stringify!(ticket)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nr) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_qstats_v1), \"::\", stringify!(nr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).buf) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_qstats_v1), \"::\", stringify!(buf))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nbytes) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_qstats_v1),\n            \"::\",\n            stringify!(nbytes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scheduler) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_qstats_v1),\n            \"::\",\n            stringify!(scheduler)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).version) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_qstats_v1),\n            \"::\",\n            stringify!(version)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_ruleset {\n    pub nr: u_int32_t,\n    pub path: [::std::os::raw::c_char; 1024usize],\n    pub name: [::std::os::raw::c_char; 64usize],\n}\n#[test]\nfn bindgen_test_layout_pfioc_ruleset() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_ruleset> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_ruleset>(),\n        1092usize,\n        concat!(\"Size of: \", stringify!(pfioc_ruleset))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_ruleset>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pfioc_ruleset))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_ruleset), \"::\", stringify!(nr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).path) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_ruleset), \"::\", stringify!(path))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).name) as usize - ptr as usize },\n        1028usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_ruleset), \"::\", stringify!(name))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_trans {\n    pub size: ::std::os::raw::c_int,\n    pub esize: ::std::os::raw::c_int,\n    pub array: *mut pfioc_trans_pfioc_trans_e,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_trans_pfioc_trans_e {\n    pub rs_num: ::std::os::raw::c_int,\n    pub anchor: [::std::os::raw::c_char; 1024usize],\n    pub ticket: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_pfioc_trans_pfioc_trans_e() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_trans_pfioc_trans_e> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_trans_pfioc_trans_e>(),\n        1032usize,\n        concat!(\"Size of: \", stringify!(pfioc_trans_pfioc_trans_e))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_trans_pfioc_trans_e>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pfioc_trans_pfioc_trans_e))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rs_num) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_trans_pfioc_trans_e),\n            \"::\",\n            stringify!(rs_num)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_trans_pfioc_trans_e),\n            \"::\",\n            stringify!(anchor)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ticket) as usize - ptr as usize },\n        1028usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_trans_pfioc_trans_e),\n            \"::\",\n            stringify!(ticket)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pfioc_trans() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_trans> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_trans>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pfioc_trans))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_trans>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_trans))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).size) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_trans), \"::\", stringify!(size))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).esize) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_trans), \"::\", stringify!(esize))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).array) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_trans), \"::\", stringify!(array))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_table {\n    pub pfrio_table: pfr_table,\n    pub pfrio_buffer: *mut ::std::os::raw::c_void,\n    pub pfrio_esize: ::std::os::raw::c_int,\n    pub pfrio_size: ::std::os::raw::c_int,\n    pub pfrio_size2: ::std::os::raw::c_int,\n    pub pfrio_nadd: ::std::os::raw::c_int,\n    pub pfrio_ndel: ::std::os::raw::c_int,\n    pub pfrio_nchange: ::std::os::raw::c_int,\n    pub pfrio_flags: ::std::os::raw::c_int,\n    pub pfrio_ticket: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_pfioc_table() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_table> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_table>(),\n        1104usize,\n        concat!(\"Size of: \", stringify!(pfioc_table))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_table>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_table))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_table) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_table)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_buffer) as usize - ptr as usize },\n        1064usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_buffer)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_esize) as usize - ptr as usize },\n        1072usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_esize)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_size) as usize - ptr as usize },\n        1076usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_size)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_size2) as usize - ptr as usize },\n        1080usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_size2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_nadd) as usize - ptr as usize },\n        1084usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_nadd)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_ndel) as usize - ptr as usize },\n        1088usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_ndel)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_nchange) as usize - ptr as usize },\n        1092usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_nchange)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_flags) as usize - ptr as usize },\n        1096usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_ticket) as usize - ptr as usize },\n        1100usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_ticket)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_iface {\n    pub pfiio_name: [::std::os::raw::c_char; 16usize],\n    pub pfiio_buffer: *mut ::std::os::raw::c_void,\n    pub pfiio_esize: ::std::os::raw::c_int,\n    pub pfiio_size: ::std::os::raw::c_int,\n    pub pfiio_nzero: ::std::os::raw::c_int,\n    pub pfiio_flags: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_pfioc_iface() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_iface> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_iface>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(pfioc_iface))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_iface>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_iface))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfiio_name) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_iface),\n            \"::\",\n            stringify!(pfiio_name)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfiio_buffer) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_iface),\n            \"::\",\n            stringify!(pfiio_buffer)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfiio_esize) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_iface),\n            \"::\",\n            stringify!(pfiio_esize)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfiio_size) as usize - ptr as usize },\n        28usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_iface),\n            \"::\",\n            stringify!(pfiio_size)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfiio_nzero) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_iface),\n            \"::\",\n            stringify!(pfiio_nzero)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfiio_flags) as usize - ptr as usize },\n        36usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_iface),\n            \"::\",\n            stringify!(pfiio_flags)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_ifspeed_v0 {\n    pub ifname: [::std::os::raw::c_char; 16usize],\n    pub baudrate: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_pf_ifspeed_v0() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_ifspeed_v0> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_ifspeed_v0>(),\n        20usize,\n        concat!(\"Size of: \", stringify!(pf_ifspeed_v0))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_ifspeed_v0>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_ifspeed_v0))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifname) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_ifspeed_v0), \"::\", stringify!(ifname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).baudrate) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_ifspeed_v0),\n            \"::\",\n            stringify!(baudrate)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_ifspeed_v1 {\n    pub ifname: [::std::os::raw::c_char; 16usize],\n    pub baudrate32: u_int32_t,\n    pub baudrate: u_int64_t,\n}\n#[test]\nfn bindgen_test_layout_pf_ifspeed_v1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_ifspeed_v1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_ifspeed_v1>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(pf_ifspeed_v1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_ifspeed_v1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_ifspeed_v1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifname) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_ifspeed_v1), \"::\", stringify!(ifname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).baudrate32) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_ifspeed_v1),\n            \"::\",\n            stringify!(baudrate32)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).baudrate) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_ifspeed_v1),\n            \"::\",\n            stringify!(baudrate)\n        )\n    );\n}\nunsafe extern \"C\" {\n    pub fn pf_osfp_add(arg1: *mut pf_osfp_ioctl) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn pf_osfp_flush();\n}\nunsafe extern \"C\" {\n    pub fn pf_osfp_get(arg1: *mut pf_osfp_ioctl) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn pf_osfp_match(arg1: *mut pf_os_fingerprint_pf_osfp_enlist, arg2: pf_osfp_t) -> ::std::os::raw::c_int;\n}\npub type __builtin_va_list = [__va_list_tag; 1usize];\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __va_list_tag {\n    pub gp_offset: ::std::os::raw::c_uint,\n    pub fp_offset: ::std::os::raw::c_uint,\n    pub overflow_arg_area: *mut ::std::os::raw::c_void,\n    pub reg_save_area: *mut ::std::os::raw::c_void,\n}\n#[test]\nfn bindgen_test_layout___va_list_tag() {\n    const UNINIT: ::std::mem::MaybeUninit<__va_list_tag> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__va_list_tag>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(__va_list_tag))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__va_list_tag>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__va_list_tag))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).gp_offset) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__va_list_tag),\n            \"::\",\n            stringify!(gp_offset)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_offset) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__va_list_tag),\n            \"::\",\n            stringify!(fp_offset)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).overflow_arg_area) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__va_list_tag),\n            \"::\",\n            stringify!(overflow_arg_area)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).reg_save_area) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__va_list_tag),\n            \"::\",\n            stringify!(reg_save_area)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct witness {\n    pub _address: u8,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct llentry {\n    pub _address: u8,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ifg_group {\n    pub _address: u8,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfi_dynaddr {\n    pub _address: u8,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfr_ktable {\n    pub _address: u8,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_kstate {\n    pub _address: u8,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_krule {\n    pub _address: u8,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_krule_global {\n    pub _address: u8,\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/redir/sys/unix/pfvar_bindgen_macos.rs",
    "content": "// automatically generated by rust-bindgen 0.69.2\n\n#[repr(C)]\n#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]\npub struct __BindgenBitfieldUnit<Storage> {\n    storage: Storage,\n}\nimpl<Storage> __BindgenBitfieldUnit<Storage> {\n    #[inline]\n    pub const fn new(storage: Storage) -> Self {\n        Self { storage }\n    }\n}\nimpl<Storage> __BindgenBitfieldUnit<Storage>\nwhere\n    Storage: AsRef<[u8]> + AsMut<[u8]>,\n{\n    #[inline]\n    pub fn get_bit(&self, index: usize) -> bool {\n        debug_assert!(index / 8 < self.storage.as_ref().len());\n        let byte_index = index / 8;\n        let byte = self.storage.as_ref()[byte_index];\n        let bit_index = if cfg!(target_endian = \"big\") {\n            7 - (index % 8)\n        } else {\n            index % 8\n        };\n        let mask = 1 << bit_index;\n        byte & mask == mask\n    }\n\n    #[inline]\n    pub fn set_bit(&mut self, index: usize, val: bool) {\n        debug_assert!(index / 8 < self.storage.as_ref().len());\n        let byte_index = index / 8;\n        let byte = &mut self.storage.as_mut()[byte_index];\n        let bit_index = if cfg!(target_endian = \"big\") {\n            7 - (index % 8)\n        } else {\n            index % 8\n        };\n        let mask = 1 << bit_index;\n        if val {\n            *byte |= mask;\n        } else {\n            *byte &= !mask;\n        }\n    }\n\n    #[inline]\n    pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 {\n        debug_assert!(bit_width <= 64);\n        debug_assert!(bit_offset / 8 < self.storage.as_ref().len());\n        debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len());\n        let mut val = 0;\n        for i in 0..(bit_width as usize) {\n            if self.get_bit(i + bit_offset) {\n                let index = if cfg!(target_endian = \"big\") {\n                    bit_width as usize - 1 - i\n                } else {\n                    i\n                };\n                val |= 1 << index;\n            }\n        }\n        val\n    }\n\n    #[inline]\n    pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) {\n        debug_assert!(bit_width <= 64);\n        debug_assert!(bit_offset / 8 < self.storage.as_ref().len());\n        debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len());\n        for i in 0..(bit_width as usize) {\n            let mask = 1 << i;\n            let val_bit_is_set = val & mask == mask;\n            let index = if cfg!(target_endian = \"big\") {\n                bit_width as usize - 1 - i\n            } else {\n                i\n            };\n            self.set_bit(index + bit_offset, val_bit_is_set);\n        }\n    }\n}\npub const __bool_true_false_are_defined: u32 = 1;\npub const true_: u32 = 1;\npub const false_: u32 = 0;\npub const BSD: u32 = 199506;\npub const BSD4_3: u32 = 1;\npub const BSD4_4: u32 = 1;\npub const NeXTBSD: u32 = 1995064;\npub const NeXTBSD4_0: u32 = 0;\npub const __DARWIN_UNIX03: u32 = 1;\npub const __DARWIN_64_BIT_INO_T: u32 = 1;\npub const __DARWIN_VERS_1050: u32 = 1;\npub const __DARWIN_NON_CANCELABLE: u32 = 0;\npub const __DARWIN_SUF_UNIX03: &[u8; 10] = b\"$UNIX2003\\0\";\npub const __DARWIN_SUF_64_BIT_INO_T: &[u8; 9] = b\"$INODE64\\0\";\npub const __DARWIN_SUF_1050: &[u8; 6] = b\"$1050\\0\";\npub const __DARWIN_SUF_EXTSN: &[u8; 14] = b\"$DARWIN_EXTSN\\0\";\npub const __DARWIN_C_ANSI: u32 = 4096;\npub const __DARWIN_C_FULL: u32 = 900000;\npub const __DARWIN_C_LEVEL: u32 = 900000;\npub const __STDC_WANT_LIB_EXT1__: u32 = 1;\npub const __DARWIN_NO_LONG_LONG: u32 = 0;\npub const _DARWIN_FEATURE_64_BIT_INODE: u32 = 1;\npub const _DARWIN_FEATURE_UNIX_CONFORMANCE: u32 = 3;\npub const __PTHREAD_SIZE__: u32 = 8176;\npub const __PTHREAD_ATTR_SIZE__: u32 = 56;\npub const __PTHREAD_MUTEXATTR_SIZE__: u32 = 8;\npub const __PTHREAD_MUTEX_SIZE__: u32 = 56;\npub const __PTHREAD_CONDATTR_SIZE__: u32 = 8;\npub const __PTHREAD_COND_SIZE__: u32 = 40;\npub const __PTHREAD_ONCE_SIZE__: u32 = 8;\npub const __PTHREAD_RWLOCK_SIZE__: u32 = 192;\npub const __PTHREAD_RWLOCKATTR_SIZE__: u32 = 16;\npub const _QUAD_HIGHWORD: u32 = 1;\npub const _QUAD_LOWWORD: u32 = 0;\npub const __DARWIN_LITTLE_ENDIAN: u32 = 1234;\npub const __DARWIN_BIG_ENDIAN: u32 = 4321;\npub const __DARWIN_PDP_ENDIAN: u32 = 3412;\npub const __DARWIN_BYTE_ORDER: u32 = 1234;\npub const LITTLE_ENDIAN: u32 = 1234;\npub const BIG_ENDIAN: u32 = 4321;\npub const PDP_ENDIAN: u32 = 3412;\npub const BYTE_ORDER: u32 = 1234;\npub const __API_TO_BE_DEPRECATED: u32 = 100000;\npub const __API_TO_BE_DEPRECATED_MACOS: u32 = 100000;\npub const __API_TO_BE_DEPRECATED_IOS: u32 = 100000;\npub const __API_TO_BE_DEPRECATED_MACCATALYST: u32 = 100000;\npub const __API_TO_BE_DEPRECATED_WATCHOS: u32 = 100000;\npub const __API_TO_BE_DEPRECATED_TVOS: u32 = 100000;\npub const __API_TO_BE_DEPRECATED_DRIVERKIT: u32 = 100000;\npub const __API_TO_BE_DEPRECATED_VISIONOS: u32 = 100000;\npub const __MAC_10_0: u32 = 1000;\npub const __MAC_10_1: u32 = 1010;\npub const __MAC_10_2: u32 = 1020;\npub const __MAC_10_3: u32 = 1030;\npub const __MAC_10_4: u32 = 1040;\npub const __MAC_10_5: u32 = 1050;\npub const __MAC_10_6: u32 = 1060;\npub const __MAC_10_7: u32 = 1070;\npub const __MAC_10_8: u32 = 1080;\npub const __MAC_10_9: u32 = 1090;\npub const __MAC_10_10: u32 = 101000;\npub const __MAC_10_10_2: u32 = 101002;\npub const __MAC_10_10_3: u32 = 101003;\npub const __MAC_10_11: u32 = 101100;\npub const __MAC_10_11_2: u32 = 101102;\npub const __MAC_10_11_3: u32 = 101103;\npub const __MAC_10_11_4: u32 = 101104;\npub const __MAC_10_12: u32 = 101200;\npub const __MAC_10_12_1: u32 = 101201;\npub const __MAC_10_12_2: u32 = 101202;\npub const __MAC_10_12_4: u32 = 101204;\npub const __MAC_10_13: u32 = 101300;\npub const __MAC_10_13_1: u32 = 101301;\npub const __MAC_10_13_2: u32 = 101302;\npub const __MAC_10_13_4: u32 = 101304;\npub const __MAC_10_14: u32 = 101400;\npub const __MAC_10_14_1: u32 = 101401;\npub const __MAC_10_14_4: u32 = 101404;\npub const __MAC_10_14_5: u32 = 101405;\npub const __MAC_10_14_6: u32 = 101406;\npub const __MAC_10_15: u32 = 101500;\npub const __MAC_10_15_1: u32 = 101501;\npub const __MAC_10_15_4: u32 = 101504;\npub const __MAC_10_16: u32 = 101600;\npub const __MAC_11_0: u32 = 110000;\npub const __MAC_11_1: u32 = 110100;\npub const __MAC_11_3: u32 = 110300;\npub const __MAC_11_4: u32 = 110400;\npub const __MAC_11_5: u32 = 110500;\npub const __MAC_11_6: u32 = 110600;\npub const __MAC_12_0: u32 = 120000;\npub const __MAC_12_1: u32 = 120100;\npub const __MAC_12_2: u32 = 120200;\npub const __MAC_12_3: u32 = 120300;\npub const __MAC_12_4: u32 = 120400;\npub const __MAC_12_5: u32 = 120500;\npub const __MAC_12_6: u32 = 120600;\npub const __MAC_12_7: u32 = 120700;\npub const __MAC_13_0: u32 = 130000;\npub const __MAC_13_1: u32 = 130100;\npub const __MAC_13_2: u32 = 130200;\npub const __MAC_13_3: u32 = 130300;\npub const __MAC_13_4: u32 = 130400;\npub const __MAC_13_5: u32 = 130500;\npub const __MAC_13_6: u32 = 130600;\npub const __MAC_14_0: u32 = 140000;\npub const __MAC_14_1: u32 = 140100;\npub const __MAC_14_2: u32 = 140200;\npub const __IPHONE_2_0: u32 = 20000;\npub const __IPHONE_2_1: u32 = 20100;\npub const __IPHONE_2_2: u32 = 20200;\npub const __IPHONE_3_0: u32 = 30000;\npub const __IPHONE_3_1: u32 = 30100;\npub const __IPHONE_3_2: u32 = 30200;\npub const __IPHONE_4_0: u32 = 40000;\npub const __IPHONE_4_1: u32 = 40100;\npub const __IPHONE_4_2: u32 = 40200;\npub const __IPHONE_4_3: u32 = 40300;\npub const __IPHONE_5_0: u32 = 50000;\npub const __IPHONE_5_1: u32 = 50100;\npub const __IPHONE_6_0: u32 = 60000;\npub const __IPHONE_6_1: u32 = 60100;\npub const __IPHONE_7_0: u32 = 70000;\npub const __IPHONE_7_1: u32 = 70100;\npub const __IPHONE_8_0: u32 = 80000;\npub const __IPHONE_8_1: u32 = 80100;\npub const __IPHONE_8_2: u32 = 80200;\npub const __IPHONE_8_3: u32 = 80300;\npub const __IPHONE_8_4: u32 = 80400;\npub const __IPHONE_9_0: u32 = 90000;\npub const __IPHONE_9_1: u32 = 90100;\npub const __IPHONE_9_2: u32 = 90200;\npub const __IPHONE_9_3: u32 = 90300;\npub const __IPHONE_10_0: u32 = 100000;\npub const __IPHONE_10_1: u32 = 100100;\npub const __IPHONE_10_2: u32 = 100200;\npub const __IPHONE_10_3: u32 = 100300;\npub const __IPHONE_11_0: u32 = 110000;\npub const __IPHONE_11_1: u32 = 110100;\npub const __IPHONE_11_2: u32 = 110200;\npub const __IPHONE_11_3: u32 = 110300;\npub const __IPHONE_11_4: u32 = 110400;\npub const __IPHONE_12_0: u32 = 120000;\npub const __IPHONE_12_1: u32 = 120100;\npub const __IPHONE_12_2: u32 = 120200;\npub const __IPHONE_12_3: u32 = 120300;\npub const __IPHONE_12_4: u32 = 120400;\npub const __IPHONE_13_0: u32 = 130000;\npub const __IPHONE_13_1: u32 = 130100;\npub const __IPHONE_13_2: u32 = 130200;\npub const __IPHONE_13_3: u32 = 130300;\npub const __IPHONE_13_4: u32 = 130400;\npub const __IPHONE_13_5: u32 = 130500;\npub const __IPHONE_13_6: u32 = 130600;\npub const __IPHONE_13_7: u32 = 130700;\npub const __IPHONE_14_0: u32 = 140000;\npub const __IPHONE_14_1: u32 = 140100;\npub const __IPHONE_14_2: u32 = 140200;\npub const __IPHONE_14_3: u32 = 140300;\npub const __IPHONE_14_5: u32 = 140500;\npub const __IPHONE_14_4: u32 = 140400;\npub const __IPHONE_14_6: u32 = 140600;\npub const __IPHONE_14_7: u32 = 140700;\npub const __IPHONE_14_8: u32 = 140800;\npub const __IPHONE_15_0: u32 = 150000;\npub const __IPHONE_15_1: u32 = 150100;\npub const __IPHONE_15_2: u32 = 150200;\npub const __IPHONE_15_3: u32 = 150300;\npub const __IPHONE_15_4: u32 = 150400;\npub const __IPHONE_15_5: u32 = 150500;\npub const __IPHONE_15_6: u32 = 150600;\npub const __IPHONE_16_0: u32 = 160000;\npub const __IPHONE_16_1: u32 = 160100;\npub const __IPHONE_16_2: u32 = 160200;\npub const __IPHONE_16_3: u32 = 160300;\npub const __IPHONE_16_4: u32 = 160400;\npub const __IPHONE_16_5: u32 = 160500;\npub const __IPHONE_16_6: u32 = 160600;\npub const __IPHONE_16_7: u32 = 160700;\npub const __IPHONE_17_0: u32 = 170000;\npub const __IPHONE_17_1: u32 = 170100;\npub const __IPHONE_17_2: u32 = 170200;\npub const __WATCHOS_1_0: u32 = 10000;\npub const __WATCHOS_2_0: u32 = 20000;\npub const __WATCHOS_2_1: u32 = 20100;\npub const __WATCHOS_2_2: u32 = 20200;\npub const __WATCHOS_3_0: u32 = 30000;\npub const __WATCHOS_3_1: u32 = 30100;\npub const __WATCHOS_3_1_1: u32 = 30101;\npub const __WATCHOS_3_2: u32 = 30200;\npub const __WATCHOS_4_0: u32 = 40000;\npub const __WATCHOS_4_1: u32 = 40100;\npub const __WATCHOS_4_2: u32 = 40200;\npub const __WATCHOS_4_3: u32 = 40300;\npub const __WATCHOS_5_0: u32 = 50000;\npub const __WATCHOS_5_1: u32 = 50100;\npub const __WATCHOS_5_2: u32 = 50200;\npub const __WATCHOS_5_3: u32 = 50300;\npub const __WATCHOS_6_0: u32 = 60000;\npub const __WATCHOS_6_1: u32 = 60100;\npub const __WATCHOS_6_2: u32 = 60200;\npub const __WATCHOS_7_0: u32 = 70000;\npub const __WATCHOS_7_1: u32 = 70100;\npub const __WATCHOS_7_2: u32 = 70200;\npub const __WATCHOS_7_3: u32 = 70300;\npub const __WATCHOS_7_4: u32 = 70400;\npub const __WATCHOS_7_5: u32 = 70500;\npub const __WATCHOS_7_6: u32 = 70600;\npub const __WATCHOS_8_0: u32 = 80000;\npub const __WATCHOS_8_1: u32 = 80100;\npub const __WATCHOS_8_3: u32 = 80300;\npub const __WATCHOS_8_4: u32 = 80400;\npub const __WATCHOS_8_5: u32 = 80500;\npub const __WATCHOS_8_6: u32 = 80600;\npub const __WATCHOS_8_7: u32 = 80700;\npub const __WATCHOS_9_0: u32 = 90000;\npub const __WATCHOS_9_1: u32 = 90100;\npub const __WATCHOS_9_2: u32 = 90200;\npub const __WATCHOS_9_3: u32 = 90300;\npub const __WATCHOS_9_4: u32 = 90400;\npub const __WATCHOS_9_5: u32 = 90500;\npub const __WATCHOS_9_6: u32 = 90600;\npub const __WATCHOS_10_0: u32 = 100000;\npub const __WATCHOS_10_1: u32 = 100100;\npub const __WATCHOS_10_2: u32 = 100200;\npub const __TVOS_9_0: u32 = 90000;\npub const __TVOS_9_1: u32 = 90100;\npub const __TVOS_9_2: u32 = 90200;\npub const __TVOS_10_0: u32 = 100000;\npub const __TVOS_10_0_1: u32 = 100001;\npub const __TVOS_10_1: u32 = 100100;\npub const __TVOS_10_2: u32 = 100200;\npub const __TVOS_11_0: u32 = 110000;\npub const __TVOS_11_1: u32 = 110100;\npub const __TVOS_11_2: u32 = 110200;\npub const __TVOS_11_3: u32 = 110300;\npub const __TVOS_11_4: u32 = 110400;\npub const __TVOS_12_0: u32 = 120000;\npub const __TVOS_12_1: u32 = 120100;\npub const __TVOS_12_2: u32 = 120200;\npub const __TVOS_12_3: u32 = 120300;\npub const __TVOS_12_4: u32 = 120400;\npub const __TVOS_13_0: u32 = 130000;\npub const __TVOS_13_2: u32 = 130200;\npub const __TVOS_13_3: u32 = 130300;\npub const __TVOS_13_4: u32 = 130400;\npub const __TVOS_14_0: u32 = 140000;\npub const __TVOS_14_1: u32 = 140100;\npub const __TVOS_14_2: u32 = 140200;\npub const __TVOS_14_3: u32 = 140300;\npub const __TVOS_14_5: u32 = 140500;\npub const __TVOS_14_6: u32 = 140600;\npub const __TVOS_14_7: u32 = 140700;\npub const __TVOS_15_0: u32 = 150000;\npub const __TVOS_15_1: u32 = 150100;\npub const __TVOS_15_2: u32 = 150200;\npub const __TVOS_15_3: u32 = 150300;\npub const __TVOS_15_4: u32 = 150400;\npub const __TVOS_15_5: u32 = 150500;\npub const __TVOS_15_6: u32 = 150600;\npub const __TVOS_16_0: u32 = 160000;\npub const __TVOS_16_1: u32 = 160100;\npub const __TVOS_16_2: u32 = 160200;\npub const __TVOS_16_3: u32 = 160300;\npub const __TVOS_16_4: u32 = 160400;\npub const __TVOS_16_5: u32 = 160500;\npub const __TVOS_16_6: u32 = 160600;\npub const __TVOS_17_0: u32 = 170000;\npub const __TVOS_17_1: u32 = 170100;\npub const __TVOS_17_2: u32 = 170200;\npub const __BRIDGEOS_2_0: u32 = 20000;\npub const __BRIDGEOS_3_0: u32 = 30000;\npub const __BRIDGEOS_3_1: u32 = 30100;\npub const __BRIDGEOS_3_4: u32 = 30400;\npub const __BRIDGEOS_4_0: u32 = 40000;\npub const __BRIDGEOS_4_1: u32 = 40100;\npub const __BRIDGEOS_5_0: u32 = 50000;\npub const __BRIDGEOS_5_1: u32 = 50100;\npub const __BRIDGEOS_5_3: u32 = 50300;\npub const __BRIDGEOS_6_0: u32 = 60000;\npub const __BRIDGEOS_6_2: u32 = 60200;\npub const __BRIDGEOS_6_4: u32 = 60400;\npub const __BRIDGEOS_6_5: u32 = 60500;\npub const __BRIDGEOS_6_6: u32 = 60600;\npub const __BRIDGEOS_7_0: u32 = 70000;\npub const __BRIDGEOS_7_1: u32 = 70100;\npub const __BRIDGEOS_7_2: u32 = 70200;\npub const __BRIDGEOS_7_3: u32 = 70300;\npub const __BRIDGEOS_7_4: u32 = 70400;\npub const __BRIDGEOS_7_6: u32 = 70600;\npub const __BRIDGEOS_8_0: u32 = 80000;\npub const __BRIDGEOS_8_1: u32 = 80100;\npub const __BRIDGEOS_8_2: u32 = 80200;\npub const __DRIVERKIT_19_0: u32 = 190000;\npub const __DRIVERKIT_20_0: u32 = 200000;\npub const __DRIVERKIT_21_0: u32 = 210000;\npub const __DRIVERKIT_22_0: u32 = 220000;\npub const __DRIVERKIT_22_4: u32 = 220400;\npub const __DRIVERKIT_22_5: u32 = 220500;\npub const __DRIVERKIT_22_6: u32 = 220600;\npub const __DRIVERKIT_23_0: u32 = 230000;\npub const __DRIVERKIT_23_1: u32 = 230100;\npub const __DRIVERKIT_23_2: u32 = 230200;\npub const __VISIONOS_1_0: u32 = 10000;\npub const MAC_OS_X_VERSION_10_0: u32 = 1000;\npub const MAC_OS_X_VERSION_10_1: u32 = 1010;\npub const MAC_OS_X_VERSION_10_2: u32 = 1020;\npub const MAC_OS_X_VERSION_10_3: u32 = 1030;\npub const MAC_OS_X_VERSION_10_4: u32 = 1040;\npub const MAC_OS_X_VERSION_10_5: u32 = 1050;\npub const MAC_OS_X_VERSION_10_6: u32 = 1060;\npub const MAC_OS_X_VERSION_10_7: u32 = 1070;\npub const MAC_OS_X_VERSION_10_8: u32 = 1080;\npub const MAC_OS_X_VERSION_10_9: u32 = 1090;\npub const MAC_OS_X_VERSION_10_10: u32 = 101000;\npub const MAC_OS_X_VERSION_10_10_2: u32 = 101002;\npub const MAC_OS_X_VERSION_10_10_3: u32 = 101003;\npub const MAC_OS_X_VERSION_10_11: u32 = 101100;\npub const MAC_OS_X_VERSION_10_11_2: u32 = 101102;\npub const MAC_OS_X_VERSION_10_11_3: u32 = 101103;\npub const MAC_OS_X_VERSION_10_11_4: u32 = 101104;\npub const MAC_OS_X_VERSION_10_12: u32 = 101200;\npub const MAC_OS_X_VERSION_10_12_1: u32 = 101201;\npub const MAC_OS_X_VERSION_10_12_2: u32 = 101202;\npub const MAC_OS_X_VERSION_10_12_4: u32 = 101204;\npub const MAC_OS_X_VERSION_10_13: u32 = 101300;\npub const MAC_OS_X_VERSION_10_13_1: u32 = 101301;\npub const MAC_OS_X_VERSION_10_13_2: u32 = 101302;\npub const MAC_OS_X_VERSION_10_13_4: u32 = 101304;\npub const MAC_OS_X_VERSION_10_14: u32 = 101400;\npub const MAC_OS_X_VERSION_10_14_1: u32 = 101401;\npub const MAC_OS_X_VERSION_10_14_4: u32 = 101404;\npub const MAC_OS_X_VERSION_10_14_5: u32 = 101405;\npub const MAC_OS_X_VERSION_10_14_6: u32 = 101406;\npub const MAC_OS_X_VERSION_10_15: u32 = 101500;\npub const MAC_OS_X_VERSION_10_15_1: u32 = 101501;\npub const MAC_OS_X_VERSION_10_15_4: u32 = 101504;\npub const MAC_OS_X_VERSION_10_16: u32 = 101600;\npub const MAC_OS_VERSION_11_0: u32 = 110000;\npub const MAC_OS_VERSION_11_1: u32 = 110100;\npub const MAC_OS_VERSION_11_3: u32 = 110300;\npub const MAC_OS_VERSION_11_4: u32 = 110400;\npub const MAC_OS_VERSION_11_5: u32 = 110500;\npub const MAC_OS_VERSION_11_6: u32 = 110600;\npub const MAC_OS_VERSION_12_0: u32 = 120000;\npub const MAC_OS_VERSION_12_1: u32 = 120100;\npub const MAC_OS_VERSION_12_2: u32 = 120200;\npub const MAC_OS_VERSION_12_3: u32 = 120300;\npub const MAC_OS_VERSION_12_4: u32 = 120400;\npub const MAC_OS_VERSION_12_5: u32 = 120500;\npub const MAC_OS_VERSION_12_6: u32 = 120600;\npub const MAC_OS_VERSION_12_7: u32 = 120700;\npub const MAC_OS_VERSION_13_0: u32 = 130000;\npub const MAC_OS_VERSION_13_1: u32 = 130100;\npub const MAC_OS_VERSION_13_2: u32 = 130200;\npub const MAC_OS_VERSION_13_3: u32 = 130300;\npub const MAC_OS_VERSION_13_4: u32 = 130400;\npub const MAC_OS_VERSION_13_5: u32 = 130500;\npub const MAC_OS_VERSION_13_6: u32 = 130600;\npub const MAC_OS_VERSION_14_0: u32 = 140000;\npub const MAC_OS_VERSION_14_1: u32 = 140100;\npub const MAC_OS_VERSION_14_2: u32 = 140200;\npub const __MAC_OS_X_VERSION_MAX_ALLOWED: u32 = 140200;\npub const __ENABLE_LEGACY_MAC_AVAILABILITY: u32 = 1;\npub const __DARWIN_FD_SETSIZE: u32 = 1024;\npub const __DARWIN_NBBY: u32 = 8;\npub const NBBY: u32 = 8;\npub const FD_SETSIZE: u32 = 1024;\npub const ARG_MAX: u32 = 1048576;\npub const CHILD_MAX: u32 = 266;\npub const GID_MAX: u32 = 2147483647;\npub const LINK_MAX: u32 = 32767;\npub const MAX_CANON: u32 = 1024;\npub const MAX_INPUT: u32 = 1024;\npub const NAME_MAX: u32 = 255;\npub const NGROUPS_MAX: u32 = 16;\npub const UID_MAX: u32 = 2147483647;\npub const OPEN_MAX: u32 = 10240;\npub const PATH_MAX: u32 = 1024;\npub const PIPE_BUF: u32 = 512;\npub const BC_BASE_MAX: u32 = 99;\npub const BC_DIM_MAX: u32 = 2048;\npub const BC_SCALE_MAX: u32 = 99;\npub const BC_STRING_MAX: u32 = 1000;\npub const CHARCLASS_NAME_MAX: u32 = 14;\npub const COLL_WEIGHTS_MAX: u32 = 2;\npub const EQUIV_CLASS_MAX: u32 = 2;\npub const EXPR_NEST_MAX: u32 = 32;\npub const LINE_MAX: u32 = 2048;\npub const RE_DUP_MAX: u32 = 255;\npub const NZERO: u32 = 20;\npub const MAXCOMLEN: u32 = 16;\npub const MAXINTERP: u32 = 64;\npub const MAXLOGNAME: u32 = 255;\npub const MAXUPRC: u32 = 266;\npub const NCARGS: u32 = 1048576;\npub const NGROUPS: u32 = 16;\npub const NOFILE: u32 = 256;\npub const NOGROUP: u32 = 65535;\npub const MAXHOSTNAMELEN: u32 = 256;\npub const MAXDOMNAMELEN: u32 = 256;\npub const NBPG: u32 = 4096;\npub const PGOFSET: u32 = 4095;\npub const PGSHIFT: u32 = 12;\npub const DEV_BSIZE: u32 = 512;\npub const DEV_BSHIFT: u32 = 9;\npub const BLKDEV_IOSIZE: u32 = 2048;\npub const MAXPHYS: u32 = 131072;\npub const CLSIZE: u32 = 1;\npub const CLSIZELOG2: u32 = 0;\npub const MSIZESHIFT: u32 = 8;\npub const MSIZE: u32 = 256;\npub const MCLSHIFT: u32 = 11;\npub const MCLBYTES: u32 = 2048;\npub const MBIGCLSHIFT: u32 = 12;\npub const MBIGCLBYTES: u32 = 4096;\npub const M16KCLSHIFT: u32 = 14;\npub const M16KCLBYTES: u32 = 16384;\npub const MCLOFSET: u32 = 2047;\npub const NMBCLUSTERS: u32 = 512;\npub const __DARWIN_CLK_TCK: u32 = 100;\npub const CHAR_BIT: u32 = 8;\npub const MB_LEN_MAX: u32 = 6;\npub const CLK_TCK: u32 = 100;\npub const SCHAR_MAX: u32 = 127;\npub const SCHAR_MIN: i32 = -128;\npub const UCHAR_MAX: u32 = 255;\npub const CHAR_MAX: u32 = 127;\npub const CHAR_MIN: i32 = -128;\npub const USHRT_MAX: u32 = 65535;\npub const SHRT_MAX: u32 = 32767;\npub const SHRT_MIN: i32 = -32768;\npub const UINT_MAX: u32 = 4294967295;\npub const INT_MAX: u32 = 2147483647;\npub const INT_MIN: i32 = -2147483648;\npub const ULONG_MAX: i32 = -1;\npub const LONG_MAX: u64 = 9223372036854775807;\npub const LONG_MIN: i64 = -9223372036854775808;\npub const ULLONG_MAX: i32 = -1;\npub const LLONG_MAX: u64 = 9223372036854775807;\npub const LLONG_MIN: i64 = -9223372036854775808;\npub const LONG_BIT: u32 = 64;\npub const SSIZE_MAX: u64 = 9223372036854775807;\npub const WORD_BIT: u32 = 32;\npub const SIZE_T_MAX: i32 = -1;\npub const UQUAD_MAX: i32 = -1;\npub const QUAD_MAX: u64 = 9223372036854775807;\npub const QUAD_MIN: i64 = -9223372036854775808;\npub const _POSIX_ARG_MAX: u32 = 4096;\npub const _POSIX_CHILD_MAX: u32 = 25;\npub const _POSIX_LINK_MAX: u32 = 8;\npub const _POSIX_MAX_CANON: u32 = 255;\npub const _POSIX_MAX_INPUT: u32 = 255;\npub const _POSIX_NAME_MAX: u32 = 14;\npub const _POSIX_NGROUPS_MAX: u32 = 8;\npub const _POSIX_OPEN_MAX: u32 = 20;\npub const _POSIX_PATH_MAX: u32 = 256;\npub const _POSIX_PIPE_BUF: u32 = 512;\npub const _POSIX_SSIZE_MAX: u32 = 32767;\npub const _POSIX_STREAM_MAX: u32 = 8;\npub const _POSIX_TZNAME_MAX: u32 = 6;\npub const _POSIX2_BC_BASE_MAX: u32 = 99;\npub const _POSIX2_BC_DIM_MAX: u32 = 2048;\npub const _POSIX2_BC_SCALE_MAX: u32 = 99;\npub const _POSIX2_BC_STRING_MAX: u32 = 1000;\npub const _POSIX2_EQUIV_CLASS_MAX: u32 = 2;\npub const _POSIX2_EXPR_NEST_MAX: u32 = 32;\npub const _POSIX2_LINE_MAX: u32 = 2048;\npub const _POSIX2_RE_DUP_MAX: u32 = 255;\npub const _POSIX_AIO_LISTIO_MAX: u32 = 2;\npub const _POSIX_AIO_MAX: u32 = 1;\npub const _POSIX_DELAYTIMER_MAX: u32 = 32;\npub const _POSIX_MQ_OPEN_MAX: u32 = 8;\npub const _POSIX_MQ_PRIO_MAX: u32 = 32;\npub const _POSIX_RTSIG_MAX: u32 = 8;\npub const _POSIX_SEM_NSEMS_MAX: u32 = 256;\npub const _POSIX_SEM_VALUE_MAX: u32 = 32767;\npub const _POSIX_SIGQUEUE_MAX: u32 = 32;\npub const _POSIX_TIMER_MAX: u32 = 32;\npub const _POSIX_CLOCKRES_MIN: u32 = 20000000;\npub const _POSIX_THREAD_DESTRUCTOR_ITERATIONS: u32 = 4;\npub const _POSIX_THREAD_KEYS_MAX: u32 = 128;\npub const _POSIX_THREAD_THREADS_MAX: u32 = 64;\npub const PTHREAD_DESTRUCTOR_ITERATIONS: u32 = 4;\npub const PTHREAD_KEYS_MAX: u32 = 512;\npub const PTHREAD_STACK_MIN: u32 = 8192;\npub const _POSIX_HOST_NAME_MAX: u32 = 255;\npub const _POSIX_LOGIN_NAME_MAX: u32 = 9;\npub const _POSIX_SS_REPL_MAX: u32 = 4;\npub const _POSIX_SYMLINK_MAX: u32 = 255;\npub const _POSIX_SYMLOOP_MAX: u32 = 8;\npub const _POSIX_TRACE_EVENT_NAME_MAX: u32 = 30;\npub const _POSIX_TRACE_NAME_MAX: u32 = 8;\npub const _POSIX_TRACE_SYS_MAX: u32 = 8;\npub const _POSIX_TRACE_USER_EVENT_MAX: u32 = 32;\npub const _POSIX_TTY_NAME_MAX: u32 = 9;\npub const _POSIX2_CHARCLASS_NAME_MAX: u32 = 14;\npub const _POSIX2_COLL_WEIGHTS_MAX: u32 = 2;\npub const _POSIX_RE_DUP_MAX: u32 = 255;\npub const OFF_MIN: i64 = -9223372036854775808;\npub const OFF_MAX: u64 = 9223372036854775807;\npub const PASS_MAX: u32 = 128;\npub const NL_ARGMAX: u32 = 9;\npub const NL_LANGMAX: u32 = 14;\npub const NL_MSGMAX: u32 = 32767;\npub const NL_NMAX: u32 = 1;\npub const NL_SETMAX: u32 = 255;\npub const NL_TEXTMAX: u32 = 2048;\npub const _XOPEN_IOV_MAX: u32 = 16;\npub const IOV_MAX: u32 = 1024;\npub const _XOPEN_NAME_MAX: u32 = 255;\npub const _XOPEN_PATH_MAX: u32 = 1024;\npub const __DARWIN_NSIG: u32 = 32;\npub const NSIG: u32 = 32;\npub const _I386_SIGNAL_H_: u32 = 1;\npub const SIGHUP: u32 = 1;\npub const SIGINT: u32 = 2;\npub const SIGQUIT: u32 = 3;\npub const SIGILL: u32 = 4;\npub const SIGTRAP: u32 = 5;\npub const SIGABRT: u32 = 6;\npub const SIGIOT: u32 = 6;\npub const SIGEMT: u32 = 7;\npub const SIGFPE: u32 = 8;\npub const SIGKILL: u32 = 9;\npub const SIGBUS: u32 = 10;\npub const SIGSEGV: u32 = 11;\npub const SIGSYS: u32 = 12;\npub const SIGPIPE: u32 = 13;\npub const SIGALRM: u32 = 14;\npub const SIGTERM: u32 = 15;\npub const SIGURG: u32 = 16;\npub const SIGSTOP: u32 = 17;\npub const SIGTSTP: u32 = 18;\npub const SIGCONT: u32 = 19;\npub const SIGCHLD: u32 = 20;\npub const SIGTTIN: u32 = 21;\npub const SIGTTOU: u32 = 22;\npub const SIGIO: u32 = 23;\npub const SIGXCPU: u32 = 24;\npub const SIGXFSZ: u32 = 25;\npub const SIGVTALRM: u32 = 26;\npub const SIGPROF: u32 = 27;\npub const SIGWINCH: u32 = 28;\npub const SIGINFO: u32 = 29;\npub const SIGUSR1: u32 = 30;\npub const SIGUSR2: u32 = 31;\npub const FP_PREC_24B: u32 = 0;\npub const FP_PREC_53B: u32 = 2;\npub const FP_PREC_64B: u32 = 3;\npub const FP_RND_NEAR: u32 = 0;\npub const FP_RND_DOWN: u32 = 1;\npub const FP_RND_UP: u32 = 2;\npub const FP_CHOP: u32 = 3;\npub const FP_STATE_BYTES: u32 = 512;\npub const _X86_INSTRUCTION_STATE_MAX_INSN_BYTES: u32 = 2380;\npub const _X86_INSTRUCTION_STATE_CACHELINE_SIZE: u32 = 64;\npub const __LASTBRANCH_MAX: u32 = 32;\npub const SIGEV_NONE: u32 = 0;\npub const SIGEV_SIGNAL: u32 = 1;\npub const SIGEV_THREAD: u32 = 3;\npub const ILL_NOOP: u32 = 0;\npub const ILL_ILLOPC: u32 = 1;\npub const ILL_ILLTRP: u32 = 2;\npub const ILL_PRVOPC: u32 = 3;\npub const ILL_ILLOPN: u32 = 4;\npub const ILL_ILLADR: u32 = 5;\npub const ILL_PRVREG: u32 = 6;\npub const ILL_COPROC: u32 = 7;\npub const ILL_BADSTK: u32 = 8;\npub const FPE_NOOP: u32 = 0;\npub const FPE_FLTDIV: u32 = 1;\npub const FPE_FLTOVF: u32 = 2;\npub const FPE_FLTUND: u32 = 3;\npub const FPE_FLTRES: u32 = 4;\npub const FPE_FLTINV: u32 = 5;\npub const FPE_FLTSUB: u32 = 6;\npub const FPE_INTDIV: u32 = 7;\npub const FPE_INTOVF: u32 = 8;\npub const SEGV_NOOP: u32 = 0;\npub const SEGV_MAPERR: u32 = 1;\npub const SEGV_ACCERR: u32 = 2;\npub const BUS_NOOP: u32 = 0;\npub const BUS_ADRALN: u32 = 1;\npub const BUS_ADRERR: u32 = 2;\npub const BUS_OBJERR: u32 = 3;\npub const TRAP_BRKPT: u32 = 1;\npub const TRAP_TRACE: u32 = 2;\npub const CLD_NOOP: u32 = 0;\npub const CLD_EXITED: u32 = 1;\npub const CLD_KILLED: u32 = 2;\npub const CLD_DUMPED: u32 = 3;\npub const CLD_TRAPPED: u32 = 4;\npub const CLD_STOPPED: u32 = 5;\npub const CLD_CONTINUED: u32 = 6;\npub const POLL_IN: u32 = 1;\npub const POLL_OUT: u32 = 2;\npub const POLL_MSG: u32 = 3;\npub const POLL_ERR: u32 = 4;\npub const POLL_PRI: u32 = 5;\npub const POLL_HUP: u32 = 6;\npub const SA_ONSTACK: u32 = 1;\npub const SA_RESTART: u32 = 2;\npub const SA_RESETHAND: u32 = 4;\npub const SA_NOCLDSTOP: u32 = 8;\npub const SA_NODEFER: u32 = 16;\npub const SA_NOCLDWAIT: u32 = 32;\npub const SA_SIGINFO: u32 = 64;\npub const SA_USERTRAMP: u32 = 256;\npub const SA_64REGSET: u32 = 512;\npub const SA_USERSPACE_MASK: u32 = 127;\npub const SIG_BLOCK: u32 = 1;\npub const SIG_UNBLOCK: u32 = 2;\npub const SIG_SETMASK: u32 = 3;\npub const SI_USER: u32 = 65537;\npub const SI_QUEUE: u32 = 65538;\npub const SI_TIMER: u32 = 65539;\npub const SI_ASYNCIO: u32 = 65540;\npub const SI_MESGQ: u32 = 65541;\npub const SS_ONSTACK: u32 = 1;\npub const SS_DISABLE: u32 = 4;\npub const MINSIGSTKSZ: u32 = 32768;\npub const SIGSTKSZ: u32 = 131072;\npub const SV_ONSTACK: u32 = 1;\npub const SV_INTERRUPT: u32 = 2;\npub const SV_RESETHAND: u32 = 4;\npub const SV_NODEFER: u32 = 16;\npub const SV_NOCLDSTOP: u32 = 8;\npub const SV_SIGINFO: u32 = 64;\npub const PSWP: u32 = 0;\npub const PVM: u32 = 4;\npub const PINOD: u32 = 8;\npub const PRIBIO: u32 = 16;\npub const PVFS: u32 = 20;\npub const PZERO: u32 = 22;\npub const PSOCK: u32 = 24;\npub const PWAIT: u32 = 32;\npub const PLOCK: u32 = 36;\npub const PPAUSE: u32 = 40;\npub const PUSER: u32 = 50;\npub const MAXPRI: u32 = 127;\npub const PRIMASK: u32 = 255;\npub const PCATCH: u32 = 256;\npub const PTTYBLOCK: u32 = 512;\npub const PDROP: u32 = 1024;\npub const PSPIN: u32 = 2048;\npub const CMASK: u32 = 18;\npub const CLBYTES: u32 = 4096;\npub const CLOFSET: u32 = 4095;\npub const CLOFF: u32 = 4095;\npub const CLSHIFT: u32 = 12;\npub const CBLOCK: u32 = 64;\npub const CBQSIZE: u32 = 8;\npub const CROUND: u32 = 63;\npub const MAXBSIZE: u32 = 1048576;\npub const MAXPHYSIO: u32 = 131072;\npub const MAXFRAG: u32 = 8;\npub const MAXPHYSIO_WIRED: u32 = 16777216;\npub const MAXPATHLEN: u32 = 1024;\npub const MAXSYMLINKS: u32 = 32;\npub const FSHIFT: u32 = 11;\npub const FSCALE: u32 = 2048;\npub const SPLAY_NEGINF: i32 = -1;\npub const SPLAY_INF: u32 = 1;\npub const RB_BLACK: u32 = 0;\npub const RB_RED: u32 = 1;\npub const RB_NEGINF: i32 = -1;\npub const RB_INF: u32 = 1;\npub const RNF_NORMAL: u32 = 1;\npub const RNF_ROOT: u32 = 2;\npub const RNF_ACTIVE: u32 = 4;\npub const __WORDSIZE: u32 = 64;\npub const INT8_MAX: u32 = 127;\npub const INT16_MAX: u32 = 32767;\npub const INT32_MAX: u32 = 2147483647;\npub const INT64_MAX: u64 = 9223372036854775807;\npub const INT8_MIN: i32 = -128;\npub const INT16_MIN: i32 = -32768;\npub const INT32_MIN: i32 = -2147483648;\npub const INT64_MIN: i64 = -9223372036854775808;\npub const UINT8_MAX: u32 = 255;\npub const UINT16_MAX: u32 = 65535;\npub const UINT32_MAX: u32 = 4294967295;\npub const UINT64_MAX: i32 = -1;\npub const INT_LEAST8_MIN: i32 = -128;\npub const INT_LEAST16_MIN: i32 = -32768;\npub const INT_LEAST32_MIN: i32 = -2147483648;\npub const INT_LEAST64_MIN: i64 = -9223372036854775808;\npub const INT_LEAST8_MAX: u32 = 127;\npub const INT_LEAST16_MAX: u32 = 32767;\npub const INT_LEAST32_MAX: u32 = 2147483647;\npub const INT_LEAST64_MAX: u64 = 9223372036854775807;\npub const UINT_LEAST8_MAX: u32 = 255;\npub const UINT_LEAST16_MAX: u32 = 65535;\npub const UINT_LEAST32_MAX: u32 = 4294967295;\npub const UINT_LEAST64_MAX: i32 = -1;\npub const INT_FAST8_MIN: i32 = -128;\npub const INT_FAST16_MIN: i32 = -32768;\npub const INT_FAST32_MIN: i32 = -2147483648;\npub const INT_FAST64_MIN: i64 = -9223372036854775808;\npub const INT_FAST8_MAX: u32 = 127;\npub const INT_FAST16_MAX: u32 = 32767;\npub const INT_FAST32_MAX: u32 = 2147483647;\npub const INT_FAST64_MAX: u64 = 9223372036854775807;\npub const UINT_FAST8_MAX: u32 = 255;\npub const UINT_FAST16_MAX: u32 = 65535;\npub const UINT_FAST32_MAX: u32 = 4294967295;\npub const UINT_FAST64_MAX: i32 = -1;\npub const INTPTR_MAX: u64 = 9223372036854775807;\npub const INTPTR_MIN: i64 = -9223372036854775808;\npub const UINTPTR_MAX: i32 = -1;\npub const SIZE_MAX: i32 = -1;\npub const RSIZE_MAX: i32 = -1;\npub const WINT_MIN: i32 = -2147483648;\npub const WINT_MAX: u32 = 2147483647;\npub const SIG_ATOMIC_MIN: i32 = -2147483648;\npub const SIG_ATOMIC_MAX: u32 = 2147483647;\npub const KEV_INET_SUBCLASS: u32 = 1;\npub const KEV_INET_NEW_ADDR: u32 = 1;\npub const KEV_INET_CHANGED_ADDR: u32 = 2;\npub const KEV_INET_ADDR_DELETED: u32 = 3;\npub const KEV_INET_SIFDSTADDR: u32 = 4;\npub const KEV_INET_SIFBRDADDR: u32 = 5;\npub const KEV_INET_SIFNETMASK: u32 = 6;\npub const KEV_INET_ARPCOLLISION: u32 = 7;\npub const KEV_INET_PORTINUSE: u32 = 8;\npub const KEV_INET_ARPRTRFAILURE: u32 = 9;\npub const KEV_INET_ARPRTRALIVE: u32 = 10;\npub const KEV_DL_SUBCLASS: u32 = 2;\npub const KEV_DL_SIFFLAGS: u32 = 1;\npub const KEV_DL_SIFMETRICS: u32 = 2;\npub const KEV_DL_SIFMTU: u32 = 3;\npub const KEV_DL_SIFPHYS: u32 = 4;\npub const KEV_DL_SIFMEDIA: u32 = 5;\npub const KEV_DL_SIFGENERIC: u32 = 6;\npub const KEV_DL_ADDMULTI: u32 = 7;\npub const KEV_DL_DELMULTI: u32 = 8;\npub const KEV_DL_IF_ATTACHED: u32 = 9;\npub const KEV_DL_IF_DETACHING: u32 = 10;\npub const KEV_DL_IF_DETACHED: u32 = 11;\npub const KEV_DL_LINK_OFF: u32 = 12;\npub const KEV_DL_LINK_ON: u32 = 13;\npub const KEV_DL_PROTO_ATTACHED: u32 = 14;\npub const KEV_DL_PROTO_DETACHED: u32 = 15;\npub const KEV_DL_LINK_ADDRESS_CHANGED: u32 = 16;\npub const KEV_DL_WAKEFLAGS_CHANGED: u32 = 17;\npub const KEV_DL_IF_IDLE_ROUTE_REFCNT: u32 = 18;\npub const KEV_DL_IFCAP_CHANGED: u32 = 19;\npub const KEV_DL_LINK_QUALITY_METRIC_CHANGED: u32 = 20;\npub const KEV_DL_NODE_PRESENCE: u32 = 21;\npub const KEV_DL_NODE_ABSENCE: u32 = 22;\npub const KEV_DL_MASTER_ELECTED: u32 = 23;\npub const KEV_DL_ISSUES: u32 = 24;\npub const KEV_DL_IFDELEGATE_CHANGED: u32 = 25;\npub const KEV_DL_AWDL_RESTRICTED: u32 = 26;\npub const KEV_DL_AWDL_UNRESTRICTED: u32 = 27;\npub const KEV_DL_RRC_STATE_CHANGED: u32 = 28;\npub const KEV_DL_QOS_MODE_CHANGED: u32 = 29;\npub const KEV_DL_LOW_POWER_MODE_CHANGED: u32 = 30;\npub const KEV_NETPOLICY_SUBCLASS: u32 = 3;\npub const KEV_NETPOLICY_IFDENIED: u32 = 1;\npub const KEV_NETPOLICY_IFFAILED: u32 = 2;\npub const KEV_NETPOLICY_NETDENIED: u32 = 3;\npub const NETPOLICY_NETWORKTYPE_LOCAL: u32 = 1;\npub const KEV_SOCKET_SUBCLASS: u32 = 4;\npub const KEV_SOCKET_CLOSED: u32 = 1;\npub const KEV_INET6_SUBCLASS: u32 = 6;\npub const KEV_INET6_NEW_USER_ADDR: u32 = 1;\npub const KEV_INET6_CHANGED_ADDR: u32 = 2;\npub const KEV_INET6_ADDR_DELETED: u32 = 3;\npub const KEV_INET6_NEW_LL_ADDR: u32 = 4;\npub const KEV_INET6_NEW_RTADV_ADDR: u32 = 5;\npub const KEV_INET6_DEFROUTER: u32 = 6;\npub const KEV_INET6_REQUEST_NAT64_PREFIX: u32 = 7;\npub const KEV_ND6_SUBCLASS: u32 = 7;\npub const KEV_ND6_RA: u32 = 1;\npub const KEV_ND6_NDFAILURE: u32 = 2;\npub const KEV_ND6_NDALIVE: u32 = 3;\npub const KEV_ND6_DAD_FAILURE: u32 = 4;\npub const KEV_ND6_DAD_SUCCESS: u32 = 5;\npub const KEV_ND6_ADDR_DETACHED: u32 = 6;\npub const KEV_ND6_ADDR_DEPRECATED: u32 = 7;\npub const KEV_ND6_ADDR_EXPIRED: u32 = 8;\npub const KEV_ND6_RTR_EXPIRED: u32 = 9;\npub const KEV_ND6_PFX_EXPIRED: u32 = 10;\npub const KEV_NECP_SUBCLASS: u32 = 8;\npub const KEV_NECP_POLICIES_CHANGED: u32 = 1;\npub const KEV_NETAGENT_SUBCLASS: u32 = 9;\npub const KEV_NETAGENT_REGISTERED: u32 = 1;\npub const KEV_NETAGENT_UNREGISTERED: u32 = 2;\npub const KEV_NETAGENT_UPDATED: u32 = 3;\npub const KEV_NETAGENT_UPDATED_INTERFACES: u32 = 4;\npub const KEV_LOG_SUBCLASS: u32 = 10;\npub const IPFWLOGEVENT: u32 = 0;\npub const KEV_NETEVENT_SUBCLASS: u32 = 11;\npub const KEV_NETEVENT_APNFALLBACK: u32 = 1;\npub const KEV_NETEVENT_CLAT46_EVENT: u32 = 2;\npub const KEV_MPTCP_SUBCLASS: u32 = 12;\npub const KEV_MPTCP_CELLUSE: u32 = 1;\npub const KEV_IPSEC_SUBCLASS: u32 = 13;\npub const KEV_IPSEC_WAKE_PACKET: u32 = 1;\npub const SOCK_STREAM: u32 = 1;\npub const SOCK_DGRAM: u32 = 2;\npub const SOCK_RAW: u32 = 3;\npub const SOCK_RDM: u32 = 4;\npub const SOCK_SEQPACKET: u32 = 5;\npub const SO_DEBUG: u32 = 1;\npub const SO_ACCEPTCONN: u32 = 2;\npub const SO_REUSEADDR: u32 = 4;\npub const SO_KEEPALIVE: u32 = 8;\npub const SO_DONTROUTE: u32 = 16;\npub const SO_BROADCAST: u32 = 32;\npub const SO_USELOOPBACK: u32 = 64;\npub const SO_LINGER: u32 = 128;\npub const SO_OOBINLINE: u32 = 256;\npub const SO_REUSEPORT: u32 = 512;\npub const SO_TIMESTAMP: u32 = 1024;\npub const SO_TIMESTAMP_MONOTONIC: u32 = 2048;\npub const SO_DONTTRUNC: u32 = 8192;\npub const SO_WANTMORE: u32 = 16384;\npub const SO_WANTOOBFLAG: u32 = 32768;\npub const SO_NOWAKEFROMSLEEP: u32 = 65536;\npub const SO_NOAPNFALLBK: u32 = 131072;\npub const SO_TIMESTAMP_CONTINUOUS: u32 = 262144;\npub const SO_SNDBUF: u32 = 4097;\npub const SO_RCVBUF: u32 = 4098;\npub const SO_SNDLOWAT: u32 = 4099;\npub const SO_RCVLOWAT: u32 = 4100;\npub const SO_SNDTIMEO: u32 = 4101;\npub const SO_RCVTIMEO: u32 = 4102;\npub const SO_ERROR: u32 = 4103;\npub const SO_TYPE: u32 = 4104;\npub const SO_LABEL: u32 = 4112;\npub const SO_PEERLABEL: u32 = 4113;\npub const SO_NREAD: u32 = 4128;\npub const SO_NKE: u32 = 4129;\npub const SO_NOSIGPIPE: u32 = 4130;\npub const SO_NOADDRERR: u32 = 4131;\npub const SO_NWRITE: u32 = 4132;\npub const SO_REUSESHAREUID: u32 = 4133;\npub const SO_NOTIFYCONFLICT: u32 = 4134;\npub const SO_UPCALLCLOSEWAIT: u32 = 4135;\npub const SO_LINGER_SEC: u32 = 4224;\npub const SO_RESTRICTIONS: u32 = 4225;\npub const SO_RESTRICT_DENY_IN: u32 = 1;\npub const SO_RESTRICT_DENY_OUT: u32 = 2;\npub const SO_RESTRICT_DENY_CELLULAR: u32 = 4;\npub const SO_RESTRICT_DENY_EXPENSIVE: u32 = 8;\npub const SO_RESTRICT_DENY_CONSTRAINED: u32 = 16;\npub const SO_RANDOMPORT: u32 = 4226;\npub const SO_NP_EXTENSIONS: u32 = 4227;\npub const SO_EXECPATH: u32 = 4229;\npub const SO_TRAFFIC_CLASS: u32 = 4230;\npub const SO_TC_BK_SYS: u32 = 100;\npub const SO_TC_BK: u32 = 200;\npub const SO_TC_BE: u32 = 0;\npub const SO_TC_RD: u32 = 300;\npub const SO_TC_OAM: u32 = 400;\npub const SO_TC_AV: u32 = 500;\npub const SO_TC_RV: u32 = 600;\npub const SO_TC_VI: u32 = 700;\npub const SO_TC_VO: u32 = 800;\npub const SO_TC_CTL: u32 = 900;\npub const SO_TC_MAX: u32 = 10;\npub const TRAFFIC_MGT_SO_BACKGROUND: u32 = 1;\npub const TRAFFIC_MGT_TCP_RECVBG: u32 = 2;\npub const SO_RECV_TRAFFIC_CLASS: u32 = 4231;\npub const SO_TRAFFIC_CLASS_DBG: u32 = 4232;\npub const SO_OPTION_UNUSED_0: u32 = 4233;\npub const SO_PRIVILEGED_TRAFFIC_CLASS: u32 = 4240;\npub const SO_DEFUNCTIT: u32 = 4241;\npub const SO_DEFUNCTOK: u32 = 4352;\npub const SO_ISDEFUNCT: u32 = 4353;\npub const SO_OPPORTUNISTIC: u32 = 4354;\npub const SO_FLUSH: u32 = 4355;\npub const SO_TC_ALL: i32 = -1;\npub const SO_RECV_ANYIF: u32 = 4356;\npub const SO_TRAFFIC_MGT_BACKGROUND: u32 = 4357;\npub const SO_FLOW_DIVERT_TOKEN: u32 = 4358;\npub const SO_DELEGATED: u32 = 4359;\npub const SO_DELEGATED_UUID: u32 = 4360;\npub const SO_NECP_ATTRIBUTES: u32 = 4361;\npub const SO_CFIL_SOCK_ID: u32 = 4368;\npub const SO_NECP_CLIENTUUID: u32 = 4369;\npub const SO_NUMRCVPKT: u32 = 4370;\npub const SO_AWDL_UNRESTRICTED: u32 = 4371;\npub const SO_EXTENDED_BK_IDLE: u32 = 4372;\npub const SO_MARK_CELLFALLBACK: u32 = 4373;\npub const SO_NET_SERVICE_TYPE: u32 = 4374;\npub const SO_QOSMARKING_POLICY_OVERRIDE: u32 = 4375;\npub const SO_INTCOPROC_ALLOW: u32 = 4376;\npub const SO_NETSVC_MARKING_LEVEL: u32 = 4377;\npub const SO_NECP_LISTENUUID: u32 = 4384;\npub const SO_MPKL_SEND_INFO: u32 = 4386;\npub const SO_STATISTICS_EVENT: u32 = 4387;\npub const SO_WANT_KEV_SOCKET_CLOSED: u32 = 4388;\npub const NET_SERVICE_TYPE_BE: u32 = 0;\npub const NET_SERVICE_TYPE_BK: u32 = 1;\npub const NET_SERVICE_TYPE_SIG: u32 = 2;\npub const NET_SERVICE_TYPE_VI: u32 = 3;\npub const NET_SERVICE_TYPE_VO: u32 = 4;\npub const NET_SERVICE_TYPE_RV: u32 = 5;\npub const NET_SERVICE_TYPE_AV: u32 = 6;\npub const NET_SERVICE_TYPE_OAM: u32 = 7;\npub const NET_SERVICE_TYPE_RD: u32 = 8;\npub const _NET_SERVICE_TYPE_COUNT: u32 = 9;\npub const SO_TC_NET_SERVICE_OFFSET: u32 = 10000;\npub const SO_TC_NETSVC_SIG: u32 = 10002;\npub const NETSVC_MRKNG_UNKNOWN: u32 = 0;\npub const NETSVC_MRKNG_LVL_L2: u32 = 1;\npub const NETSVC_MRKNG_LVL_L3L2_ALL: u32 = 2;\npub const NETSVC_MRKNG_LVL_L3L2_BK: u32 = 3;\npub const SAE_ASSOCID_ANY: u32 = 0;\npub const SAE_CONNID_ANY: u32 = 0;\npub const CONNECT_RESUME_ON_READ_WRITE: u32 = 1;\npub const CONNECT_DATA_IDEMPOTENT: u32 = 2;\npub const CONNECT_DATA_AUTHENTICATED: u32 = 4;\npub const SONPX_SETOPTSHUT: u32 = 1;\npub const SOL_SOCKET: u32 = 65535;\npub const AF_UNSPEC: u32 = 0;\npub const AF_UNIX: u32 = 1;\npub const AF_LOCAL: u32 = 1;\npub const AF_INET: u32 = 2;\npub const AF_IMPLINK: u32 = 3;\npub const AF_PUP: u32 = 4;\npub const AF_CHAOS: u32 = 5;\npub const AF_NS: u32 = 6;\npub const AF_ISO: u32 = 7;\npub const AF_OSI: u32 = 7;\npub const AF_ECMA: u32 = 8;\npub const AF_DATAKIT: u32 = 9;\npub const AF_CCITT: u32 = 10;\npub const AF_SNA: u32 = 11;\npub const AF_DECnet: u32 = 12;\npub const AF_DLI: u32 = 13;\npub const AF_LAT: u32 = 14;\npub const AF_HYLINK: u32 = 15;\npub const AF_APPLETALK: u32 = 16;\npub const AF_ROUTE: u32 = 17;\npub const AF_LINK: u32 = 18;\npub const pseudo_AF_XTP: u32 = 19;\npub const AF_COIP: u32 = 20;\npub const AF_CNT: u32 = 21;\npub const pseudo_AF_RTIP: u32 = 22;\npub const AF_IPX: u32 = 23;\npub const AF_SIP: u32 = 24;\npub const pseudo_AF_PIP: u32 = 25;\npub const AF_NDRV: u32 = 27;\npub const AF_ISDN: u32 = 28;\npub const AF_E164: u32 = 28;\npub const pseudo_AF_KEY: u32 = 29;\npub const AF_INET6: u32 = 30;\npub const AF_NATM: u32 = 31;\npub const AF_SYSTEM: u32 = 32;\npub const AF_NETBIOS: u32 = 33;\npub const AF_PPP: u32 = 34;\npub const pseudo_AF_HDRCMPLT: u32 = 35;\npub const AF_AFP: u32 = 36;\npub const AF_IEEE80211: u32 = 37;\npub const AF_UTUN: u32 = 38;\npub const AF_MULTIPATH: u32 = 39;\npub const AF_VSOCK: u32 = 40;\npub const AF_MAX: u32 = 41;\npub const SOCK_MAXADDRLEN: u32 = 255;\npub const _SS_MAXSIZE: u32 = 128;\npub const PF_UNSPEC: u32 = 0;\npub const PF_LOCAL: u32 = 1;\npub const PF_UNIX: u32 = 1;\npub const PF_INET: u32 = 2;\npub const PF_IMPLINK: u32 = 3;\npub const PF_PUP: u32 = 4;\npub const PF_CHAOS: u32 = 5;\npub const PF_NS: u32 = 6;\npub const PF_ISO: u32 = 7;\npub const PF_OSI: u32 = 7;\npub const PF_ECMA: u32 = 8;\npub const PF_DATAKIT: u32 = 9;\npub const PF_CCITT: u32 = 10;\npub const PF_SNA: u32 = 11;\npub const PF_DECnet: u32 = 12;\npub const PF_DLI: u32 = 13;\npub const PF_LAT: u32 = 14;\npub const PF_HYLINK: u32 = 15;\npub const PF_APPLETALK: u32 = 16;\npub const PF_ROUTE: u32 = 17;\npub const PF_LINK: u32 = 18;\npub const PF_XTP: u32 = 19;\npub const PF_COIP: u32 = 20;\npub const PF_CNT: u32 = 21;\npub const PF_SIP: u32 = 24;\npub const PF_IPX: u32 = 23;\npub const PF_RTIP: u32 = 22;\npub const PF_PIP: u32 = 25;\npub const PF_NDRV: u32 = 27;\npub const PF_ISDN: u32 = 28;\npub const PF_KEY: u32 = 29;\npub const PF_INET6: u32 = 30;\npub const PF_NATM: u32 = 31;\npub const PF_SYSTEM: u32 = 32;\npub const PF_NETBIOS: u32 = 33;\npub const PF_PPP: u32 = 34;\npub const PF_AFP: u32 = 36;\npub const PF_UTUN: u32 = 38;\npub const PF_MULTIPATH: u32 = 39;\npub const PF_VSOCK: u32 = 40;\npub const PF_MAX: u32 = 41;\npub const NET_MAXID: u32 = 41;\npub const NET_RT_DUMP: u32 = 1;\npub const NET_RT_FLAGS: u32 = 2;\npub const NET_RT_IFLIST: u32 = 3;\npub const NET_RT_STAT: u32 = 4;\npub const NET_RT_TRASH: u32 = 5;\npub const NET_RT_IFLIST2: u32 = 6;\npub const NET_RT_DUMP2: u32 = 7;\npub const NET_RT_DUMPX: u32 = 8;\npub const NET_RT_DUMPX_FLAGS: u32 = 9;\npub const NET_RT_FLAGS_PRIV: u32 = 10;\npub const NET_RT_MAXID: u32 = 11;\npub const SO_STATISTICS_EVENT_ENTER_CELLFALLBACK: u32 = 1;\npub const SO_STATISTICS_EVENT_EXIT_CELLFALLBACK: u32 = 2;\npub const SO_STATISTICS_EVENT_RESERVED_1: u32 = 4;\npub const SO_STATISTICS_EVENT_RESERVED_2: u32 = 8;\npub const SOMAXCONN: u32 = 128;\npub const MSG_OOB: u32 = 1;\npub const MSG_PEEK: u32 = 2;\npub const MSG_DONTROUTE: u32 = 4;\npub const MSG_EOR: u32 = 8;\npub const MSG_TRUNC: u32 = 16;\npub const MSG_CTRUNC: u32 = 32;\npub const MSG_WAITALL: u32 = 64;\npub const MSG_DONTWAIT: u32 = 128;\npub const MSG_EOF: u32 = 256;\npub const MSG_WAITSTREAM: u32 = 512;\npub const MSG_FLUSH: u32 = 1024;\npub const MSG_HOLD: u32 = 2048;\npub const MSG_SEND: u32 = 4096;\npub const MSG_HAVEMORE: u32 = 8192;\npub const MSG_RCVMORE: u32 = 16384;\npub const MSG_NEEDSA: u32 = 65536;\npub const MSG_NOSIGNAL: u32 = 524288;\npub const SCM_RIGHTS: u32 = 1;\npub const SCM_TIMESTAMP: u32 = 2;\npub const SCM_CREDS: u32 = 3;\npub const SCM_TIMESTAMP_MONOTONIC: u32 = 4;\npub const SCM_TIMESTAMP_CONTINUOUS: u32 = 7;\npub const SCM_MPKL_SEND_INFO: u32 = 8;\npub const SCM_MPKL_RECV_INFO: u32 = 9;\npub const SHUT_RD: u32 = 0;\npub const SHUT_WR: u32 = 1;\npub const SHUT_RDWR: u32 = 2;\npub const CIF_CONNECTING: u32 = 1;\npub const CIF_CONNECTED: u32 = 2;\npub const CIF_DISCONNECTING: u32 = 4;\npub const CIF_DISCONNECTED: u32 = 8;\npub const CIF_BOUND_IF: u32 = 16;\npub const CIF_BOUND_IP: u32 = 32;\npub const CIF_BOUND_PORT: u32 = 64;\npub const CIF_PREFERRED: u32 = 128;\npub const CIF_MP_CAPABLE: u32 = 256;\npub const CIF_MP_READY: u32 = 512;\npub const CIF_MP_DEGRADED: u32 = 1024;\npub const CIF_MP_ACTIVE: u32 = 2048;\npub const CIAUX_TCP: u32 = 1;\npub const CIAUX_MPTCP: u32 = 2;\npub const IPPROTO_IP: u32 = 0;\npub const IPPROTO_HOPOPTS: u32 = 0;\npub const IPPROTO_ICMP: u32 = 1;\npub const IPPROTO_IGMP: u32 = 2;\npub const IPPROTO_GGP: u32 = 3;\npub const IPPROTO_IPV4: u32 = 4;\npub const IPPROTO_IPIP: u32 = 4;\npub const IPPROTO_TCP: u32 = 6;\npub const IPPROTO_ST: u32 = 7;\npub const IPPROTO_EGP: u32 = 8;\npub const IPPROTO_PIGP: u32 = 9;\npub const IPPROTO_RCCMON: u32 = 10;\npub const IPPROTO_NVPII: u32 = 11;\npub const IPPROTO_PUP: u32 = 12;\npub const IPPROTO_ARGUS: u32 = 13;\npub const IPPROTO_EMCON: u32 = 14;\npub const IPPROTO_XNET: u32 = 15;\npub const IPPROTO_CHAOS: u32 = 16;\npub const IPPROTO_UDP: u32 = 17;\npub const IPPROTO_MUX: u32 = 18;\npub const IPPROTO_MEAS: u32 = 19;\npub const IPPROTO_HMP: u32 = 20;\npub const IPPROTO_PRM: u32 = 21;\npub const IPPROTO_IDP: u32 = 22;\npub const IPPROTO_TRUNK1: u32 = 23;\npub const IPPROTO_TRUNK2: u32 = 24;\npub const IPPROTO_LEAF1: u32 = 25;\npub const IPPROTO_LEAF2: u32 = 26;\npub const IPPROTO_RDP: u32 = 27;\npub const IPPROTO_IRTP: u32 = 28;\npub const IPPROTO_TP: u32 = 29;\npub const IPPROTO_BLT: u32 = 30;\npub const IPPROTO_NSP: u32 = 31;\npub const IPPROTO_INP: u32 = 32;\npub const IPPROTO_SEP: u32 = 33;\npub const IPPROTO_3PC: u32 = 34;\npub const IPPROTO_IDPR: u32 = 35;\npub const IPPROTO_XTP: u32 = 36;\npub const IPPROTO_DDP: u32 = 37;\npub const IPPROTO_CMTP: u32 = 38;\npub const IPPROTO_TPXX: u32 = 39;\npub const IPPROTO_IL: u32 = 40;\npub const IPPROTO_IPV6: u32 = 41;\npub const IPPROTO_SDRP: u32 = 42;\npub const IPPROTO_ROUTING: u32 = 43;\npub const IPPROTO_FRAGMENT: u32 = 44;\npub const IPPROTO_IDRP: u32 = 45;\npub const IPPROTO_RSVP: u32 = 46;\npub const IPPROTO_GRE: u32 = 47;\npub const IPPROTO_MHRP: u32 = 48;\npub const IPPROTO_BHA: u32 = 49;\npub const IPPROTO_ESP: u32 = 50;\npub const IPPROTO_AH: u32 = 51;\npub const IPPROTO_INLSP: u32 = 52;\npub const IPPROTO_SWIPE: u32 = 53;\npub const IPPROTO_NHRP: u32 = 54;\npub const IPPROTO_ICMPV6: u32 = 58;\npub const IPPROTO_NONE: u32 = 59;\npub const IPPROTO_DSTOPTS: u32 = 60;\npub const IPPROTO_AHIP: u32 = 61;\npub const IPPROTO_CFTP: u32 = 62;\npub const IPPROTO_HELLO: u32 = 63;\npub const IPPROTO_SATEXPAK: u32 = 64;\npub const IPPROTO_KRYPTOLAN: u32 = 65;\npub const IPPROTO_RVD: u32 = 66;\npub const IPPROTO_IPPC: u32 = 67;\npub const IPPROTO_ADFS: u32 = 68;\npub const IPPROTO_SATMON: u32 = 69;\npub const IPPROTO_VISA: u32 = 70;\npub const IPPROTO_IPCV: u32 = 71;\npub const IPPROTO_CPNX: u32 = 72;\npub const IPPROTO_CPHB: u32 = 73;\npub const IPPROTO_WSN: u32 = 74;\npub const IPPROTO_PVP: u32 = 75;\npub const IPPROTO_BRSATMON: u32 = 76;\npub const IPPROTO_ND: u32 = 77;\npub const IPPROTO_WBMON: u32 = 78;\npub const IPPROTO_WBEXPAK: u32 = 79;\npub const IPPROTO_EON: u32 = 80;\npub const IPPROTO_VMTP: u32 = 81;\npub const IPPROTO_SVMTP: u32 = 82;\npub const IPPROTO_VINES: u32 = 83;\npub const IPPROTO_TTP: u32 = 84;\npub const IPPROTO_IGP: u32 = 85;\npub const IPPROTO_DGP: u32 = 86;\npub const IPPROTO_TCF: u32 = 87;\npub const IPPROTO_IGRP: u32 = 88;\npub const IPPROTO_OSPFIGP: u32 = 89;\npub const IPPROTO_SRPC: u32 = 90;\npub const IPPROTO_LARP: u32 = 91;\npub const IPPROTO_MTP: u32 = 92;\npub const IPPROTO_AX25: u32 = 93;\npub const IPPROTO_IPEIP: u32 = 94;\npub const IPPROTO_MICP: u32 = 95;\npub const IPPROTO_SCCSP: u32 = 96;\npub const IPPROTO_ETHERIP: u32 = 97;\npub const IPPROTO_ENCAP: u32 = 98;\npub const IPPROTO_APES: u32 = 99;\npub const IPPROTO_GMTP: u32 = 100;\npub const IPPROTO_PIM: u32 = 103;\npub const IPPROTO_IPCOMP: u32 = 108;\npub const IPPROTO_PGM: u32 = 113;\npub const IPPROTO_SCTP: u32 = 132;\npub const IPPROTO_QUIC: u32 = 253;\npub const IPPROTO_DIVERT: u32 = 254;\npub const IPPROTO_RAW: u32 = 255;\npub const IPPROTO_MAX: u32 = 256;\npub const IPPROTO_DONE: u32 = 257;\npub const __DARWIN_IPPORT_RESERVED: u32 = 1024;\npub const IPPORT_RESERVED: u32 = 1024;\npub const IPPORT_USERRESERVED: u32 = 5000;\npub const IPPORT_HIFIRSTAUTO: u32 = 49152;\npub const IPPORT_HILASTAUTO: u32 = 65535;\npub const IPPORT_RESERVEDSTART: u32 = 600;\npub const IN_CLASSA_NET: u32 = 4278190080;\npub const IN_CLASSA_NSHIFT: u32 = 24;\npub const IN_CLASSA_HOST: u32 = 16777215;\npub const IN_CLASSA_MAX: u32 = 128;\npub const IN_CLASSB_NET: u32 = 4294901760;\npub const IN_CLASSB_NSHIFT: u32 = 16;\npub const IN_CLASSB_HOST: u32 = 65535;\npub const IN_CLASSB_MAX: u32 = 65536;\npub const IN_CLASSC_NET: u32 = 4294967040;\npub const IN_CLASSC_NSHIFT: u32 = 8;\npub const IN_CLASSC_HOST: u32 = 255;\npub const IN_CLASSD_NET: u32 = 4026531840;\npub const IN_CLASSD_NSHIFT: u32 = 28;\npub const IN_CLASSD_HOST: u32 = 268435455;\npub const INADDR_NONE: u32 = 4294967295;\npub const IN_LOOPBACKNET: u32 = 127;\npub const INET_ADDRSTRLEN: u32 = 16;\npub const IP_OPTIONS: u32 = 1;\npub const IP_HDRINCL: u32 = 2;\npub const IP_TOS: u32 = 3;\npub const IP_TTL: u32 = 4;\npub const IP_RECVOPTS: u32 = 5;\npub const IP_RECVRETOPTS: u32 = 6;\npub const IP_RECVDSTADDR: u32 = 7;\npub const IP_RETOPTS: u32 = 8;\npub const IP_MULTICAST_IF: u32 = 9;\npub const IP_MULTICAST_TTL: u32 = 10;\npub const IP_MULTICAST_LOOP: u32 = 11;\npub const IP_ADD_MEMBERSHIP: u32 = 12;\npub const IP_DROP_MEMBERSHIP: u32 = 13;\npub const IP_MULTICAST_VIF: u32 = 14;\npub const IP_RSVP_ON: u32 = 15;\npub const IP_RSVP_OFF: u32 = 16;\npub const IP_RSVP_VIF_ON: u32 = 17;\npub const IP_RSVP_VIF_OFF: u32 = 18;\npub const IP_PORTRANGE: u32 = 19;\npub const IP_RECVIF: u32 = 20;\npub const IP_IPSEC_POLICY: u32 = 21;\npub const IP_FAITH: u32 = 22;\npub const IP_STRIPHDR: u32 = 23;\npub const IP_RECVTTL: u32 = 24;\npub const IP_BOUND_IF: u32 = 25;\npub const IP_PKTINFO: u32 = 26;\npub const IP_RECVPKTINFO: u32 = 26;\npub const IP_RECVTOS: u32 = 27;\npub const IP_DONTFRAG: u32 = 28;\npub const IP_FW_ADD: u32 = 40;\npub const IP_FW_DEL: u32 = 41;\npub const IP_FW_FLUSH: u32 = 42;\npub const IP_FW_ZERO: u32 = 43;\npub const IP_FW_GET: u32 = 44;\npub const IP_FW_RESETLOG: u32 = 45;\npub const IP_OLD_FW_ADD: u32 = 50;\npub const IP_OLD_FW_DEL: u32 = 51;\npub const IP_OLD_FW_FLUSH: u32 = 52;\npub const IP_OLD_FW_ZERO: u32 = 53;\npub const IP_OLD_FW_GET: u32 = 54;\npub const IP_NAT__XXX: u32 = 55;\npub const IP_OLD_FW_RESETLOG: u32 = 56;\npub const IP_DUMMYNET_CONFIGURE: u32 = 60;\npub const IP_DUMMYNET_DEL: u32 = 61;\npub const IP_DUMMYNET_FLUSH: u32 = 62;\npub const IP_DUMMYNET_GET: u32 = 64;\npub const IP_TRAFFIC_MGT_BACKGROUND: u32 = 65;\npub const IP_MULTICAST_IFINDEX: u32 = 66;\npub const IP_ADD_SOURCE_MEMBERSHIP: u32 = 70;\npub const IP_DROP_SOURCE_MEMBERSHIP: u32 = 71;\npub const IP_BLOCK_SOURCE: u32 = 72;\npub const IP_UNBLOCK_SOURCE: u32 = 73;\npub const IP_MSFILTER: u32 = 74;\npub const MCAST_JOIN_GROUP: u32 = 80;\npub const MCAST_LEAVE_GROUP: u32 = 81;\npub const MCAST_JOIN_SOURCE_GROUP: u32 = 82;\npub const MCAST_LEAVE_SOURCE_GROUP: u32 = 83;\npub const MCAST_BLOCK_SOURCE: u32 = 84;\npub const MCAST_UNBLOCK_SOURCE: u32 = 85;\npub const IP_NO_IFT_CELLULAR: u32 = 6969;\npub const IP_NO_IFT_PDP: u32 = 6969;\npub const IP_OUT_IF: u32 = 9696;\npub const IP_DEFAULT_MULTICAST_TTL: u32 = 1;\npub const IP_DEFAULT_MULTICAST_LOOP: u32 = 1;\npub const IP_MIN_MEMBERSHIPS: u32 = 31;\npub const IP_MAX_MEMBERSHIPS: u32 = 4095;\npub const IP_MAX_GROUP_SRC_FILTER: u32 = 512;\npub const IP_MAX_SOCK_SRC_FILTER: u32 = 128;\npub const IP_MAX_SOCK_MUTE_FILTER: u32 = 128;\npub const MCAST_UNDEFINED: u32 = 0;\npub const MCAST_INCLUDE: u32 = 1;\npub const MCAST_EXCLUDE: u32 = 2;\npub const IP_PORTRANGE_DEFAULT: u32 = 0;\npub const IP_PORTRANGE_HIGH: u32 = 1;\npub const IP_PORTRANGE_LOW: u32 = 2;\npub const IPPROTO_MAXID: u32 = 52;\npub const IPCTL_FORWARDING: u32 = 1;\npub const IPCTL_SENDREDIRECTS: u32 = 2;\npub const IPCTL_DEFTTL: u32 = 3;\npub const IPCTL_RTEXPIRE: u32 = 5;\npub const IPCTL_RTMINEXPIRE: u32 = 6;\npub const IPCTL_RTMAXCACHE: u32 = 7;\npub const IPCTL_SOURCEROUTE: u32 = 8;\npub const IPCTL_DIRECTEDBROADCAST: u32 = 9;\npub const IPCTL_INTRQMAXLEN: u32 = 10;\npub const IPCTL_INTRQDROPS: u32 = 11;\npub const IPCTL_STATS: u32 = 12;\npub const IPCTL_ACCEPTSOURCEROUTE: u32 = 13;\npub const IPCTL_FASTFORWARDING: u32 = 14;\npub const IPCTL_KEEPFAITH: u32 = 15;\npub const IPCTL_GIF_TTL: u32 = 16;\npub const IPCTL_MAXID: u32 = 17;\npub const __KAME_VERSION: &[u8; 18] = b\"2009/apple-darwin\\0\";\npub const IPV6PORT_RESERVED: u32 = 1024;\npub const IPV6PORT_ANONMIN: u32 = 49152;\npub const IPV6PORT_ANONMAX: u32 = 65535;\npub const IPV6PORT_RESERVEDMIN: u32 = 600;\npub const IPV6PORT_RESERVEDMAX: u32 = 1023;\npub const INET6_ADDRSTRLEN: u32 = 46;\npub const __IPV6_ADDR_SCOPE_NODELOCAL: u32 = 1;\npub const __IPV6_ADDR_SCOPE_INTFACELOCAL: u32 = 1;\npub const __IPV6_ADDR_SCOPE_LINKLOCAL: u32 = 2;\npub const __IPV6_ADDR_SCOPE_SITELOCAL: u32 = 5;\npub const __IPV6_ADDR_SCOPE_ORGLOCAL: u32 = 8;\npub const __IPV6_ADDR_SCOPE_GLOBAL: u32 = 14;\npub const IPV6_ADDR_MC_FLAGS_TRANSIENT: u32 = 16;\npub const IPV6_ADDR_MC_FLAGS_PREFIX: u32 = 32;\npub const IPV6_ADDR_MC_FLAGS_UNICAST_BASED: u32 = 48;\npub const IPV6_SOCKOPT_RESERVED1: u32 = 3;\npub const IPV6_UNICAST_HOPS: u32 = 4;\npub const IPV6_MULTICAST_IF: u32 = 9;\npub const IPV6_MULTICAST_HOPS: u32 = 10;\npub const IPV6_MULTICAST_LOOP: u32 = 11;\npub const IPV6_JOIN_GROUP: u32 = 12;\npub const IPV6_LEAVE_GROUP: u32 = 13;\npub const IPV6_PORTRANGE: u32 = 14;\npub const ICMP6_FILTER: u32 = 18;\npub const IPV6_2292PKTINFO: u32 = 19;\npub const IPV6_2292HOPLIMIT: u32 = 20;\npub const IPV6_2292NEXTHOP: u32 = 21;\npub const IPV6_2292HOPOPTS: u32 = 22;\npub const IPV6_2292DSTOPTS: u32 = 23;\npub const IPV6_2292RTHDR: u32 = 24;\npub const IPV6_2292PKTOPTIONS: u32 = 25;\npub const IPV6_CHECKSUM: u32 = 26;\npub const IPV6_V6ONLY: u32 = 27;\npub const IPV6_BINDV6ONLY: u32 = 27;\npub const IPV6_IPSEC_POLICY: u32 = 28;\npub const IPV6_FAITH: u32 = 29;\npub const IPV6_FW_ADD: u32 = 30;\npub const IPV6_FW_DEL: u32 = 31;\npub const IPV6_FW_FLUSH: u32 = 32;\npub const IPV6_FW_ZERO: u32 = 33;\npub const IPV6_FW_GET: u32 = 34;\npub const IPV6_RECVTCLASS: u32 = 35;\npub const IPV6_TCLASS: u32 = 36;\npub const IPV6_BOUND_IF: u32 = 125;\npub const IPV6_NO_IFT_CELLULAR: u32 = 6969;\npub const IPV6_OUT_IF: u32 = 9696;\npub const IPV6_RTHDR_LOOSE: u32 = 0;\npub const IPV6_RTHDR_STRICT: u32 = 1;\npub const IPV6_RTHDR_TYPE_0: u32 = 0;\npub const IPV6_DEFAULT_MULTICAST_HOPS: u32 = 1;\npub const IPV6_DEFAULT_MULTICAST_LOOP: u32 = 1;\npub const IPV6_MIN_MEMBERSHIPS: u32 = 31;\npub const IPV6_MAX_MEMBERSHIPS: u32 = 4095;\npub const IPV6_MAX_GROUP_SRC_FILTER: u32 = 512;\npub const IPV6_MAX_SOCK_SRC_FILTER: u32 = 128;\npub const IPV6_PORTRANGE_DEFAULT: u32 = 0;\npub const IPV6_PORTRANGE_HIGH: u32 = 1;\npub const IPV6_PORTRANGE_LOW: u32 = 2;\npub const IPV6PROTO_MAXID: u32 = 104;\npub const IPV6CTL_FORWARDING: u32 = 1;\npub const IPV6CTL_SENDREDIRECTS: u32 = 2;\npub const IPV6CTL_DEFHLIM: u32 = 3;\npub const IPV6CTL_FORWSRCRT: u32 = 5;\npub const IPV6CTL_STATS: u32 = 6;\npub const IPV6CTL_MRTSTATS: u32 = 7;\npub const IPV6CTL_MRTPROTO: u32 = 8;\npub const IPV6CTL_MAXFRAGPACKETS: u32 = 9;\npub const IPV6CTL_SOURCECHECK: u32 = 10;\npub const IPV6CTL_SOURCECHECK_LOGINT: u32 = 11;\npub const IPV6CTL_ACCEPT_RTADV: u32 = 12;\npub const IPV6CTL_KEEPFAITH: u32 = 13;\npub const IPV6CTL_LOG_INTERVAL: u32 = 14;\npub const IPV6CTL_HDRNESTLIMIT: u32 = 15;\npub const IPV6CTL_DAD_COUNT: u32 = 16;\npub const IPV6CTL_AUTO_FLOWLABEL: u32 = 17;\npub const IPV6CTL_DEFMCASTHLIM: u32 = 18;\npub const IPV6CTL_GIF_HLIM: u32 = 19;\npub const IPV6CTL_KAME_VERSION: u32 = 20;\npub const IPV6CTL_USE_DEPRECATED: u32 = 21;\npub const IPV6CTL_RR_PRUNE: u32 = 22;\npub const IPV6CTL_V6ONLY: u32 = 24;\npub const IPV6CTL_RTEXPIRE: u32 = 25;\npub const IPV6CTL_RTMINEXPIRE: u32 = 26;\npub const IPV6CTL_RTMAXCACHE: u32 = 27;\npub const IPV6CTL_USETEMPADDR: u32 = 32;\npub const IPV6CTL_TEMPPLTIME: u32 = 33;\npub const IPV6CTL_TEMPVLTIME: u32 = 34;\npub const IPV6CTL_AUTO_LINKLOCAL: u32 = 35;\npub const IPV6CTL_RIP6STATS: u32 = 36;\npub const IPV6CTL_PREFER_TEMPADDR: u32 = 37;\npub const IPV6CTL_ADDRCTLPOLICY: u32 = 38;\npub const IPV6CTL_USE_DEFAULTZONE: u32 = 39;\npub const IPV6CTL_MAXFRAGS: u32 = 41;\npub const IPV6CTL_MCAST_PMTU: u32 = 44;\npub const IPV6CTL_NEIGHBORGCTHRESH: u32 = 46;\npub const IPV6CTL_MAXIFPREFIXES: u32 = 47;\npub const IPV6CTL_MAXIFDEFROUTERS: u32 = 48;\npub const IPV6CTL_MAXDYNROUTES: u32 = 49;\npub const ICMPV6CTL_ND6_ONLINKNSRFC4861: u32 = 50;\npub const IPV6CTL_ULA_USETEMPADDR: u32 = 51;\npub const IPV6CTL_MAXID: u32 = 51;\npub const _DSCP_DF: u32 = 0;\npub const _DSCP_CS0: u32 = 0;\npub const _DSCP_CS1: u32 = 8;\npub const _DSCP_CS2: u32 = 16;\npub const _DSCP_CS3: u32 = 24;\npub const _DSCP_CS4: u32 = 32;\npub const _DSCP_CS5: u32 = 40;\npub const _DSCP_CS6: u32 = 48;\npub const _DSCP_CS7: u32 = 56;\npub const _DSCP_EF: u32 = 46;\npub const _DSCP_VA: u32 = 44;\npub const _DSCP_AF11: u32 = 10;\npub const _DSCP_AF12: u32 = 12;\npub const _DSCP_AF13: u32 = 14;\npub const _DSCP_AF21: u32 = 18;\npub const _DSCP_AF22: u32 = 20;\npub const _DSCP_AF23: u32 = 22;\npub const _DSCP_AF31: u32 = 26;\npub const _DSCP_AF32: u32 = 28;\npub const _DSCP_AF33: u32 = 30;\npub const _DSCP_AF41: u32 = 34;\npub const _DSCP_AF42: u32 = 36;\npub const _DSCP_AF43: u32 = 38;\npub const _DSCP_52: u32 = 52;\npub const _MAX_DSCP: u32 = 63;\npub const ITIMER_REAL: u32 = 0;\npub const ITIMER_VIRTUAL: u32 = 1;\npub const ITIMER_PROF: u32 = 2;\npub const DST_NONE: u32 = 0;\npub const DST_USA: u32 = 1;\npub const DST_AUST: u32 = 2;\npub const DST_WET: u32 = 3;\npub const DST_MET: u32 = 4;\npub const DST_EET: u32 = 5;\npub const DST_CAN: u32 = 6;\npub const __DARWIN_WCHAR_MIN: i32 = -2147483648;\npub const _FORTIFY_SOURCE: u32 = 2;\npub const TIME_UTC: u32 = 1;\npub const RTM_RTTUNIT: u32 = 1000000;\npub const RTF_UP: u32 = 1;\npub const RTF_GATEWAY: u32 = 2;\npub const RTF_HOST: u32 = 4;\npub const RTF_REJECT: u32 = 8;\npub const RTF_DYNAMIC: u32 = 16;\npub const RTF_MODIFIED: u32 = 32;\npub const RTF_DONE: u32 = 64;\npub const RTF_DELCLONE: u32 = 128;\npub const RTF_CLONING: u32 = 256;\npub const RTF_XRESOLVE: u32 = 512;\npub const RTF_LLINFO: u32 = 1024;\npub const RTF_LLDATA: u32 = 1024;\npub const RTF_STATIC: u32 = 2048;\npub const RTF_BLACKHOLE: u32 = 4096;\npub const RTF_NOIFREF: u32 = 8192;\npub const RTF_PROTO2: u32 = 16384;\npub const RTF_PROTO1: u32 = 32768;\npub const RTF_PRCLONING: u32 = 65536;\npub const RTF_WASCLONED: u32 = 131072;\npub const RTF_PROTO3: u32 = 262144;\npub const RTF_PINNED: u32 = 1048576;\npub const RTF_LOCAL: u32 = 2097152;\npub const RTF_BROADCAST: u32 = 4194304;\npub const RTF_MULTICAST: u32 = 8388608;\npub const RTF_IFSCOPE: u32 = 16777216;\npub const RTF_CONDEMNED: u32 = 33554432;\npub const RTF_IFREF: u32 = 67108864;\npub const RTF_PROXY: u32 = 134217728;\npub const RTF_ROUTER: u32 = 268435456;\npub const RTF_DEAD: u32 = 536870912;\npub const RTF_GLOBAL: u32 = 1073741824;\npub const RTPRF_OURS: u32 = 262144;\npub const RTF_BITS : & [u8 ; 223] = b\"\\x10\\x01UP\\x02GATEWAY\\x03HOST\\x04REJECT\\x05DYNAMIC\\x06MODIFIED\\x07DONE\\x08DELCLONE\\tCLONING\\nXRESOLVE\\x0BLLINFO\\x0CSTATIC\\rBLACKHOLE\\x0ENOIFREF\\x0FPROTO2\\x10PROTO1\\x11PRCLONING\\x12WASCLONED\\x13PROTO3\\x15PINNED\\x16LOCAL\\x17BROADCAST\\x18MULTICAST\\x19IFSCOPE\\x1ACONDEMNED\\x1BIFREF\\x1CPROXY\\x1DROUTER\\x1FGLOBAL\\0\" ;\npub const RTM_VERSION: u32 = 5;\npub const RTM_ADD: u32 = 1;\npub const RTM_DELETE: u32 = 2;\npub const RTM_CHANGE: u32 = 3;\npub const RTM_GET: u32 = 4;\npub const RTM_LOSING: u32 = 5;\npub const RTM_REDIRECT: u32 = 6;\npub const RTM_MISS: u32 = 7;\npub const RTM_LOCK: u32 = 8;\npub const RTM_OLDADD: u32 = 9;\npub const RTM_OLDDEL: u32 = 10;\npub const RTM_RESOLVE: u32 = 11;\npub const RTM_NEWADDR: u32 = 12;\npub const RTM_DELADDR: u32 = 13;\npub const RTM_IFINFO: u32 = 14;\npub const RTM_NEWMADDR: u32 = 15;\npub const RTM_DELMADDR: u32 = 16;\npub const RTM_GET_SILENT: u32 = 17;\npub const RTM_IFINFO2: u32 = 18;\npub const RTM_NEWMADDR2: u32 = 19;\npub const RTM_GET2: u32 = 20;\npub const RTM_GET_EXT: u32 = 21;\npub const RTV_MTU: u32 = 1;\npub const RTV_HOPCOUNT: u32 = 2;\npub const RTV_EXPIRE: u32 = 4;\npub const RTV_RPIPE: u32 = 8;\npub const RTV_SPIPE: u32 = 16;\npub const RTV_SSTHRESH: u32 = 32;\npub const RTV_RTT: u32 = 64;\npub const RTV_RTTVAR: u32 = 128;\npub const RTV_REFRESH_HOST: u32 = 256;\npub const RTA_DST: u32 = 1;\npub const RTA_GATEWAY: u32 = 2;\npub const RTA_NETMASK: u32 = 4;\npub const RTA_GENMASK: u32 = 8;\npub const RTA_IFP: u32 = 16;\npub const RTA_IFA: u32 = 32;\npub const RTA_AUTHOR: u32 = 64;\npub const RTA_BRD: u32 = 128;\npub const RTAX_DST: u32 = 0;\npub const RTAX_GATEWAY: u32 = 1;\npub const RTAX_NETMASK: u32 = 2;\npub const RTAX_GENMASK: u32 = 3;\npub const RTAX_IFP: u32 = 4;\npub const RTAX_IFA: u32 = 5;\npub const RTAX_AUTHOR: u32 = 6;\npub const RTAX_BRD: u32 = 7;\npub const RTAX_MAX: u32 = 8;\npub const IFSCOPE_NONE: u32 = 0;\npub const APPLE_IF_FAM_LOOPBACK: u32 = 1;\npub const APPLE_IF_FAM_ETHERNET: u32 = 2;\npub const APPLE_IF_FAM_SLIP: u32 = 3;\npub const APPLE_IF_FAM_TUN: u32 = 4;\npub const APPLE_IF_FAM_VLAN: u32 = 5;\npub const APPLE_IF_FAM_PPP: u32 = 6;\npub const APPLE_IF_FAM_PVC: u32 = 7;\npub const APPLE_IF_FAM_DISC: u32 = 8;\npub const APPLE_IF_FAM_MDECAP: u32 = 9;\npub const APPLE_IF_FAM_GIF: u32 = 10;\npub const APPLE_IF_FAM_FAITH: u32 = 11;\npub const APPLE_IF_FAM_STF: u32 = 12;\npub const APPLE_IF_FAM_FIREWIRE: u32 = 13;\npub const APPLE_IF_FAM_BOND: u32 = 14;\npub const APPLE_IF_FAM_CELLULAR: u32 = 15;\npub const APPLE_IF_FAM_6LOWPAN: u32 = 16;\npub const APPLE_IF_FAM_UTUN: u32 = 17;\npub const APPLE_IF_FAM_IPSEC: u32 = 18;\npub const IF_MINMTU: u32 = 72;\npub const IF_MAXMTU: u32 = 65535;\npub const IFNAMSIZ: u32 = 16;\npub const IF_NETEM_PARAMS_PSCALE: u32 = 100000;\npub const IF_VAR_H_HAS_IFNET_STATS_PER_FLOW: u32 = 1;\npub const IF_CELLULAR_STATUS_REPORT_VERSION_1: u32 = 1;\npub const IF_WIFI_STATUS_REPORT_VERSION_1: u32 = 1;\npub const IF_CELLULAR_STATUS_REPORT_CURRENT_VERSION: u32 = 1;\npub const IF_WIFI_STATUS_REPORT_CURRENT_VERSION: u32 = 1;\npub const IF_CELL_LINK_QUALITY_METRIC_VALID: u32 = 1;\npub const IF_CELL_UL_EFFECTIVE_BANDWIDTH_VALID: u32 = 2;\npub const IF_CELL_UL_MAX_BANDWIDTH_VALID: u32 = 4;\npub const IF_CELL_UL_MIN_LATENCY_VALID: u32 = 8;\npub const IF_CELL_UL_EFFECTIVE_LATENCY_VALID: u32 = 16;\npub const IF_CELL_UL_MAX_LATENCY_VALID: u32 = 32;\npub const IF_CELL_UL_RETXT_LEVEL_VALID: u32 = 64;\npub const IF_CELL_UL_BYTES_LOST_VALID: u32 = 128;\npub const IF_CELL_UL_MIN_QUEUE_SIZE_VALID: u32 = 256;\npub const IF_CELL_UL_AVG_QUEUE_SIZE_VALID: u32 = 512;\npub const IF_CELL_UL_MAX_QUEUE_SIZE_VALID: u32 = 1024;\npub const IF_CELL_DL_EFFECTIVE_BANDWIDTH_VALID: u32 = 2048;\npub const IF_CELL_DL_MAX_BANDWIDTH_VALID: u32 = 4096;\npub const IF_CELL_CONFIG_INACTIVITY_TIME_VALID: u32 = 8192;\npub const IF_CELL_CONFIG_BACKOFF_TIME_VALID: u32 = 16384;\npub const IF_CELL_UL_MSS_RECOMMENDED_VALID: u32 = 32768;\npub const IF_CELL_UL_RETXT_LEVEL_NONE: u32 = 1;\npub const IF_CELL_UL_RETXT_LEVEL_LOW: u32 = 2;\npub const IF_CELL_UL_RETXT_LEVEL_MEDIUM: u32 = 3;\npub const IF_CELL_UL_RETXT_LEVEL_HIGH: u32 = 4;\npub const IF_CELL_UL_MSS_RECOMMENDED_NONE: u32 = 0;\npub const IF_CELL_UL_MSS_RECOMMENDED_MEDIUM: u32 = 1;\npub const IF_CELL_UL_MSS_RECOMMENDED_LOW: u32 = 2;\npub const IF_WIFI_LINK_QUALITY_METRIC_VALID: u32 = 1;\npub const IF_WIFI_UL_EFFECTIVE_BANDWIDTH_VALID: u32 = 2;\npub const IF_WIFI_UL_MAX_BANDWIDTH_VALID: u32 = 4;\npub const IF_WIFI_UL_MIN_LATENCY_VALID: u32 = 8;\npub const IF_WIFI_UL_EFFECTIVE_LATENCY_VALID: u32 = 16;\npub const IF_WIFI_UL_MAX_LATENCY_VALID: u32 = 32;\npub const IF_WIFI_UL_RETXT_LEVEL_VALID: u32 = 64;\npub const IF_WIFI_UL_ERROR_RATE_VALID: u32 = 128;\npub const IF_WIFI_UL_BYTES_LOST_VALID: u32 = 256;\npub const IF_WIFI_DL_EFFECTIVE_BANDWIDTH_VALID: u32 = 512;\npub const IF_WIFI_DL_MAX_BANDWIDTH_VALID: u32 = 1024;\npub const IF_WIFI_DL_MIN_LATENCY_VALID: u32 = 2048;\npub const IF_WIFI_DL_EFFECTIVE_LATENCY_VALID: u32 = 4096;\npub const IF_WIFI_DL_MAX_LATENCY_VALID: u32 = 8192;\npub const IF_WIFI_DL_ERROR_RATE_VALID: u32 = 16384;\npub const IF_WIFI_CONFIG_FREQUENCY_VALID: u32 = 32768;\npub const IF_WIFI_CONFIG_MULTICAST_RATE_VALID: u32 = 65536;\npub const IF_WIFI_CONFIG_SCAN_COUNT_VALID: u32 = 131072;\npub const IF_WIFI_CONFIG_SCAN_DURATION_VALID: u32 = 262144;\npub const IF_WIFI_UL_RETXT_LEVEL_NONE: u32 = 1;\npub const IF_WIFI_UL_RETXT_LEVEL_LOW: u32 = 2;\npub const IF_WIFI_UL_RETXT_LEVEL_MEDIUM: u32 = 3;\npub const IF_WIFI_UL_RETXT_LEVEL_HIGH: u32 = 4;\npub const IF_WIFI_CONFIG_FREQUENCY_2_4_GHZ: u32 = 1;\npub const IF_WIFI_CONFIG_FREQUENCY_5_0_GHZ: u32 = 2;\npub const IF_INTERFACE_STATE_RRC_STATE_VALID: u32 = 1;\npub const IF_INTERFACE_STATE_LQM_STATE_VALID: u32 = 2;\npub const IF_INTERFACE_STATE_INTERFACE_AVAILABILITY_VALID: u32 = 4;\npub const IF_INTERFACE_STATE_RRC_STATE_IDLE: u32 = 0;\npub const IF_INTERFACE_STATE_RRC_STATE_CONNECTED: u32 = 1;\npub const IF_INTERFACE_STATE_INTERFACE_AVAILABLE: u32 = 0;\npub const IF_INTERFACE_STATE_INTERFACE_UNAVAILABLE: u32 = 1;\npub const IF_INTERFACE_ADVISORY_VERSION_1: u32 = 1;\npub const IF_INTERFACE_ADVISORY_VERSION_CURRENT: u32 = 1;\npub const IF_INTERFACE_ADVISORY_DIRECTION_TX: u32 = 1;\npub const IF_INTERFACE_ADVISORY_DIRECTION_RX: u32 = 2;\npub const IF_INTERFACE_ADVISORY_RATE_SUGGESTION_RAMP_UP: u32 = 2147483647;\npub const IF_INTERFACE_ADVISORY_RATE_SUGGESTION_RAMP_DOWN: i32 = -2147483648;\npub const IF_INTERFACE_ADVISORY_RATE_SUGGESTION_RAMP_NEUTRAL: u32 = 0;\npub const IF_HWASSIST_CSUM_IP: u32 = 1;\npub const IF_HWASSIST_CSUM_TCP: u32 = 2;\npub const IF_HWASSIST_CSUM_UDP: u32 = 4;\npub const IF_HWASSIST_CSUM_IP_FRAGS: u32 = 8;\npub const IF_HWASSIST_CSUM_FRAGMENT: u32 = 16;\npub const IF_HWASSIST_CSUM_TCPIPV6: u32 = 32;\npub const IF_HWASSIST_CSUM_UDPIPV6: u32 = 64;\npub const IF_HWASSIST_CSUM_FRAGMENT_IPV6: u32 = 128;\npub const IF_HWASSIST_CSUM_PARTIAL: u32 = 4096;\npub const IF_HWASSIST_CSUM_ZERO_INVERT: u32 = 8192;\npub const IF_HWASSIST_CSUM_MASK: u32 = 65535;\npub const IF_HWASSIST_VLAN_TAGGING: u32 = 65536;\npub const IF_HWASSIST_VLAN_MTU: u32 = 131072;\npub const IF_HWASSIST_TSO_V4: u32 = 2097152;\npub const IF_HWASSIST_TSO_V6: u32 = 4194304;\npub const IFXNAMSIZ: u32 = 24;\npub const IFNET_NETWORK_ID_LEN: u32 = 32;\npub const PF_MD5_DIGEST_LENGTH: u32 = 16;\npub const PF_GRE_PPTP_VARIANT: u32 = 1;\npub const PFTM_TCP_FIRST_PACKET_VAL: u32 = 120;\npub const PFTM_TCP_OPENING_VAL: u32 = 30;\npub const PFTM_TCP_ESTABLISHED_VAL: u32 = 86400;\npub const PFTM_TCP_CLOSING_VAL: u32 = 900;\npub const PFTM_TCP_FIN_WAIT_VAL: u32 = 45;\npub const PFTM_TCP_CLOSED_VAL: u32 = 90;\npub const PFTM_UDP_FIRST_PACKET_VAL: u32 = 60;\npub const PFTM_UDP_SINGLE_VAL: u32 = 30;\npub const PFTM_UDP_MULTIPLE_VAL: u32 = 60;\npub const PFTM_ICMP_FIRST_PACKET_VAL: u32 = 20;\npub const PFTM_ICMP_ERROR_REPLY_VAL: u32 = 10;\npub const PFTM_GREv1_FIRST_PACKET_VAL: u32 = 120;\npub const PFTM_GREv1_INITIATING_VAL: u32 = 30;\npub const PFTM_GREv1_ESTABLISHED_VAL: u32 = 1800;\npub const PFTM_ESP_FIRST_PACKET_VAL: u32 = 120;\npub const PFTM_ESP_INITIATING_VAL: u32 = 30;\npub const PFTM_ESP_ESTABLISHED_VAL: u32 = 900;\npub const PFTM_OTHER_FIRST_PACKET_VAL: u32 = 60;\npub const PFTM_OTHER_SINGLE_VAL: u32 = 30;\npub const PFTM_OTHER_MULTIPLE_VAL: u32 = 60;\npub const PFTM_FRAG_VAL: u32 = 30;\npub const PFTM_INTERVAL_VAL: u32 = 10;\npub const PFTM_SRC_NODE_VAL: u32 = 0;\npub const PFTM_TS_DIFF_VAL: u32 = 30;\npub const PF_POOL_IDMASK: u32 = 15;\npub const PF_POOL_TYPEMASK: u32 = 15;\npub const PF_POOL_STICKYADDR: u32 = 32;\npub const PF_WSCALE_FLAG: u32 = 128;\npub const PF_WSCALE_MASK: u32 = 15;\npub const PF_LOG: u32 = 1;\npub const PF_LOG_ALL: u32 = 2;\npub const PF_LOG_SOCKET_LOOKUP: u32 = 4;\npub const PF_TABLE_NAME_SIZE: u32 = 32;\npub const PFI_AFLAG_NETWORK: u32 = 1;\npub const PFI_AFLAG_BROADCAST: u32 = 2;\npub const PFI_AFLAG_PEER: u32 = 4;\npub const PFI_AFLAG_MODEMASK: u32 = 7;\npub const PFI_AFLAG_NOALIAS: u32 = 8;\npub const RTLABEL_LEN: u32 = 32;\npub const PF_OSFP_EXPANDED: u32 = 1;\npub const PF_OSFP_GENERIC: u32 = 2;\npub const PF_OSFP_NODETAIL: u32 = 4;\npub const PF_OSFP_LEN: u32 = 32;\npub const _FP_RESERVED_BIT: u32 = 1;\npub const _FP_UNUSED_BITS: u32 = 1;\npub const _FP_CLASS_BITS: u32 = 10;\npub const _FP_VERSION_BITS: u32 = 10;\npub const _FP_SUBTYPE_BITS: u32 = 10;\npub const PF_OSFP_WSIZE_MOD: u32 = 1;\npub const PF_OSFP_WSIZE_DC: u32 = 2;\npub const PF_OSFP_WSIZE_MSS: u32 = 4;\npub const PF_OSFP_WSIZE_MTU: u32 = 8;\npub const PF_OSFP_PSIZE_MOD: u32 = 16;\npub const PF_OSFP_PSIZE_DC: u32 = 32;\npub const PF_OSFP_WSCALE: u32 = 64;\npub const PF_OSFP_WSCALE_MOD: u32 = 128;\npub const PF_OSFP_WSCALE_DC: u32 = 256;\npub const PF_OSFP_MSS: u32 = 512;\npub const PF_OSFP_MSS_MOD: u32 = 1024;\npub const PF_OSFP_MSS_DC: u32 = 2048;\npub const PF_OSFP_DF: u32 = 4096;\npub const PF_OSFP_TS0: u32 = 8192;\npub const PF_OSFP_INET6: u32 = 16384;\npub const PF_OSFP_MAXTTL_OFFSET: u32 = 40;\npub const PF_OSFP_TCPOPT_NOP: u32 = 0;\npub const PF_OSFP_TCPOPT_WSCALE: u32 = 1;\npub const PF_OSFP_TCPOPT_MSS: u32 = 2;\npub const PF_OSFP_TCPOPT_SACK: u32 = 3;\npub const PF_OSFP_TCPOPT_TS: u32 = 4;\npub const PF_OSFP_TCPOPT_BITS: u32 = 3;\npub const PF_ANCHOR_NAME_SIZE: u32 = 64;\npub const PF_SKIP_IFP: u32 = 0;\npub const PF_SKIP_DIR: u32 = 1;\npub const PF_SKIP_AF: u32 = 2;\npub const PF_SKIP_PROTO: u32 = 3;\npub const PF_SKIP_SRC_ADDR: u32 = 4;\npub const PF_SKIP_SRC_PORT: u32 = 5;\npub const PF_SKIP_DST_ADDR: u32 = 6;\npub const PF_SKIP_DST_PORT: u32 = 7;\npub const PF_SKIP_COUNT: u32 = 8;\npub const PF_RULE_LABEL_SIZE: u32 = 64;\npub const PF_QNAME_SIZE: u32 = 64;\npub const PF_TAG_NAME_SIZE: u32 = 64;\npub const PF_OWNER_NAME_SIZE: u32 = 64;\npub const PF_STATE_NORMAL: u32 = 1;\npub const PF_STATE_MODULATE: u32 = 2;\npub const PF_STATE_SYNPROXY: u32 = 3;\npub const SCIDX_MASK: u32 = 15;\npub const SC_BE: u32 = 16;\npub const SC_BK_SYS: u32 = 17;\npub const SC_BK: u32 = 18;\npub const SC_RD: u32 = 19;\npub const SC_OAM: u32 = 20;\npub const SC_AV: u32 = 21;\npub const SC_RV: u32 = 22;\npub const SC_VI: u32 = 23;\npub const SC_SIG: u32 = 23;\npub const SC_VO: u32 = 24;\npub const SC_CTL: u32 = 25;\npub const DSCP_MASK: u32 = 252;\npub const DSCP_CUMASK: u32 = 3;\npub const DSCP_EF: u32 = 184;\npub const DSCP_AF11: u32 = 40;\npub const DSCP_AF12: u32 = 48;\npub const DSCP_AF13: u32 = 56;\npub const DSCP_AF21: u32 = 72;\npub const DSCP_AF22: u32 = 80;\npub const DSCP_AF23: u32 = 88;\npub const DSCP_AF31: u32 = 104;\npub const DSCP_AF32: u32 = 112;\npub const DSCP_AF33: u32 = 120;\npub const DSCP_AF41: u32 = 136;\npub const DSCP_AF42: u32 = 144;\npub const DSCP_AF43: u32 = 152;\npub const AF_CLASSMASK: u32 = 224;\npub const AF_DROPPRECMASK: u32 = 24;\npub const PF_FLUSH: u32 = 1;\npub const PF_FLUSH_GLOBAL: u32 = 2;\npub const PFDEV_PF: u32 = 0;\npub const PFDEV_PFM: u32 = 1;\npub const PFDEV_MAX: u32 = 2;\npub const PFRULE_DROP: u32 = 0;\npub const PFRULE_RETURNRST: u32 = 1;\npub const PFRULE_FRAGMENT: u32 = 2;\npub const PFRULE_RETURNICMP: u32 = 4;\npub const PFRULE_RETURN: u32 = 8;\npub const PFRULE_NOSYNC: u32 = 16;\npub const PFRULE_SRCTRACK: u32 = 32;\npub const PFRULE_RULESRCTRACK: u32 = 64;\npub const PFRULE_NODF: u32 = 256;\npub const PFRULE_FRAGCROP: u32 = 512;\npub const PFRULE_FRAGDROP: u32 = 1024;\npub const PFRULE_RANDOMID: u32 = 2048;\npub const PFRULE_REASSEMBLE_TCP: u32 = 4096;\npub const PFRULE_TOS: u32 = 8192;\npub const PFRULE_DSCP: u32 = 16384;\npub const PFRULE_SC: u32 = 32768;\npub const PFRULE_IFBOUND: u32 = 65536;\npub const PFRULE_PFM: u32 = 131072;\npub const PFSTATE_HIWAT: u32 = 10000;\npub const PFSTATE_ADAPT_START: u32 = 6000;\npub const PFSTATE_ADAPT_END: u32 = 12000;\npub const PFAPPSTATE_HIWAT: u32 = 10000;\npub const PF_TAG_NAME_SYSTEM_SERVICE: &[u8; 32] = b\"com.apple.pf.system_service_tag\\0\";\npub const PF_TAG_NAME_STACK_DROP: &[u8; 28] = b\"com.apple.pf.stack_drop_tag\\0\";\npub const PF_THRESHOLD_MULT: u32 = 1000;\npub const PF_THRESHOLD_MAX: u32 = 4294967;\npub const PFSNODE_HIWAT: u32 = 10000;\npub const PFSTATE_NOSYNC: u32 = 1;\npub const PFSTATE_FROMSYNC: u32 = 2;\npub const PFSTATE_STALE: u32 = 4;\npub const PFSYNC_SCRUB_FLAG_VALID: u32 = 1;\npub const PFSYNC_FLAG_COMPRESS: u32 = 1;\npub const PFSYNC_FLAG_STALE: u32 = 2;\npub const PFSYNC_FLAG_SRCNODE: u32 = 4;\npub const PFSYNC_FLAG_NATSRCNODE: u32 = 8;\npub const PF_RESERVED_ANCHOR: &[u8; 4] = b\"_pf\\0\";\npub const PFR_TFLAG_PERSIST: u32 = 1;\npub const PFR_TFLAG_CONST: u32 = 2;\npub const PFR_TFLAG_ACTIVE: u32 = 4;\npub const PFR_TFLAG_INACTIVE: u32 = 8;\npub const PFR_TFLAG_REFERENCED: u32 = 16;\npub const PFR_TFLAG_REFDANCHOR: u32 = 32;\npub const PFR_TFLAG_USRMASK: u32 = 3;\npub const PFR_TFLAG_SETMASK: u32 = 60;\npub const PFR_TFLAG_ALLMASK: u32 = 63;\npub const PFI_IFLAG_SKIP: u32 = 256;\npub const PF_DPORT_RANGE: u32 = 1;\npub const PF_RPORT_RANGE: u32 = 2;\npub const PFRES_MATCH: u32 = 0;\npub const PFRES_BADOFF: u32 = 1;\npub const PFRES_FRAG: u32 = 2;\npub const PFRES_SHORT: u32 = 3;\npub const PFRES_NORM: u32 = 4;\npub const PFRES_MEMORY: u32 = 5;\npub const PFRES_TS: u32 = 6;\npub const PFRES_CONGEST: u32 = 7;\npub const PFRES_IPOPTIONS: u32 = 8;\npub const PFRES_PROTCKSUM: u32 = 9;\npub const PFRES_BADSTATE: u32 = 10;\npub const PFRES_STATEINS: u32 = 11;\npub const PFRES_MAXSTATES: u32 = 12;\npub const PFRES_SRCLIMIT: u32 = 13;\npub const PFRES_SYNPROXY: u32 = 14;\npub const PFRES_DUMMYNET: u32 = 15;\npub const PFRES_MAX: u32 = 16;\npub const LCNT_STATES: u32 = 0;\npub const LCNT_SRCSTATES: u32 = 1;\npub const LCNT_SRCNODES: u32 = 2;\npub const LCNT_SRCCONN: u32 = 3;\npub const LCNT_SRCCONNRATE: u32 = 4;\npub const LCNT_OVERLOAD_TABLE: u32 = 5;\npub const LCNT_OVERLOAD_FLUSH: u32 = 6;\npub const LCNT_MAX: u32 = 7;\npub const PFUDPS_NO_TRAFFIC: u32 = 0;\npub const PFUDPS_SINGLE: u32 = 1;\npub const PFUDPS_MULTIPLE: u32 = 2;\npub const PFUDPS_NSTATES: u32 = 3;\npub const PFGRE1S_NO_TRAFFIC: u32 = 0;\npub const PFGRE1S_INITIATING: u32 = 1;\npub const PFGRE1S_ESTABLISHED: u32 = 2;\npub const PFGRE1S_NSTATES: u32 = 3;\npub const PFESPS_NO_TRAFFIC: u32 = 0;\npub const PFESPS_INITIATING: u32 = 1;\npub const PFESPS_ESTABLISHED: u32 = 2;\npub const PFESPS_NSTATES: u32 = 3;\npub const PFOTHERS_NO_TRAFFIC: u32 = 0;\npub const PFOTHERS_SINGLE: u32 = 1;\npub const PFOTHERS_MULTIPLE: u32 = 2;\npub const PFOTHERS_NSTATES: u32 = 3;\npub const FCNT_STATE_SEARCH: u32 = 0;\npub const FCNT_STATE_INSERT: u32 = 1;\npub const FCNT_STATE_REMOVALS: u32 = 2;\npub const FCNT_MAX: u32 = 3;\npub const SCNT_SRC_NODE_SEARCH: u32 = 0;\npub const SCNT_SRC_NODE_INSERT: u32 = 1;\npub const SCNT_SRC_NODE_REMOVALS: u32 = 2;\npub const SCNT_MAX: u32 = 3;\npub const PF_ALTQ_BW_ABSOLUTE: u32 = 1;\npub const PF_ALTQ_BW_PERCENT: u32 = 2;\npub const PF_ALTQF_TBR: u32 = 1;\npub const PF_ALTQ_QRF_WEIGHT: u32 = 1;\npub const PFFRAG_FRENT_HIWAT: u32 = 5000;\npub const PFFRAG_FRAG_HIWAT: u32 = 1000;\npub const PFFRAG_FRCENT_HIWAT: u32 = 50000;\npub const PFFRAG_FRCACHE_HIWAT: u32 = 10000;\npub const PFR_KTABLE_HIWAT: u32 = 1000;\npub const PFR_KENTRY_HIWAT: u32 = 200000;\npub const PFR_KENTRY_HIWAT_SMALL: u32 = 100000;\npub const PFTOK_PROCNAME_LEN: u32 = 64;\npub const PFR_FLAG_ATOMIC: u32 = 1;\npub const PFR_FLAG_DUMMY: u32 = 2;\npub const PFR_FLAG_FEEDBACK: u32 = 4;\npub const PFR_FLAG_CLSTATS: u32 = 8;\npub const PFR_FLAG_ADDRSTOO: u32 = 16;\npub const PFR_FLAG_REPLACE: u32 = 32;\npub const PFR_FLAG_ALLRSETS: u32 = 64;\npub const PFR_FLAG_ALLMASK: u32 = 127;\npub type __int8_t = ::std::os::raw::c_schar;\npub type __uint8_t = ::std::os::raw::c_uchar;\npub type __int16_t = ::std::os::raw::c_short;\npub type __uint16_t = ::std::os::raw::c_ushort;\npub type __int32_t = ::std::os::raw::c_int;\npub type __uint32_t = ::std::os::raw::c_uint;\npub type __int64_t = ::std::os::raw::c_longlong;\npub type __uint64_t = ::std::os::raw::c_ulonglong;\npub type __darwin_intptr_t = ::std::os::raw::c_long;\npub type __darwin_natural_t = ::std::os::raw::c_uint;\npub type __darwin_ct_rune_t = ::std::os::raw::c_int;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union __mbstate_t {\n    pub __mbstate8: [::std::os::raw::c_char; 128usize],\n    pub _mbstateL: ::std::os::raw::c_longlong,\n}\n#[test]\nfn bindgen_test_layout___mbstate_t() {\n    const UNINIT: ::std::mem::MaybeUninit<__mbstate_t> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__mbstate_t>(),\n        128usize,\n        concat!(\"Size of: \", stringify!(__mbstate_t))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__mbstate_t>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__mbstate_t))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__mbstate8) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__mbstate_t),\n            \"::\",\n            stringify!(__mbstate8)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._mbstateL) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__mbstate_t),\n            \"::\",\n            stringify!(_mbstateL)\n        )\n    );\n}\npub type __darwin_mbstate_t = __mbstate_t;\npub type __darwin_ptrdiff_t = ::std::os::raw::c_long;\npub type __darwin_size_t = ::std::os::raw::c_ulong;\npub type __darwin_va_list = __builtin_va_list;\npub type __darwin_wchar_t = ::std::os::raw::c_int;\npub type __darwin_rune_t = __darwin_wchar_t;\npub type __darwin_wint_t = ::std::os::raw::c_int;\npub type __darwin_clock_t = ::std::os::raw::c_ulong;\npub type __darwin_socklen_t = __uint32_t;\npub type __darwin_ssize_t = ::std::os::raw::c_long;\npub type __darwin_time_t = ::std::os::raw::c_long;\npub type __darwin_blkcnt_t = __int64_t;\npub type __darwin_blksize_t = __int32_t;\npub type __darwin_dev_t = __int32_t;\npub type __darwin_fsblkcnt_t = ::std::os::raw::c_uint;\npub type __darwin_fsfilcnt_t = ::std::os::raw::c_uint;\npub type __darwin_gid_t = __uint32_t;\npub type __darwin_id_t = __uint32_t;\npub type __darwin_ino64_t = __uint64_t;\npub type __darwin_ino_t = __darwin_ino64_t;\npub type __darwin_mach_port_name_t = __darwin_natural_t;\npub type __darwin_mach_port_t = __darwin_mach_port_name_t;\npub type __darwin_mode_t = __uint16_t;\npub type __darwin_off_t = __int64_t;\npub type __darwin_pid_t = __int32_t;\npub type __darwin_sigset_t = __uint32_t;\npub type __darwin_suseconds_t = __int32_t;\npub type __darwin_uid_t = __uint32_t;\npub type __darwin_useconds_t = __uint32_t;\npub type __darwin_uuid_t = [::std::os::raw::c_uchar; 16usize];\npub type __darwin_uuid_string_t = [::std::os::raw::c_char; 37usize];\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_pthread_handler_rec {\n    pub __routine: ::std::option::Option<unsafe extern \"C\" fn(arg1: *mut ::std::os::raw::c_void)>,\n    pub __arg: *mut ::std::os::raw::c_void,\n    pub __next: *mut __darwin_pthread_handler_rec,\n}\n#[test]\nfn bindgen_test_layout___darwin_pthread_handler_rec() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_pthread_handler_rec> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_pthread_handler_rec>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(__darwin_pthread_handler_rec))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_pthread_handler_rec>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__darwin_pthread_handler_rec))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__routine) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_pthread_handler_rec),\n            \"::\",\n            stringify!(__routine)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__arg) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_pthread_handler_rec),\n            \"::\",\n            stringify!(__arg)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__next) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_pthread_handler_rec),\n            \"::\",\n            stringify!(__next)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct _opaque_pthread_attr_t {\n    pub __sig: ::std::os::raw::c_long,\n    pub __opaque: [::std::os::raw::c_char; 56usize],\n}\n#[test]\nfn bindgen_test_layout__opaque_pthread_attr_t() {\n    const UNINIT: ::std::mem::MaybeUninit<_opaque_pthread_attr_t> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<_opaque_pthread_attr_t>(),\n        64usize,\n        concat!(\"Size of: \", stringify!(_opaque_pthread_attr_t))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<_opaque_pthread_attr_t>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(_opaque_pthread_attr_t))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__sig) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_opaque_pthread_attr_t),\n            \"::\",\n            stringify!(__sig)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__opaque) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_opaque_pthread_attr_t),\n            \"::\",\n            stringify!(__opaque)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct _opaque_pthread_cond_t {\n    pub __sig: ::std::os::raw::c_long,\n    pub __opaque: [::std::os::raw::c_char; 40usize],\n}\n#[test]\nfn bindgen_test_layout__opaque_pthread_cond_t() {\n    const UNINIT: ::std::mem::MaybeUninit<_opaque_pthread_cond_t> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<_opaque_pthread_cond_t>(),\n        48usize,\n        concat!(\"Size of: \", stringify!(_opaque_pthread_cond_t))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<_opaque_pthread_cond_t>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(_opaque_pthread_cond_t))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__sig) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_opaque_pthread_cond_t),\n            \"::\",\n            stringify!(__sig)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__opaque) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_opaque_pthread_cond_t),\n            \"::\",\n            stringify!(__opaque)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct _opaque_pthread_condattr_t {\n    pub __sig: ::std::os::raw::c_long,\n    pub __opaque: [::std::os::raw::c_char; 8usize],\n}\n#[test]\nfn bindgen_test_layout__opaque_pthread_condattr_t() {\n    const UNINIT: ::std::mem::MaybeUninit<_opaque_pthread_condattr_t> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<_opaque_pthread_condattr_t>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(_opaque_pthread_condattr_t))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<_opaque_pthread_condattr_t>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(_opaque_pthread_condattr_t))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__sig) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_opaque_pthread_condattr_t),\n            \"::\",\n            stringify!(__sig)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__opaque) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_opaque_pthread_condattr_t),\n            \"::\",\n            stringify!(__opaque)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct _opaque_pthread_mutex_t {\n    pub __sig: ::std::os::raw::c_long,\n    pub __opaque: [::std::os::raw::c_char; 56usize],\n}\n#[test]\nfn bindgen_test_layout__opaque_pthread_mutex_t() {\n    const UNINIT: ::std::mem::MaybeUninit<_opaque_pthread_mutex_t> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<_opaque_pthread_mutex_t>(),\n        64usize,\n        concat!(\"Size of: \", stringify!(_opaque_pthread_mutex_t))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<_opaque_pthread_mutex_t>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(_opaque_pthread_mutex_t))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__sig) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_opaque_pthread_mutex_t),\n            \"::\",\n            stringify!(__sig)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__opaque) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_opaque_pthread_mutex_t),\n            \"::\",\n            stringify!(__opaque)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct _opaque_pthread_mutexattr_t {\n    pub __sig: ::std::os::raw::c_long,\n    pub __opaque: [::std::os::raw::c_char; 8usize],\n}\n#[test]\nfn bindgen_test_layout__opaque_pthread_mutexattr_t() {\n    const UNINIT: ::std::mem::MaybeUninit<_opaque_pthread_mutexattr_t> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<_opaque_pthread_mutexattr_t>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(_opaque_pthread_mutexattr_t))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<_opaque_pthread_mutexattr_t>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(_opaque_pthread_mutexattr_t))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__sig) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_opaque_pthread_mutexattr_t),\n            \"::\",\n            stringify!(__sig)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__opaque) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_opaque_pthread_mutexattr_t),\n            \"::\",\n            stringify!(__opaque)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct _opaque_pthread_once_t {\n    pub __sig: ::std::os::raw::c_long,\n    pub __opaque: [::std::os::raw::c_char; 8usize],\n}\n#[test]\nfn bindgen_test_layout__opaque_pthread_once_t() {\n    const UNINIT: ::std::mem::MaybeUninit<_opaque_pthread_once_t> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<_opaque_pthread_once_t>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(_opaque_pthread_once_t))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<_opaque_pthread_once_t>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(_opaque_pthread_once_t))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__sig) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_opaque_pthread_once_t),\n            \"::\",\n            stringify!(__sig)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__opaque) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_opaque_pthread_once_t),\n            \"::\",\n            stringify!(__opaque)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct _opaque_pthread_rwlock_t {\n    pub __sig: ::std::os::raw::c_long,\n    pub __opaque: [::std::os::raw::c_char; 192usize],\n}\n#[test]\nfn bindgen_test_layout__opaque_pthread_rwlock_t() {\n    const UNINIT: ::std::mem::MaybeUninit<_opaque_pthread_rwlock_t> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<_opaque_pthread_rwlock_t>(),\n        200usize,\n        concat!(\"Size of: \", stringify!(_opaque_pthread_rwlock_t))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<_opaque_pthread_rwlock_t>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(_opaque_pthread_rwlock_t))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__sig) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_opaque_pthread_rwlock_t),\n            \"::\",\n            stringify!(__sig)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__opaque) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_opaque_pthread_rwlock_t),\n            \"::\",\n            stringify!(__opaque)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct _opaque_pthread_rwlockattr_t {\n    pub __sig: ::std::os::raw::c_long,\n    pub __opaque: [::std::os::raw::c_char; 16usize],\n}\n#[test]\nfn bindgen_test_layout__opaque_pthread_rwlockattr_t() {\n    const UNINIT: ::std::mem::MaybeUninit<_opaque_pthread_rwlockattr_t> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<_opaque_pthread_rwlockattr_t>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(_opaque_pthread_rwlockattr_t))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<_opaque_pthread_rwlockattr_t>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(_opaque_pthread_rwlockattr_t))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__sig) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_opaque_pthread_rwlockattr_t),\n            \"::\",\n            stringify!(__sig)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__opaque) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_opaque_pthread_rwlockattr_t),\n            \"::\",\n            stringify!(__opaque)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct _opaque_pthread_t {\n    pub __sig: ::std::os::raw::c_long,\n    pub __cleanup_stack: *mut __darwin_pthread_handler_rec,\n    pub __opaque: [::std::os::raw::c_char; 8176usize],\n}\n#[test]\nfn bindgen_test_layout__opaque_pthread_t() {\n    const UNINIT: ::std::mem::MaybeUninit<_opaque_pthread_t> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<_opaque_pthread_t>(),\n        8192usize,\n        concat!(\"Size of: \", stringify!(_opaque_pthread_t))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<_opaque_pthread_t>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(_opaque_pthread_t))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__sig) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_opaque_pthread_t),\n            \"::\",\n            stringify!(__sig)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__cleanup_stack) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_opaque_pthread_t),\n            \"::\",\n            stringify!(__cleanup_stack)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__opaque) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_opaque_pthread_t),\n            \"::\",\n            stringify!(__opaque)\n        )\n    );\n}\npub type __darwin_pthread_attr_t = _opaque_pthread_attr_t;\npub type __darwin_pthread_cond_t = _opaque_pthread_cond_t;\npub type __darwin_pthread_condattr_t = _opaque_pthread_condattr_t;\npub type __darwin_pthread_key_t = ::std::os::raw::c_ulong;\npub type __darwin_pthread_mutex_t = _opaque_pthread_mutex_t;\npub type __darwin_pthread_mutexattr_t = _opaque_pthread_mutexattr_t;\npub type __darwin_pthread_once_t = _opaque_pthread_once_t;\npub type __darwin_pthread_rwlock_t = _opaque_pthread_rwlock_t;\npub type __darwin_pthread_rwlockattr_t = _opaque_pthread_rwlockattr_t;\npub type __darwin_pthread_t = *mut _opaque_pthread_t;\npub type u_int8_t = ::std::os::raw::c_uchar;\npub type u_int16_t = ::std::os::raw::c_ushort;\npub type u_int32_t = ::std::os::raw::c_uint;\npub type u_int64_t = ::std::os::raw::c_ulonglong;\npub type register_t = i64;\npub type user_addr_t = u_int64_t;\npub type user_size_t = u_int64_t;\npub type user_ssize_t = i64;\npub type user_long_t = i64;\npub type user_ulong_t = u_int64_t;\npub type user_time_t = i64;\npub type user_off_t = i64;\npub type syscall_arg_t = u_int64_t;\npub type u_char = ::std::os::raw::c_uchar;\npub type u_short = ::std::os::raw::c_ushort;\npub type u_int = ::std::os::raw::c_uint;\npub type u_long = ::std::os::raw::c_ulong;\npub type ushort = ::std::os::raw::c_ushort;\npub type uint = ::std::os::raw::c_uint;\npub type u_quad_t = u_int64_t;\npub type quad_t = i64;\npub type qaddr_t = *mut quad_t;\npub type caddr_t = *mut ::std::os::raw::c_char;\npub type daddr_t = i32;\npub type dev_t = __darwin_dev_t;\npub type fixpt_t = u_int32_t;\npub type blkcnt_t = __darwin_blkcnt_t;\npub type blksize_t = __darwin_blksize_t;\npub type gid_t = __darwin_gid_t;\npub type in_addr_t = __uint32_t;\npub type in_port_t = __uint16_t;\npub type ino_t = __darwin_ino_t;\npub type ino64_t = __darwin_ino64_t;\npub type key_t = __int32_t;\npub type mode_t = __darwin_mode_t;\npub type nlink_t = __uint16_t;\npub type id_t = __darwin_id_t;\npub type pid_t = __darwin_pid_t;\npub type off_t = __darwin_off_t;\npub type segsz_t = i32;\npub type swblk_t = i32;\npub type uid_t = __darwin_uid_t;\npub type clock_t = __darwin_clock_t;\npub type time_t = __darwin_time_t;\npub type useconds_t = __darwin_useconds_t;\npub type suseconds_t = __darwin_suseconds_t;\npub type rsize_t = __darwin_size_t;\npub type errno_t = ::std::os::raw::c_int;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct fd_set {\n    pub fds_bits: [__int32_t; 32usize],\n}\n#[test]\nfn bindgen_test_layout_fd_set() {\n    const UNINIT: ::std::mem::MaybeUninit<fd_set> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<fd_set>(),\n        128usize,\n        concat!(\"Size of: \", stringify!(fd_set))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<fd_set>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(fd_set))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fds_bits) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(fd_set), \"::\", stringify!(fds_bits))\n    );\n}\nunsafe extern \"C\" {\n    pub fn __darwin_check_fd_set_overflow(\n        arg1: ::std::os::raw::c_int,\n        arg2: *const ::std::os::raw::c_void,\n        arg3: ::std::os::raw::c_int,\n    ) -> ::std::os::raw::c_int;\n}\npub type fd_mask = __int32_t;\npub type pthread_attr_t = __darwin_pthread_attr_t;\npub type pthread_cond_t = __darwin_pthread_cond_t;\npub type pthread_condattr_t = __darwin_pthread_condattr_t;\npub type pthread_mutex_t = __darwin_pthread_mutex_t;\npub type pthread_mutexattr_t = __darwin_pthread_mutexattr_t;\npub type pthread_once_t = __darwin_pthread_once_t;\npub type pthread_rwlock_t = __darwin_pthread_rwlock_t;\npub type pthread_rwlockattr_t = __darwin_pthread_rwlockattr_t;\npub type pthread_t = __darwin_pthread_t;\npub type pthread_key_t = __darwin_pthread_key_t;\npub type fsblkcnt_t = __darwin_fsblkcnt_t;\npub type fsfilcnt_t = __darwin_fsfilcnt_t;\npub type sig_atomic_t = ::std::os::raw::c_int;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_i386_thread_state {\n    pub __eax: ::std::os::raw::c_uint,\n    pub __ebx: ::std::os::raw::c_uint,\n    pub __ecx: ::std::os::raw::c_uint,\n    pub __edx: ::std::os::raw::c_uint,\n    pub __edi: ::std::os::raw::c_uint,\n    pub __esi: ::std::os::raw::c_uint,\n    pub __ebp: ::std::os::raw::c_uint,\n    pub __esp: ::std::os::raw::c_uint,\n    pub __ss: ::std::os::raw::c_uint,\n    pub __eflags: ::std::os::raw::c_uint,\n    pub __eip: ::std::os::raw::c_uint,\n    pub __cs: ::std::os::raw::c_uint,\n    pub __ds: ::std::os::raw::c_uint,\n    pub __es: ::std::os::raw::c_uint,\n    pub __fs: ::std::os::raw::c_uint,\n    pub __gs: ::std::os::raw::c_uint,\n}\n#[test]\nfn bindgen_test_layout___darwin_i386_thread_state() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_i386_thread_state> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_i386_thread_state>(),\n        64usize,\n        concat!(\"Size of: \", stringify!(__darwin_i386_thread_state))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_i386_thread_state>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(__darwin_i386_thread_state))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__eax) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_thread_state),\n            \"::\",\n            stringify!(__eax)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ebx) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_thread_state),\n            \"::\",\n            stringify!(__ebx)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ecx) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_thread_state),\n            \"::\",\n            stringify!(__ecx)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__edx) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_thread_state),\n            \"::\",\n            stringify!(__edx)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__edi) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_thread_state),\n            \"::\",\n            stringify!(__edi)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__esi) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_thread_state),\n            \"::\",\n            stringify!(__esi)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ebp) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_thread_state),\n            \"::\",\n            stringify!(__ebp)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__esp) as usize - ptr as usize },\n        28usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_thread_state),\n            \"::\",\n            stringify!(__esp)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ss) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_thread_state),\n            \"::\",\n            stringify!(__ss)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__eflags) as usize - ptr as usize },\n        36usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_thread_state),\n            \"::\",\n            stringify!(__eflags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__eip) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_thread_state),\n            \"::\",\n            stringify!(__eip)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__cs) as usize - ptr as usize },\n        44usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_thread_state),\n            \"::\",\n            stringify!(__cs)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ds) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_thread_state),\n            \"::\",\n            stringify!(__ds)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__es) as usize - ptr as usize },\n        52usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_thread_state),\n            \"::\",\n            stringify!(__es)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fs) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_thread_state),\n            \"::\",\n            stringify!(__fs)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__gs) as usize - ptr as usize },\n        60usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_thread_state),\n            \"::\",\n            stringify!(__gs)\n        )\n    );\n}\n#[repr(C)]\n#[repr(align(2))]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_fp_control {\n    pub _bitfield_align_1: [u8; 0],\n    pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>,\n}\n#[test]\nfn bindgen_test_layout___darwin_fp_control() {\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_fp_control>(),\n        2usize,\n        concat!(\"Size of: \", stringify!(__darwin_fp_control))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_fp_control>(),\n        2usize,\n        concat!(\"Alignment of \", stringify!(__darwin_fp_control))\n    );\n}\nimpl __darwin_fp_control {\n    #[inline]\n    pub fn __invalid(&self) -> ::std::os::raw::c_ushort {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set___invalid(&mut self, val: ::std::os::raw::c_ushort) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(0usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn __denorm(&self) -> ::std::os::raw::c_ushort {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set___denorm(&mut self, val: ::std::os::raw::c_ushort) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(1usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn __zdiv(&self) -> ::std::os::raw::c_ushort {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set___zdiv(&mut self, val: ::std::os::raw::c_ushort) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(2usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn __ovrfl(&self) -> ::std::os::raw::c_ushort {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set___ovrfl(&mut self, val: ::std::os::raw::c_ushort) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(3usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn __undfl(&self) -> ::std::os::raw::c_ushort {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set___undfl(&mut self, val: ::std::os::raw::c_ushort) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(4usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn __precis(&self) -> ::std::os::raw::c_ushort {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set___precis(&mut self, val: ::std::os::raw::c_ushort) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(5usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn __pc(&self) -> ::std::os::raw::c_ushort {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 2u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set___pc(&mut self, val: ::std::os::raw::c_ushort) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(8usize, 2u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn __rc(&self) -> ::std::os::raw::c_ushort {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(10usize, 2u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set___rc(&mut self, val: ::std::os::raw::c_ushort) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(10usize, 2u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn new_bitfield_1(\n        __invalid: ::std::os::raw::c_ushort,\n        __denorm: ::std::os::raw::c_ushort,\n        __zdiv: ::std::os::raw::c_ushort,\n        __ovrfl: ::std::os::raw::c_ushort,\n        __undfl: ::std::os::raw::c_ushort,\n        __precis: ::std::os::raw::c_ushort,\n        __pc: ::std::os::raw::c_ushort,\n        __rc: ::std::os::raw::c_ushort,\n    ) -> __BindgenBitfieldUnit<[u8; 2usize]> {\n        let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = Default::default();\n        __bindgen_bitfield_unit.set(0usize, 1u8, {\n            let __invalid: u16 = unsafe { ::std::mem::transmute(__invalid) };\n            __invalid as u64\n        });\n        __bindgen_bitfield_unit.set(1usize, 1u8, {\n            let __denorm: u16 = unsafe { ::std::mem::transmute(__denorm) };\n            __denorm as u64\n        });\n        __bindgen_bitfield_unit.set(2usize, 1u8, {\n            let __zdiv: u16 = unsafe { ::std::mem::transmute(__zdiv) };\n            __zdiv as u64\n        });\n        __bindgen_bitfield_unit.set(3usize, 1u8, {\n            let __ovrfl: u16 = unsafe { ::std::mem::transmute(__ovrfl) };\n            __ovrfl as u64\n        });\n        __bindgen_bitfield_unit.set(4usize, 1u8, {\n            let __undfl: u16 = unsafe { ::std::mem::transmute(__undfl) };\n            __undfl as u64\n        });\n        __bindgen_bitfield_unit.set(5usize, 1u8, {\n            let __precis: u16 = unsafe { ::std::mem::transmute(__precis) };\n            __precis as u64\n        });\n        __bindgen_bitfield_unit.set(8usize, 2u8, {\n            let __pc: u16 = unsafe { ::std::mem::transmute(__pc) };\n            __pc as u64\n        });\n        __bindgen_bitfield_unit.set(10usize, 2u8, {\n            let __rc: u16 = unsafe { ::std::mem::transmute(__rc) };\n            __rc as u64\n        });\n        __bindgen_bitfield_unit\n    }\n}\npub type __darwin_fp_control_t = __darwin_fp_control;\n#[repr(C)]\n#[repr(align(2))]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_fp_status {\n    pub _bitfield_align_1: [u8; 0],\n    pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>,\n}\n#[test]\nfn bindgen_test_layout___darwin_fp_status() {\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_fp_status>(),\n        2usize,\n        concat!(\"Size of: \", stringify!(__darwin_fp_status))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_fp_status>(),\n        2usize,\n        concat!(\"Alignment of \", stringify!(__darwin_fp_status))\n    );\n}\nimpl __darwin_fp_status {\n    #[inline]\n    pub fn __invalid(&self) -> ::std::os::raw::c_ushort {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set___invalid(&mut self, val: ::std::os::raw::c_ushort) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(0usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn __denorm(&self) -> ::std::os::raw::c_ushort {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set___denorm(&mut self, val: ::std::os::raw::c_ushort) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(1usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn __zdiv(&self) -> ::std::os::raw::c_ushort {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set___zdiv(&mut self, val: ::std::os::raw::c_ushort) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(2usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn __ovrfl(&self) -> ::std::os::raw::c_ushort {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set___ovrfl(&mut self, val: ::std::os::raw::c_ushort) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(3usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn __undfl(&self) -> ::std::os::raw::c_ushort {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set___undfl(&mut self, val: ::std::os::raw::c_ushort) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(4usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn __precis(&self) -> ::std::os::raw::c_ushort {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set___precis(&mut self, val: ::std::os::raw::c_ushort) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(5usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn __stkflt(&self) -> ::std::os::raw::c_ushort {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(6usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set___stkflt(&mut self, val: ::std::os::raw::c_ushort) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(6usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn __errsumm(&self) -> ::std::os::raw::c_ushort {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set___errsumm(&mut self, val: ::std::os::raw::c_ushort) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(7usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn __c0(&self) -> ::std::os::raw::c_ushort {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set___c0(&mut self, val: ::std::os::raw::c_ushort) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(8usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn __c1(&self) -> ::std::os::raw::c_ushort {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(9usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set___c1(&mut self, val: ::std::os::raw::c_ushort) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(9usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn __c2(&self) -> ::std::os::raw::c_ushort {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(10usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set___c2(&mut self, val: ::std::os::raw::c_ushort) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(10usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn __tos(&self) -> ::std::os::raw::c_ushort {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(11usize, 3u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set___tos(&mut self, val: ::std::os::raw::c_ushort) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(11usize, 3u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn __c3(&self) -> ::std::os::raw::c_ushort {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(14usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set___c3(&mut self, val: ::std::os::raw::c_ushort) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(14usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn __busy(&self) -> ::std::os::raw::c_ushort {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(15usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set___busy(&mut self, val: ::std::os::raw::c_ushort) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(15usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn new_bitfield_1(\n        __invalid: ::std::os::raw::c_ushort,\n        __denorm: ::std::os::raw::c_ushort,\n        __zdiv: ::std::os::raw::c_ushort,\n        __ovrfl: ::std::os::raw::c_ushort,\n        __undfl: ::std::os::raw::c_ushort,\n        __precis: ::std::os::raw::c_ushort,\n        __stkflt: ::std::os::raw::c_ushort,\n        __errsumm: ::std::os::raw::c_ushort,\n        __c0: ::std::os::raw::c_ushort,\n        __c1: ::std::os::raw::c_ushort,\n        __c2: ::std::os::raw::c_ushort,\n        __tos: ::std::os::raw::c_ushort,\n        __c3: ::std::os::raw::c_ushort,\n        __busy: ::std::os::raw::c_ushort,\n    ) -> __BindgenBitfieldUnit<[u8; 2usize]> {\n        let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = Default::default();\n        __bindgen_bitfield_unit.set(0usize, 1u8, {\n            let __invalid: u16 = unsafe { ::std::mem::transmute(__invalid) };\n            __invalid as u64\n        });\n        __bindgen_bitfield_unit.set(1usize, 1u8, {\n            let __denorm: u16 = unsafe { ::std::mem::transmute(__denorm) };\n            __denorm as u64\n        });\n        __bindgen_bitfield_unit.set(2usize, 1u8, {\n            let __zdiv: u16 = unsafe { ::std::mem::transmute(__zdiv) };\n            __zdiv as u64\n        });\n        __bindgen_bitfield_unit.set(3usize, 1u8, {\n            let __ovrfl: u16 = unsafe { ::std::mem::transmute(__ovrfl) };\n            __ovrfl as u64\n        });\n        __bindgen_bitfield_unit.set(4usize, 1u8, {\n            let __undfl: u16 = unsafe { ::std::mem::transmute(__undfl) };\n            __undfl as u64\n        });\n        __bindgen_bitfield_unit.set(5usize, 1u8, {\n            let __precis: u16 = unsafe { ::std::mem::transmute(__precis) };\n            __precis as u64\n        });\n        __bindgen_bitfield_unit.set(6usize, 1u8, {\n            let __stkflt: u16 = unsafe { ::std::mem::transmute(__stkflt) };\n            __stkflt as u64\n        });\n        __bindgen_bitfield_unit.set(7usize, 1u8, {\n            let __errsumm: u16 = unsafe { ::std::mem::transmute(__errsumm) };\n            __errsumm as u64\n        });\n        __bindgen_bitfield_unit.set(8usize, 1u8, {\n            let __c0: u16 = unsafe { ::std::mem::transmute(__c0) };\n            __c0 as u64\n        });\n        __bindgen_bitfield_unit.set(9usize, 1u8, {\n            let __c1: u16 = unsafe { ::std::mem::transmute(__c1) };\n            __c1 as u64\n        });\n        __bindgen_bitfield_unit.set(10usize, 1u8, {\n            let __c2: u16 = unsafe { ::std::mem::transmute(__c2) };\n            __c2 as u64\n        });\n        __bindgen_bitfield_unit.set(11usize, 3u8, {\n            let __tos: u16 = unsafe { ::std::mem::transmute(__tos) };\n            __tos as u64\n        });\n        __bindgen_bitfield_unit.set(14usize, 1u8, {\n            let __c3: u16 = unsafe { ::std::mem::transmute(__c3) };\n            __c3 as u64\n        });\n        __bindgen_bitfield_unit.set(15usize, 1u8, {\n            let __busy: u16 = unsafe { ::std::mem::transmute(__busy) };\n            __busy as u64\n        });\n        __bindgen_bitfield_unit\n    }\n}\npub type __darwin_fp_status_t = __darwin_fp_status;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_mmst_reg {\n    pub __mmst_reg: [::std::os::raw::c_char; 10usize],\n    pub __mmst_rsrv: [::std::os::raw::c_char; 6usize],\n}\n#[test]\nfn bindgen_test_layout___darwin_mmst_reg() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_mmst_reg> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_mmst_reg>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(__darwin_mmst_reg))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_mmst_reg>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(__darwin_mmst_reg))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__mmst_reg) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mmst_reg),\n            \"::\",\n            stringify!(__mmst_reg)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__mmst_rsrv) as usize - ptr as usize },\n        10usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mmst_reg),\n            \"::\",\n            stringify!(__mmst_rsrv)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_xmm_reg {\n    pub __xmm_reg: [::std::os::raw::c_char; 16usize],\n}\n#[test]\nfn bindgen_test_layout___darwin_xmm_reg() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_xmm_reg> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_xmm_reg>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(__darwin_xmm_reg))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_xmm_reg>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(__darwin_xmm_reg))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__xmm_reg) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_xmm_reg),\n            \"::\",\n            stringify!(__xmm_reg)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_ymm_reg {\n    pub __ymm_reg: [::std::os::raw::c_char; 32usize],\n}\n#[test]\nfn bindgen_test_layout___darwin_ymm_reg() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_ymm_reg> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_ymm_reg>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(__darwin_ymm_reg))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_ymm_reg>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(__darwin_ymm_reg))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ymm_reg) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_ymm_reg),\n            \"::\",\n            stringify!(__ymm_reg)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_zmm_reg {\n    pub __zmm_reg: [::std::os::raw::c_char; 64usize],\n}\n#[test]\nfn bindgen_test_layout___darwin_zmm_reg() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_zmm_reg> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_zmm_reg>(),\n        64usize,\n        concat!(\"Size of: \", stringify!(__darwin_zmm_reg))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_zmm_reg>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(__darwin_zmm_reg))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__zmm_reg) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_zmm_reg),\n            \"::\",\n            stringify!(__zmm_reg)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_opmask_reg {\n    pub __opmask_reg: [::std::os::raw::c_char; 8usize],\n}\n#[test]\nfn bindgen_test_layout___darwin_opmask_reg() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_opmask_reg> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_opmask_reg>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(__darwin_opmask_reg))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_opmask_reg>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(__darwin_opmask_reg))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__opmask_reg) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_opmask_reg),\n            \"::\",\n            stringify!(__opmask_reg)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_i386_float_state {\n    pub __fpu_reserved: [::std::os::raw::c_int; 2usize],\n    pub __fpu_fcw: __darwin_fp_control,\n    pub __fpu_fsw: __darwin_fp_status,\n    pub __fpu_ftw: __uint8_t,\n    pub __fpu_rsrv1: __uint8_t,\n    pub __fpu_fop: __uint16_t,\n    pub __fpu_ip: __uint32_t,\n    pub __fpu_cs: __uint16_t,\n    pub __fpu_rsrv2: __uint16_t,\n    pub __fpu_dp: __uint32_t,\n    pub __fpu_ds: __uint16_t,\n    pub __fpu_rsrv3: __uint16_t,\n    pub __fpu_mxcsr: __uint32_t,\n    pub __fpu_mxcsrmask: __uint32_t,\n    pub __fpu_stmm0: __darwin_mmst_reg,\n    pub __fpu_stmm1: __darwin_mmst_reg,\n    pub __fpu_stmm2: __darwin_mmst_reg,\n    pub __fpu_stmm3: __darwin_mmst_reg,\n    pub __fpu_stmm4: __darwin_mmst_reg,\n    pub __fpu_stmm5: __darwin_mmst_reg,\n    pub __fpu_stmm6: __darwin_mmst_reg,\n    pub __fpu_stmm7: __darwin_mmst_reg,\n    pub __fpu_xmm0: __darwin_xmm_reg,\n    pub __fpu_xmm1: __darwin_xmm_reg,\n    pub __fpu_xmm2: __darwin_xmm_reg,\n    pub __fpu_xmm3: __darwin_xmm_reg,\n    pub __fpu_xmm4: __darwin_xmm_reg,\n    pub __fpu_xmm5: __darwin_xmm_reg,\n    pub __fpu_xmm6: __darwin_xmm_reg,\n    pub __fpu_xmm7: __darwin_xmm_reg,\n    pub __fpu_rsrv4: [::std::os::raw::c_char; 224usize],\n    pub __fpu_reserved1: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout___darwin_i386_float_state() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_i386_float_state> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_i386_float_state>(),\n        524usize,\n        concat!(\"Size of: \", stringify!(__darwin_i386_float_state))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_i386_float_state>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(__darwin_i386_float_state))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_reserved) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_reserved)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_fcw) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_fcw)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_fsw) as usize - ptr as usize },\n        10usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_fsw)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ftw) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_ftw)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_rsrv1) as usize - ptr as usize },\n        13usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_rsrv1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_fop) as usize - ptr as usize },\n        14usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_fop)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ip) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_ip)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_cs) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_cs)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_rsrv2) as usize - ptr as usize },\n        22usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_rsrv2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_dp) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_dp)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ds) as usize - ptr as usize },\n        28usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_ds)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_rsrv3) as usize - ptr as usize },\n        30usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_rsrv3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_mxcsr) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_mxcsr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_mxcsrmask) as usize - ptr as usize },\n        36usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_mxcsrmask)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm0) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_stmm0)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm1) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_stmm1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm2) as usize - ptr as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_stmm2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm3) as usize - ptr as usize },\n        88usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_stmm3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm4) as usize - ptr as usize },\n        104usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_stmm4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm5) as usize - ptr as usize },\n        120usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_stmm5)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm6) as usize - ptr as usize },\n        136usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_stmm6)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm7) as usize - ptr as usize },\n        152usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_stmm7)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm0) as usize - ptr as usize },\n        168usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_xmm0)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm1) as usize - ptr as usize },\n        184usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_xmm1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm2) as usize - ptr as usize },\n        200usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_xmm2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm3) as usize - ptr as usize },\n        216usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_xmm3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm4) as usize - ptr as usize },\n        232usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_xmm4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm5) as usize - ptr as usize },\n        248usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_xmm5)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm6) as usize - ptr as usize },\n        264usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_xmm6)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm7) as usize - ptr as usize },\n        280usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_xmm7)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_rsrv4) as usize - ptr as usize },\n        296usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_rsrv4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_reserved1) as usize - ptr as usize },\n        520usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_float_state),\n            \"::\",\n            stringify!(__fpu_reserved1)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_i386_avx_state {\n    pub __fpu_reserved: [::std::os::raw::c_int; 2usize],\n    pub __fpu_fcw: __darwin_fp_control,\n    pub __fpu_fsw: __darwin_fp_status,\n    pub __fpu_ftw: __uint8_t,\n    pub __fpu_rsrv1: __uint8_t,\n    pub __fpu_fop: __uint16_t,\n    pub __fpu_ip: __uint32_t,\n    pub __fpu_cs: __uint16_t,\n    pub __fpu_rsrv2: __uint16_t,\n    pub __fpu_dp: __uint32_t,\n    pub __fpu_ds: __uint16_t,\n    pub __fpu_rsrv3: __uint16_t,\n    pub __fpu_mxcsr: __uint32_t,\n    pub __fpu_mxcsrmask: __uint32_t,\n    pub __fpu_stmm0: __darwin_mmst_reg,\n    pub __fpu_stmm1: __darwin_mmst_reg,\n    pub __fpu_stmm2: __darwin_mmst_reg,\n    pub __fpu_stmm3: __darwin_mmst_reg,\n    pub __fpu_stmm4: __darwin_mmst_reg,\n    pub __fpu_stmm5: __darwin_mmst_reg,\n    pub __fpu_stmm6: __darwin_mmst_reg,\n    pub __fpu_stmm7: __darwin_mmst_reg,\n    pub __fpu_xmm0: __darwin_xmm_reg,\n    pub __fpu_xmm1: __darwin_xmm_reg,\n    pub __fpu_xmm2: __darwin_xmm_reg,\n    pub __fpu_xmm3: __darwin_xmm_reg,\n    pub __fpu_xmm4: __darwin_xmm_reg,\n    pub __fpu_xmm5: __darwin_xmm_reg,\n    pub __fpu_xmm6: __darwin_xmm_reg,\n    pub __fpu_xmm7: __darwin_xmm_reg,\n    pub __fpu_rsrv4: [::std::os::raw::c_char; 224usize],\n    pub __fpu_reserved1: ::std::os::raw::c_int,\n    pub __avx_reserved1: [::std::os::raw::c_char; 64usize],\n    pub __fpu_ymmh0: __darwin_xmm_reg,\n    pub __fpu_ymmh1: __darwin_xmm_reg,\n    pub __fpu_ymmh2: __darwin_xmm_reg,\n    pub __fpu_ymmh3: __darwin_xmm_reg,\n    pub __fpu_ymmh4: __darwin_xmm_reg,\n    pub __fpu_ymmh5: __darwin_xmm_reg,\n    pub __fpu_ymmh6: __darwin_xmm_reg,\n    pub __fpu_ymmh7: __darwin_xmm_reg,\n}\n#[test]\nfn bindgen_test_layout___darwin_i386_avx_state() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_i386_avx_state> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_i386_avx_state>(),\n        716usize,\n        concat!(\"Size of: \", stringify!(__darwin_i386_avx_state))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_i386_avx_state>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(__darwin_i386_avx_state))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_reserved) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_reserved)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_fcw) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_fcw)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_fsw) as usize - ptr as usize },\n        10usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_fsw)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ftw) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_ftw)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_rsrv1) as usize - ptr as usize },\n        13usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_rsrv1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_fop) as usize - ptr as usize },\n        14usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_fop)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ip) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_ip)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_cs) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_cs)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_rsrv2) as usize - ptr as usize },\n        22usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_rsrv2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_dp) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_dp)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ds) as usize - ptr as usize },\n        28usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_ds)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_rsrv3) as usize - ptr as usize },\n        30usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_rsrv3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_mxcsr) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_mxcsr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_mxcsrmask) as usize - ptr as usize },\n        36usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_mxcsrmask)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm0) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_stmm0)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm1) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_stmm1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm2) as usize - ptr as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_stmm2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm3) as usize - ptr as usize },\n        88usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_stmm3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm4) as usize - ptr as usize },\n        104usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_stmm4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm5) as usize - ptr as usize },\n        120usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_stmm5)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm6) as usize - ptr as usize },\n        136usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_stmm6)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm7) as usize - ptr as usize },\n        152usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_stmm7)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm0) as usize - ptr as usize },\n        168usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_xmm0)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm1) as usize - ptr as usize },\n        184usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_xmm1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm2) as usize - ptr as usize },\n        200usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_xmm2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm3) as usize - ptr as usize },\n        216usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_xmm3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm4) as usize - ptr as usize },\n        232usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_xmm4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm5) as usize - ptr as usize },\n        248usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_xmm5)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm6) as usize - ptr as usize },\n        264usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_xmm6)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm7) as usize - ptr as usize },\n        280usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_xmm7)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_rsrv4) as usize - ptr as usize },\n        296usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_rsrv4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_reserved1) as usize - ptr as usize },\n        520usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_reserved1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__avx_reserved1) as usize - ptr as usize },\n        524usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__avx_reserved1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh0) as usize - ptr as usize },\n        588usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_ymmh0)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh1) as usize - ptr as usize },\n        604usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_ymmh1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh2) as usize - ptr as usize },\n        620usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_ymmh2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh3) as usize - ptr as usize },\n        636usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_ymmh3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh4) as usize - ptr as usize },\n        652usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_ymmh4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh5) as usize - ptr as usize },\n        668usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_ymmh5)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh6) as usize - ptr as usize },\n        684usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_ymmh6)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh7) as usize - ptr as usize },\n        700usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx_state),\n            \"::\",\n            stringify!(__fpu_ymmh7)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_i386_avx512_state {\n    pub __fpu_reserved: [::std::os::raw::c_int; 2usize],\n    pub __fpu_fcw: __darwin_fp_control,\n    pub __fpu_fsw: __darwin_fp_status,\n    pub __fpu_ftw: __uint8_t,\n    pub __fpu_rsrv1: __uint8_t,\n    pub __fpu_fop: __uint16_t,\n    pub __fpu_ip: __uint32_t,\n    pub __fpu_cs: __uint16_t,\n    pub __fpu_rsrv2: __uint16_t,\n    pub __fpu_dp: __uint32_t,\n    pub __fpu_ds: __uint16_t,\n    pub __fpu_rsrv3: __uint16_t,\n    pub __fpu_mxcsr: __uint32_t,\n    pub __fpu_mxcsrmask: __uint32_t,\n    pub __fpu_stmm0: __darwin_mmst_reg,\n    pub __fpu_stmm1: __darwin_mmst_reg,\n    pub __fpu_stmm2: __darwin_mmst_reg,\n    pub __fpu_stmm3: __darwin_mmst_reg,\n    pub __fpu_stmm4: __darwin_mmst_reg,\n    pub __fpu_stmm5: __darwin_mmst_reg,\n    pub __fpu_stmm6: __darwin_mmst_reg,\n    pub __fpu_stmm7: __darwin_mmst_reg,\n    pub __fpu_xmm0: __darwin_xmm_reg,\n    pub __fpu_xmm1: __darwin_xmm_reg,\n    pub __fpu_xmm2: __darwin_xmm_reg,\n    pub __fpu_xmm3: __darwin_xmm_reg,\n    pub __fpu_xmm4: __darwin_xmm_reg,\n    pub __fpu_xmm5: __darwin_xmm_reg,\n    pub __fpu_xmm6: __darwin_xmm_reg,\n    pub __fpu_xmm7: __darwin_xmm_reg,\n    pub __fpu_rsrv4: [::std::os::raw::c_char; 224usize],\n    pub __fpu_reserved1: ::std::os::raw::c_int,\n    pub __avx_reserved1: [::std::os::raw::c_char; 64usize],\n    pub __fpu_ymmh0: __darwin_xmm_reg,\n    pub __fpu_ymmh1: __darwin_xmm_reg,\n    pub __fpu_ymmh2: __darwin_xmm_reg,\n    pub __fpu_ymmh3: __darwin_xmm_reg,\n    pub __fpu_ymmh4: __darwin_xmm_reg,\n    pub __fpu_ymmh5: __darwin_xmm_reg,\n    pub __fpu_ymmh6: __darwin_xmm_reg,\n    pub __fpu_ymmh7: __darwin_xmm_reg,\n    pub __fpu_k0: __darwin_opmask_reg,\n    pub __fpu_k1: __darwin_opmask_reg,\n    pub __fpu_k2: __darwin_opmask_reg,\n    pub __fpu_k3: __darwin_opmask_reg,\n    pub __fpu_k4: __darwin_opmask_reg,\n    pub __fpu_k5: __darwin_opmask_reg,\n    pub __fpu_k6: __darwin_opmask_reg,\n    pub __fpu_k7: __darwin_opmask_reg,\n    pub __fpu_zmmh0: __darwin_ymm_reg,\n    pub __fpu_zmmh1: __darwin_ymm_reg,\n    pub __fpu_zmmh2: __darwin_ymm_reg,\n    pub __fpu_zmmh3: __darwin_ymm_reg,\n    pub __fpu_zmmh4: __darwin_ymm_reg,\n    pub __fpu_zmmh5: __darwin_ymm_reg,\n    pub __fpu_zmmh6: __darwin_ymm_reg,\n    pub __fpu_zmmh7: __darwin_ymm_reg,\n}\n#[test]\nfn bindgen_test_layout___darwin_i386_avx512_state() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_i386_avx512_state> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_i386_avx512_state>(),\n        1036usize,\n        concat!(\"Size of: \", stringify!(__darwin_i386_avx512_state))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_i386_avx512_state>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(__darwin_i386_avx512_state))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_reserved) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_reserved)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_fcw) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_fcw)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_fsw) as usize - ptr as usize },\n        10usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_fsw)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ftw) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_ftw)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_rsrv1) as usize - ptr as usize },\n        13usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_rsrv1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_fop) as usize - ptr as usize },\n        14usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_fop)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ip) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_ip)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_cs) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_cs)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_rsrv2) as usize - ptr as usize },\n        22usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_rsrv2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_dp) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_dp)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ds) as usize - ptr as usize },\n        28usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_ds)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_rsrv3) as usize - ptr as usize },\n        30usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_rsrv3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_mxcsr) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_mxcsr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_mxcsrmask) as usize - ptr as usize },\n        36usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_mxcsrmask)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm0) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_stmm0)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm1) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_stmm1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm2) as usize - ptr as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_stmm2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm3) as usize - ptr as usize },\n        88usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_stmm3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm4) as usize - ptr as usize },\n        104usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_stmm4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm5) as usize - ptr as usize },\n        120usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_stmm5)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm6) as usize - ptr as usize },\n        136usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_stmm6)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm7) as usize - ptr as usize },\n        152usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_stmm7)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm0) as usize - ptr as usize },\n        168usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_xmm0)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm1) as usize - ptr as usize },\n        184usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_xmm1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm2) as usize - ptr as usize },\n        200usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_xmm2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm3) as usize - ptr as usize },\n        216usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_xmm3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm4) as usize - ptr as usize },\n        232usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_xmm4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm5) as usize - ptr as usize },\n        248usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_xmm5)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm6) as usize - ptr as usize },\n        264usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_xmm6)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm7) as usize - ptr as usize },\n        280usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_xmm7)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_rsrv4) as usize - ptr as usize },\n        296usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_rsrv4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_reserved1) as usize - ptr as usize },\n        520usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_reserved1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__avx_reserved1) as usize - ptr as usize },\n        524usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__avx_reserved1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh0) as usize - ptr as usize },\n        588usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_ymmh0)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh1) as usize - ptr as usize },\n        604usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_ymmh1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh2) as usize - ptr as usize },\n        620usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_ymmh2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh3) as usize - ptr as usize },\n        636usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_ymmh3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh4) as usize - ptr as usize },\n        652usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_ymmh4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh5) as usize - ptr as usize },\n        668usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_ymmh5)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh6) as usize - ptr as usize },\n        684usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_ymmh6)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh7) as usize - ptr as usize },\n        700usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_ymmh7)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_k0) as usize - ptr as usize },\n        716usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_k0)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_k1) as usize - ptr as usize },\n        724usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_k1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_k2) as usize - ptr as usize },\n        732usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_k2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_k3) as usize - ptr as usize },\n        740usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_k3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_k4) as usize - ptr as usize },\n        748usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_k4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_k5) as usize - ptr as usize },\n        756usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_k5)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_k6) as usize - ptr as usize },\n        764usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_k6)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_k7) as usize - ptr as usize },\n        772usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_k7)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmmh0) as usize - ptr as usize },\n        780usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_zmmh0)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmmh1) as usize - ptr as usize },\n        812usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_zmmh1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmmh2) as usize - ptr as usize },\n        844usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_zmmh2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmmh3) as usize - ptr as usize },\n        876usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_zmmh3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmmh4) as usize - ptr as usize },\n        908usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_zmmh4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmmh5) as usize - ptr as usize },\n        940usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_zmmh5)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmmh6) as usize - ptr as usize },\n        972usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_zmmh6)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmmh7) as usize - ptr as usize },\n        1004usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_avx512_state),\n            \"::\",\n            stringify!(__fpu_zmmh7)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_i386_exception_state {\n    pub __trapno: __uint16_t,\n    pub __cpu: __uint16_t,\n    pub __err: __uint32_t,\n    pub __faultvaddr: __uint32_t,\n}\n#[test]\nfn bindgen_test_layout___darwin_i386_exception_state() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_i386_exception_state> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_i386_exception_state>(),\n        12usize,\n        concat!(\"Size of: \", stringify!(__darwin_i386_exception_state))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_i386_exception_state>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(__darwin_i386_exception_state))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__trapno) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_exception_state),\n            \"::\",\n            stringify!(__trapno)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__cpu) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_exception_state),\n            \"::\",\n            stringify!(__cpu)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__err) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_exception_state),\n            \"::\",\n            stringify!(__err)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__faultvaddr) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_i386_exception_state),\n            \"::\",\n            stringify!(__faultvaddr)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_x86_debug_state32 {\n    pub __dr0: ::std::os::raw::c_uint,\n    pub __dr1: ::std::os::raw::c_uint,\n    pub __dr2: ::std::os::raw::c_uint,\n    pub __dr3: ::std::os::raw::c_uint,\n    pub __dr4: ::std::os::raw::c_uint,\n    pub __dr5: ::std::os::raw::c_uint,\n    pub __dr6: ::std::os::raw::c_uint,\n    pub __dr7: ::std::os::raw::c_uint,\n}\n#[test]\nfn bindgen_test_layout___darwin_x86_debug_state32() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_x86_debug_state32> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_x86_debug_state32>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(__darwin_x86_debug_state32))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_x86_debug_state32>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(__darwin_x86_debug_state32))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__dr0) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_debug_state32),\n            \"::\",\n            stringify!(__dr0)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__dr1) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_debug_state32),\n            \"::\",\n            stringify!(__dr1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__dr2) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_debug_state32),\n            \"::\",\n            stringify!(__dr2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__dr3) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_debug_state32),\n            \"::\",\n            stringify!(__dr3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__dr4) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_debug_state32),\n            \"::\",\n            stringify!(__dr4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__dr5) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_debug_state32),\n            \"::\",\n            stringify!(__dr5)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__dr6) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_debug_state32),\n            \"::\",\n            stringify!(__dr6)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__dr7) as usize - ptr as usize },\n        28usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_debug_state32),\n            \"::\",\n            stringify!(__dr7)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __x86_instruction_state {\n    pub __insn_stream_valid_bytes: ::std::os::raw::c_int,\n    pub __insn_offset: ::std::os::raw::c_int,\n    pub __out_of_synch: ::std::os::raw::c_int,\n    pub __insn_bytes: [__uint8_t; 2380usize],\n    pub __insn_cacheline: [__uint8_t; 64usize],\n}\n#[test]\nfn bindgen_test_layout___x86_instruction_state() {\n    const UNINIT: ::std::mem::MaybeUninit<__x86_instruction_state> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__x86_instruction_state>(),\n        2456usize,\n        concat!(\"Size of: \", stringify!(__x86_instruction_state))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__x86_instruction_state>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(__x86_instruction_state))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__insn_stream_valid_bytes) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__x86_instruction_state),\n            \"::\",\n            stringify!(__insn_stream_valid_bytes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__insn_offset) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__x86_instruction_state),\n            \"::\",\n            stringify!(__insn_offset)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__out_of_synch) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__x86_instruction_state),\n            \"::\",\n            stringify!(__out_of_synch)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__insn_bytes) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__x86_instruction_state),\n            \"::\",\n            stringify!(__insn_bytes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__insn_cacheline) as usize - ptr as usize },\n        2392usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__x86_instruction_state),\n            \"::\",\n            stringify!(__insn_cacheline)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __last_branch_record {\n    pub __from_ip: __uint64_t,\n    pub __to_ip: __uint64_t,\n    pub _bitfield_align_1: [u16; 0],\n    pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>,\n    pub __bindgen_padding_0: u32,\n}\n#[test]\nfn bindgen_test_layout___last_branch_record() {\n    const UNINIT: ::std::mem::MaybeUninit<__last_branch_record> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__last_branch_record>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(__last_branch_record))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__last_branch_record>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__last_branch_record))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__from_ip) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__last_branch_record),\n            \"::\",\n            stringify!(__from_ip)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__to_ip) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__last_branch_record),\n            \"::\",\n            stringify!(__to_ip)\n        )\n    );\n}\nimpl __last_branch_record {\n    #[inline]\n    pub fn __mispredict(&self) -> __uint32_t {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) }\n    }\n\n    #[inline]\n    pub fn set___mispredict(&mut self, val: __uint32_t) {\n        unsafe {\n            let val: u32 = ::std::mem::transmute(val);\n            self._bitfield_1.set(0usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn __tsx_abort(&self) -> __uint32_t {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) }\n    }\n\n    #[inline]\n    pub fn set___tsx_abort(&mut self, val: __uint32_t) {\n        unsafe {\n            let val: u32 = ::std::mem::transmute(val);\n            self._bitfield_1.set(1usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn __in_tsx(&self) -> __uint32_t {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u32) }\n    }\n\n    #[inline]\n    pub fn set___in_tsx(&mut self, val: __uint32_t) {\n        unsafe {\n            let val: u32 = ::std::mem::transmute(val);\n            self._bitfield_1.set(2usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn __cycle_count(&self) -> __uint32_t {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 16u8) as u32) }\n    }\n\n    #[inline]\n    pub fn set___cycle_count(&mut self, val: __uint32_t) {\n        unsafe {\n            let val: u32 = ::std::mem::transmute(val);\n            self._bitfield_1.set(3usize, 16u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn __reserved(&self) -> __uint32_t {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(19usize, 13u8) as u32) }\n    }\n\n    #[inline]\n    pub fn set___reserved(&mut self, val: __uint32_t) {\n        unsafe {\n            let val: u32 = ::std::mem::transmute(val);\n            self._bitfield_1.set(19usize, 13u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn new_bitfield_1(\n        __mispredict: __uint32_t,\n        __tsx_abort: __uint32_t,\n        __in_tsx: __uint32_t,\n        __cycle_count: __uint32_t,\n        __reserved: __uint32_t,\n    ) -> __BindgenBitfieldUnit<[u8; 4usize]> {\n        let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default();\n        __bindgen_bitfield_unit.set(0usize, 1u8, {\n            let __mispredict: u32 = unsafe { ::std::mem::transmute(__mispredict) };\n            __mispredict as u64\n        });\n        __bindgen_bitfield_unit.set(1usize, 1u8, {\n            let __tsx_abort: u32 = unsafe { ::std::mem::transmute(__tsx_abort) };\n            __tsx_abort as u64\n        });\n        __bindgen_bitfield_unit.set(2usize, 1u8, {\n            let __in_tsx: u32 = unsafe { ::std::mem::transmute(__in_tsx) };\n            __in_tsx as u64\n        });\n        __bindgen_bitfield_unit.set(3usize, 16u8, {\n            let __cycle_count: u32 = unsafe { ::std::mem::transmute(__cycle_count) };\n            __cycle_count as u64\n        });\n        __bindgen_bitfield_unit.set(19usize, 13u8, {\n            let __reserved: u32 = unsafe { ::std::mem::transmute(__reserved) };\n            __reserved as u64\n        });\n        __bindgen_bitfield_unit\n    }\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __last_branch_state {\n    pub __lbr_count: ::std::os::raw::c_int,\n    pub _bitfield_align_1: [u32; 0],\n    pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>,\n    pub __lbrs: [__last_branch_record; 32usize],\n}\n#[test]\nfn bindgen_test_layout___last_branch_state() {\n    const UNINIT: ::std::mem::MaybeUninit<__last_branch_state> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__last_branch_state>(),\n        776usize,\n        concat!(\"Size of: \", stringify!(__last_branch_state))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__last_branch_state>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__last_branch_state))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__lbr_count) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__last_branch_state),\n            \"::\",\n            stringify!(__lbr_count)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__lbrs) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__last_branch_state),\n            \"::\",\n            stringify!(__lbrs)\n        )\n    );\n}\nimpl __last_branch_state {\n    #[inline]\n    pub fn __lbr_supported_tsx(&self) -> __uint32_t {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) }\n    }\n\n    #[inline]\n    pub fn set___lbr_supported_tsx(&mut self, val: __uint32_t) {\n        unsafe {\n            let val: u32 = ::std::mem::transmute(val);\n            self._bitfield_1.set(0usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn __lbr_supported_cycle_count(&self) -> __uint32_t {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) }\n    }\n\n    #[inline]\n    pub fn set___lbr_supported_cycle_count(&mut self, val: __uint32_t) {\n        unsafe {\n            let val: u32 = ::std::mem::transmute(val);\n            self._bitfield_1.set(1usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn __reserved(&self) -> __uint32_t {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 30u8) as u32) }\n    }\n\n    #[inline]\n    pub fn set___reserved(&mut self, val: __uint32_t) {\n        unsafe {\n            let val: u32 = ::std::mem::transmute(val);\n            self._bitfield_1.set(2usize, 30u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn new_bitfield_1(\n        __lbr_supported_tsx: __uint32_t,\n        __lbr_supported_cycle_count: __uint32_t,\n        __reserved: __uint32_t,\n    ) -> __BindgenBitfieldUnit<[u8; 4usize]> {\n        let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default();\n        __bindgen_bitfield_unit.set(0usize, 1u8, {\n            let __lbr_supported_tsx: u32 = unsafe { ::std::mem::transmute(__lbr_supported_tsx) };\n            __lbr_supported_tsx as u64\n        });\n        __bindgen_bitfield_unit.set(1usize, 1u8, {\n            let __lbr_supported_cycle_count: u32 = unsafe { ::std::mem::transmute(__lbr_supported_cycle_count) };\n            __lbr_supported_cycle_count as u64\n        });\n        __bindgen_bitfield_unit.set(2usize, 30u8, {\n            let __reserved: u32 = unsafe { ::std::mem::transmute(__reserved) };\n            __reserved as u64\n        });\n        __bindgen_bitfield_unit\n    }\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __x86_pagein_state {\n    pub __pagein_error: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout___x86_pagein_state() {\n    const UNINIT: ::std::mem::MaybeUninit<__x86_pagein_state> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__x86_pagein_state>(),\n        4usize,\n        concat!(\"Size of: \", stringify!(__x86_pagein_state))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__x86_pagein_state>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(__x86_pagein_state))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__pagein_error) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__x86_pagein_state),\n            \"::\",\n            stringify!(__pagein_error)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_x86_thread_state64 {\n    pub __rax: __uint64_t,\n    pub __rbx: __uint64_t,\n    pub __rcx: __uint64_t,\n    pub __rdx: __uint64_t,\n    pub __rdi: __uint64_t,\n    pub __rsi: __uint64_t,\n    pub __rbp: __uint64_t,\n    pub __rsp: __uint64_t,\n    pub __r8: __uint64_t,\n    pub __r9: __uint64_t,\n    pub __r10: __uint64_t,\n    pub __r11: __uint64_t,\n    pub __r12: __uint64_t,\n    pub __r13: __uint64_t,\n    pub __r14: __uint64_t,\n    pub __r15: __uint64_t,\n    pub __rip: __uint64_t,\n    pub __rflags: __uint64_t,\n    pub __cs: __uint64_t,\n    pub __fs: __uint64_t,\n    pub __gs: __uint64_t,\n}\n#[test]\nfn bindgen_test_layout___darwin_x86_thread_state64() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_x86_thread_state64> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_x86_thread_state64>(),\n        168usize,\n        concat!(\"Size of: \", stringify!(__darwin_x86_thread_state64))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_x86_thread_state64>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__darwin_x86_thread_state64))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__rax) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_thread_state64),\n            \"::\",\n            stringify!(__rax)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__rbx) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_thread_state64),\n            \"::\",\n            stringify!(__rbx)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__rcx) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_thread_state64),\n            \"::\",\n            stringify!(__rcx)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__rdx) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_thread_state64),\n            \"::\",\n            stringify!(__rdx)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__rdi) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_thread_state64),\n            \"::\",\n            stringify!(__rdi)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__rsi) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_thread_state64),\n            \"::\",\n            stringify!(__rsi)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__rbp) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_thread_state64),\n            \"::\",\n            stringify!(__rbp)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__rsp) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_thread_state64),\n            \"::\",\n            stringify!(__rsp)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__r8) as usize - ptr as usize },\n        64usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_thread_state64),\n            \"::\",\n            stringify!(__r8)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__r9) as usize - ptr as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_thread_state64),\n            \"::\",\n            stringify!(__r9)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__r10) as usize - ptr as usize },\n        80usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_thread_state64),\n            \"::\",\n            stringify!(__r10)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__r11) as usize - ptr as usize },\n        88usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_thread_state64),\n            \"::\",\n            stringify!(__r11)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__r12) as usize - ptr as usize },\n        96usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_thread_state64),\n            \"::\",\n            stringify!(__r12)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__r13) as usize - ptr as usize },\n        104usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_thread_state64),\n            \"::\",\n            stringify!(__r13)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__r14) as usize - ptr as usize },\n        112usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_thread_state64),\n            \"::\",\n            stringify!(__r14)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__r15) as usize - ptr as usize },\n        120usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_thread_state64),\n            \"::\",\n            stringify!(__r15)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__rip) as usize - ptr as usize },\n        128usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_thread_state64),\n            \"::\",\n            stringify!(__rip)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__rflags) as usize - ptr as usize },\n        136usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_thread_state64),\n            \"::\",\n            stringify!(__rflags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__cs) as usize - ptr as usize },\n        144usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_thread_state64),\n            \"::\",\n            stringify!(__cs)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fs) as usize - ptr as usize },\n        152usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_thread_state64),\n            \"::\",\n            stringify!(__fs)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__gs) as usize - ptr as usize },\n        160usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_thread_state64),\n            \"::\",\n            stringify!(__gs)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_x86_thread_full_state64 {\n    pub __ss64: __darwin_x86_thread_state64,\n    pub __ds: __uint64_t,\n    pub __es: __uint64_t,\n    pub __ss: __uint64_t,\n    pub __gsbase: __uint64_t,\n}\n#[test]\nfn bindgen_test_layout___darwin_x86_thread_full_state64() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_x86_thread_full_state64> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_x86_thread_full_state64>(),\n        200usize,\n        concat!(\"Size of: \", stringify!(__darwin_x86_thread_full_state64))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_x86_thread_full_state64>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__darwin_x86_thread_full_state64))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ss64) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_thread_full_state64),\n            \"::\",\n            stringify!(__ss64)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ds) as usize - ptr as usize },\n        168usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_thread_full_state64),\n            \"::\",\n            stringify!(__ds)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__es) as usize - ptr as usize },\n        176usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_thread_full_state64),\n            \"::\",\n            stringify!(__es)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ss) as usize - ptr as usize },\n        184usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_thread_full_state64),\n            \"::\",\n            stringify!(__ss)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__gsbase) as usize - ptr as usize },\n        192usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_thread_full_state64),\n            \"::\",\n            stringify!(__gsbase)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_x86_float_state64 {\n    pub __fpu_reserved: [::std::os::raw::c_int; 2usize],\n    pub __fpu_fcw: __darwin_fp_control,\n    pub __fpu_fsw: __darwin_fp_status,\n    pub __fpu_ftw: __uint8_t,\n    pub __fpu_rsrv1: __uint8_t,\n    pub __fpu_fop: __uint16_t,\n    pub __fpu_ip: __uint32_t,\n    pub __fpu_cs: __uint16_t,\n    pub __fpu_rsrv2: __uint16_t,\n    pub __fpu_dp: __uint32_t,\n    pub __fpu_ds: __uint16_t,\n    pub __fpu_rsrv3: __uint16_t,\n    pub __fpu_mxcsr: __uint32_t,\n    pub __fpu_mxcsrmask: __uint32_t,\n    pub __fpu_stmm0: __darwin_mmst_reg,\n    pub __fpu_stmm1: __darwin_mmst_reg,\n    pub __fpu_stmm2: __darwin_mmst_reg,\n    pub __fpu_stmm3: __darwin_mmst_reg,\n    pub __fpu_stmm4: __darwin_mmst_reg,\n    pub __fpu_stmm5: __darwin_mmst_reg,\n    pub __fpu_stmm6: __darwin_mmst_reg,\n    pub __fpu_stmm7: __darwin_mmst_reg,\n    pub __fpu_xmm0: __darwin_xmm_reg,\n    pub __fpu_xmm1: __darwin_xmm_reg,\n    pub __fpu_xmm2: __darwin_xmm_reg,\n    pub __fpu_xmm3: __darwin_xmm_reg,\n    pub __fpu_xmm4: __darwin_xmm_reg,\n    pub __fpu_xmm5: __darwin_xmm_reg,\n    pub __fpu_xmm6: __darwin_xmm_reg,\n    pub __fpu_xmm7: __darwin_xmm_reg,\n    pub __fpu_xmm8: __darwin_xmm_reg,\n    pub __fpu_xmm9: __darwin_xmm_reg,\n    pub __fpu_xmm10: __darwin_xmm_reg,\n    pub __fpu_xmm11: __darwin_xmm_reg,\n    pub __fpu_xmm12: __darwin_xmm_reg,\n    pub __fpu_xmm13: __darwin_xmm_reg,\n    pub __fpu_xmm14: __darwin_xmm_reg,\n    pub __fpu_xmm15: __darwin_xmm_reg,\n    pub __fpu_rsrv4: [::std::os::raw::c_char; 96usize],\n    pub __fpu_reserved1: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout___darwin_x86_float_state64() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_x86_float_state64> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_x86_float_state64>(),\n        524usize,\n        concat!(\"Size of: \", stringify!(__darwin_x86_float_state64))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_x86_float_state64>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(__darwin_x86_float_state64))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_reserved) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_reserved)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_fcw) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_fcw)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_fsw) as usize - ptr as usize },\n        10usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_fsw)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ftw) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_ftw)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_rsrv1) as usize - ptr as usize },\n        13usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_rsrv1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_fop) as usize - ptr as usize },\n        14usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_fop)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ip) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_ip)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_cs) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_cs)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_rsrv2) as usize - ptr as usize },\n        22usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_rsrv2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_dp) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_dp)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ds) as usize - ptr as usize },\n        28usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_ds)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_rsrv3) as usize - ptr as usize },\n        30usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_rsrv3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_mxcsr) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_mxcsr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_mxcsrmask) as usize - ptr as usize },\n        36usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_mxcsrmask)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm0) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_stmm0)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm1) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_stmm1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm2) as usize - ptr as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_stmm2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm3) as usize - ptr as usize },\n        88usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_stmm3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm4) as usize - ptr as usize },\n        104usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_stmm4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm5) as usize - ptr as usize },\n        120usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_stmm5)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm6) as usize - ptr as usize },\n        136usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_stmm6)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm7) as usize - ptr as usize },\n        152usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_stmm7)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm0) as usize - ptr as usize },\n        168usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_xmm0)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm1) as usize - ptr as usize },\n        184usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_xmm1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm2) as usize - ptr as usize },\n        200usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_xmm2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm3) as usize - ptr as usize },\n        216usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_xmm3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm4) as usize - ptr as usize },\n        232usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_xmm4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm5) as usize - ptr as usize },\n        248usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_xmm5)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm6) as usize - ptr as usize },\n        264usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_xmm6)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm7) as usize - ptr as usize },\n        280usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_xmm7)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm8) as usize - ptr as usize },\n        296usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_xmm8)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm9) as usize - ptr as usize },\n        312usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_xmm9)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm10) as usize - ptr as usize },\n        328usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_xmm10)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm11) as usize - ptr as usize },\n        344usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_xmm11)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm12) as usize - ptr as usize },\n        360usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_xmm12)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm13) as usize - ptr as usize },\n        376usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_xmm13)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm14) as usize - ptr as usize },\n        392usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_xmm14)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm15) as usize - ptr as usize },\n        408usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_xmm15)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_rsrv4) as usize - ptr as usize },\n        424usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_rsrv4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_reserved1) as usize - ptr as usize },\n        520usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_float_state64),\n            \"::\",\n            stringify!(__fpu_reserved1)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_x86_avx_state64 {\n    pub __fpu_reserved: [::std::os::raw::c_int; 2usize],\n    pub __fpu_fcw: __darwin_fp_control,\n    pub __fpu_fsw: __darwin_fp_status,\n    pub __fpu_ftw: __uint8_t,\n    pub __fpu_rsrv1: __uint8_t,\n    pub __fpu_fop: __uint16_t,\n    pub __fpu_ip: __uint32_t,\n    pub __fpu_cs: __uint16_t,\n    pub __fpu_rsrv2: __uint16_t,\n    pub __fpu_dp: __uint32_t,\n    pub __fpu_ds: __uint16_t,\n    pub __fpu_rsrv3: __uint16_t,\n    pub __fpu_mxcsr: __uint32_t,\n    pub __fpu_mxcsrmask: __uint32_t,\n    pub __fpu_stmm0: __darwin_mmst_reg,\n    pub __fpu_stmm1: __darwin_mmst_reg,\n    pub __fpu_stmm2: __darwin_mmst_reg,\n    pub __fpu_stmm3: __darwin_mmst_reg,\n    pub __fpu_stmm4: __darwin_mmst_reg,\n    pub __fpu_stmm5: __darwin_mmst_reg,\n    pub __fpu_stmm6: __darwin_mmst_reg,\n    pub __fpu_stmm7: __darwin_mmst_reg,\n    pub __fpu_xmm0: __darwin_xmm_reg,\n    pub __fpu_xmm1: __darwin_xmm_reg,\n    pub __fpu_xmm2: __darwin_xmm_reg,\n    pub __fpu_xmm3: __darwin_xmm_reg,\n    pub __fpu_xmm4: __darwin_xmm_reg,\n    pub __fpu_xmm5: __darwin_xmm_reg,\n    pub __fpu_xmm6: __darwin_xmm_reg,\n    pub __fpu_xmm7: __darwin_xmm_reg,\n    pub __fpu_xmm8: __darwin_xmm_reg,\n    pub __fpu_xmm9: __darwin_xmm_reg,\n    pub __fpu_xmm10: __darwin_xmm_reg,\n    pub __fpu_xmm11: __darwin_xmm_reg,\n    pub __fpu_xmm12: __darwin_xmm_reg,\n    pub __fpu_xmm13: __darwin_xmm_reg,\n    pub __fpu_xmm14: __darwin_xmm_reg,\n    pub __fpu_xmm15: __darwin_xmm_reg,\n    pub __fpu_rsrv4: [::std::os::raw::c_char; 96usize],\n    pub __fpu_reserved1: ::std::os::raw::c_int,\n    pub __avx_reserved1: [::std::os::raw::c_char; 64usize],\n    pub __fpu_ymmh0: __darwin_xmm_reg,\n    pub __fpu_ymmh1: __darwin_xmm_reg,\n    pub __fpu_ymmh2: __darwin_xmm_reg,\n    pub __fpu_ymmh3: __darwin_xmm_reg,\n    pub __fpu_ymmh4: __darwin_xmm_reg,\n    pub __fpu_ymmh5: __darwin_xmm_reg,\n    pub __fpu_ymmh6: __darwin_xmm_reg,\n    pub __fpu_ymmh7: __darwin_xmm_reg,\n    pub __fpu_ymmh8: __darwin_xmm_reg,\n    pub __fpu_ymmh9: __darwin_xmm_reg,\n    pub __fpu_ymmh10: __darwin_xmm_reg,\n    pub __fpu_ymmh11: __darwin_xmm_reg,\n    pub __fpu_ymmh12: __darwin_xmm_reg,\n    pub __fpu_ymmh13: __darwin_xmm_reg,\n    pub __fpu_ymmh14: __darwin_xmm_reg,\n    pub __fpu_ymmh15: __darwin_xmm_reg,\n}\n#[test]\nfn bindgen_test_layout___darwin_x86_avx_state64() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_x86_avx_state64> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_x86_avx_state64>(),\n        844usize,\n        concat!(\"Size of: \", stringify!(__darwin_x86_avx_state64))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_x86_avx_state64>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(__darwin_x86_avx_state64))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_reserved) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_reserved)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_fcw) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_fcw)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_fsw) as usize - ptr as usize },\n        10usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_fsw)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ftw) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_ftw)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_rsrv1) as usize - ptr as usize },\n        13usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_rsrv1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_fop) as usize - ptr as usize },\n        14usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_fop)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ip) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_ip)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_cs) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_cs)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_rsrv2) as usize - ptr as usize },\n        22usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_rsrv2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_dp) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_dp)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ds) as usize - ptr as usize },\n        28usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_ds)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_rsrv3) as usize - ptr as usize },\n        30usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_rsrv3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_mxcsr) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_mxcsr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_mxcsrmask) as usize - ptr as usize },\n        36usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_mxcsrmask)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm0) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_stmm0)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm1) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_stmm1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm2) as usize - ptr as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_stmm2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm3) as usize - ptr as usize },\n        88usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_stmm3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm4) as usize - ptr as usize },\n        104usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_stmm4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm5) as usize - ptr as usize },\n        120usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_stmm5)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm6) as usize - ptr as usize },\n        136usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_stmm6)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm7) as usize - ptr as usize },\n        152usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_stmm7)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm0) as usize - ptr as usize },\n        168usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_xmm0)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm1) as usize - ptr as usize },\n        184usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_xmm1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm2) as usize - ptr as usize },\n        200usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_xmm2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm3) as usize - ptr as usize },\n        216usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_xmm3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm4) as usize - ptr as usize },\n        232usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_xmm4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm5) as usize - ptr as usize },\n        248usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_xmm5)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm6) as usize - ptr as usize },\n        264usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_xmm6)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm7) as usize - ptr as usize },\n        280usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_xmm7)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm8) as usize - ptr as usize },\n        296usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_xmm8)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm9) as usize - ptr as usize },\n        312usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_xmm9)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm10) as usize - ptr as usize },\n        328usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_xmm10)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm11) as usize - ptr as usize },\n        344usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_xmm11)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm12) as usize - ptr as usize },\n        360usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_xmm12)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm13) as usize - ptr as usize },\n        376usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_xmm13)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm14) as usize - ptr as usize },\n        392usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_xmm14)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm15) as usize - ptr as usize },\n        408usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_xmm15)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_rsrv4) as usize - ptr as usize },\n        424usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_rsrv4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_reserved1) as usize - ptr as usize },\n        520usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_reserved1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__avx_reserved1) as usize - ptr as usize },\n        524usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__avx_reserved1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh0) as usize - ptr as usize },\n        588usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_ymmh0)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh1) as usize - ptr as usize },\n        604usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_ymmh1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh2) as usize - ptr as usize },\n        620usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_ymmh2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh3) as usize - ptr as usize },\n        636usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_ymmh3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh4) as usize - ptr as usize },\n        652usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_ymmh4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh5) as usize - ptr as usize },\n        668usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_ymmh5)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh6) as usize - ptr as usize },\n        684usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_ymmh6)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh7) as usize - ptr as usize },\n        700usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_ymmh7)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh8) as usize - ptr as usize },\n        716usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_ymmh8)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh9) as usize - ptr as usize },\n        732usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_ymmh9)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh10) as usize - ptr as usize },\n        748usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_ymmh10)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh11) as usize - ptr as usize },\n        764usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_ymmh11)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh12) as usize - ptr as usize },\n        780usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_ymmh12)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh13) as usize - ptr as usize },\n        796usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_ymmh13)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh14) as usize - ptr as usize },\n        812usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_ymmh14)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh15) as usize - ptr as usize },\n        828usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx_state64),\n            \"::\",\n            stringify!(__fpu_ymmh15)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_x86_avx512_state64 {\n    pub __fpu_reserved: [::std::os::raw::c_int; 2usize],\n    pub __fpu_fcw: __darwin_fp_control,\n    pub __fpu_fsw: __darwin_fp_status,\n    pub __fpu_ftw: __uint8_t,\n    pub __fpu_rsrv1: __uint8_t,\n    pub __fpu_fop: __uint16_t,\n    pub __fpu_ip: __uint32_t,\n    pub __fpu_cs: __uint16_t,\n    pub __fpu_rsrv2: __uint16_t,\n    pub __fpu_dp: __uint32_t,\n    pub __fpu_ds: __uint16_t,\n    pub __fpu_rsrv3: __uint16_t,\n    pub __fpu_mxcsr: __uint32_t,\n    pub __fpu_mxcsrmask: __uint32_t,\n    pub __fpu_stmm0: __darwin_mmst_reg,\n    pub __fpu_stmm1: __darwin_mmst_reg,\n    pub __fpu_stmm2: __darwin_mmst_reg,\n    pub __fpu_stmm3: __darwin_mmst_reg,\n    pub __fpu_stmm4: __darwin_mmst_reg,\n    pub __fpu_stmm5: __darwin_mmst_reg,\n    pub __fpu_stmm6: __darwin_mmst_reg,\n    pub __fpu_stmm7: __darwin_mmst_reg,\n    pub __fpu_xmm0: __darwin_xmm_reg,\n    pub __fpu_xmm1: __darwin_xmm_reg,\n    pub __fpu_xmm2: __darwin_xmm_reg,\n    pub __fpu_xmm3: __darwin_xmm_reg,\n    pub __fpu_xmm4: __darwin_xmm_reg,\n    pub __fpu_xmm5: __darwin_xmm_reg,\n    pub __fpu_xmm6: __darwin_xmm_reg,\n    pub __fpu_xmm7: __darwin_xmm_reg,\n    pub __fpu_xmm8: __darwin_xmm_reg,\n    pub __fpu_xmm9: __darwin_xmm_reg,\n    pub __fpu_xmm10: __darwin_xmm_reg,\n    pub __fpu_xmm11: __darwin_xmm_reg,\n    pub __fpu_xmm12: __darwin_xmm_reg,\n    pub __fpu_xmm13: __darwin_xmm_reg,\n    pub __fpu_xmm14: __darwin_xmm_reg,\n    pub __fpu_xmm15: __darwin_xmm_reg,\n    pub __fpu_rsrv4: [::std::os::raw::c_char; 96usize],\n    pub __fpu_reserved1: ::std::os::raw::c_int,\n    pub __avx_reserved1: [::std::os::raw::c_char; 64usize],\n    pub __fpu_ymmh0: __darwin_xmm_reg,\n    pub __fpu_ymmh1: __darwin_xmm_reg,\n    pub __fpu_ymmh2: __darwin_xmm_reg,\n    pub __fpu_ymmh3: __darwin_xmm_reg,\n    pub __fpu_ymmh4: __darwin_xmm_reg,\n    pub __fpu_ymmh5: __darwin_xmm_reg,\n    pub __fpu_ymmh6: __darwin_xmm_reg,\n    pub __fpu_ymmh7: __darwin_xmm_reg,\n    pub __fpu_ymmh8: __darwin_xmm_reg,\n    pub __fpu_ymmh9: __darwin_xmm_reg,\n    pub __fpu_ymmh10: __darwin_xmm_reg,\n    pub __fpu_ymmh11: __darwin_xmm_reg,\n    pub __fpu_ymmh12: __darwin_xmm_reg,\n    pub __fpu_ymmh13: __darwin_xmm_reg,\n    pub __fpu_ymmh14: __darwin_xmm_reg,\n    pub __fpu_ymmh15: __darwin_xmm_reg,\n    pub __fpu_k0: __darwin_opmask_reg,\n    pub __fpu_k1: __darwin_opmask_reg,\n    pub __fpu_k2: __darwin_opmask_reg,\n    pub __fpu_k3: __darwin_opmask_reg,\n    pub __fpu_k4: __darwin_opmask_reg,\n    pub __fpu_k5: __darwin_opmask_reg,\n    pub __fpu_k6: __darwin_opmask_reg,\n    pub __fpu_k7: __darwin_opmask_reg,\n    pub __fpu_zmmh0: __darwin_ymm_reg,\n    pub __fpu_zmmh1: __darwin_ymm_reg,\n    pub __fpu_zmmh2: __darwin_ymm_reg,\n    pub __fpu_zmmh3: __darwin_ymm_reg,\n    pub __fpu_zmmh4: __darwin_ymm_reg,\n    pub __fpu_zmmh5: __darwin_ymm_reg,\n    pub __fpu_zmmh6: __darwin_ymm_reg,\n    pub __fpu_zmmh7: __darwin_ymm_reg,\n    pub __fpu_zmmh8: __darwin_ymm_reg,\n    pub __fpu_zmmh9: __darwin_ymm_reg,\n    pub __fpu_zmmh10: __darwin_ymm_reg,\n    pub __fpu_zmmh11: __darwin_ymm_reg,\n    pub __fpu_zmmh12: __darwin_ymm_reg,\n    pub __fpu_zmmh13: __darwin_ymm_reg,\n    pub __fpu_zmmh14: __darwin_ymm_reg,\n    pub __fpu_zmmh15: __darwin_ymm_reg,\n    pub __fpu_zmm16: __darwin_zmm_reg,\n    pub __fpu_zmm17: __darwin_zmm_reg,\n    pub __fpu_zmm18: __darwin_zmm_reg,\n    pub __fpu_zmm19: __darwin_zmm_reg,\n    pub __fpu_zmm20: __darwin_zmm_reg,\n    pub __fpu_zmm21: __darwin_zmm_reg,\n    pub __fpu_zmm22: __darwin_zmm_reg,\n    pub __fpu_zmm23: __darwin_zmm_reg,\n    pub __fpu_zmm24: __darwin_zmm_reg,\n    pub __fpu_zmm25: __darwin_zmm_reg,\n    pub __fpu_zmm26: __darwin_zmm_reg,\n    pub __fpu_zmm27: __darwin_zmm_reg,\n    pub __fpu_zmm28: __darwin_zmm_reg,\n    pub __fpu_zmm29: __darwin_zmm_reg,\n    pub __fpu_zmm30: __darwin_zmm_reg,\n    pub __fpu_zmm31: __darwin_zmm_reg,\n}\n#[test]\nfn bindgen_test_layout___darwin_x86_avx512_state64() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_x86_avx512_state64> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_x86_avx512_state64>(),\n        2444usize,\n        concat!(\"Size of: \", stringify!(__darwin_x86_avx512_state64))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_x86_avx512_state64>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(__darwin_x86_avx512_state64))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_reserved) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_reserved)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_fcw) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_fcw)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_fsw) as usize - ptr as usize },\n        10usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_fsw)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ftw) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_ftw)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_rsrv1) as usize - ptr as usize },\n        13usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_rsrv1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_fop) as usize - ptr as usize },\n        14usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_fop)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ip) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_ip)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_cs) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_cs)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_rsrv2) as usize - ptr as usize },\n        22usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_rsrv2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_dp) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_dp)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ds) as usize - ptr as usize },\n        28usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_ds)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_rsrv3) as usize - ptr as usize },\n        30usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_rsrv3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_mxcsr) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_mxcsr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_mxcsrmask) as usize - ptr as usize },\n        36usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_mxcsrmask)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm0) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_stmm0)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm1) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_stmm1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm2) as usize - ptr as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_stmm2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm3) as usize - ptr as usize },\n        88usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_stmm3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm4) as usize - ptr as usize },\n        104usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_stmm4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm5) as usize - ptr as usize },\n        120usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_stmm5)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm6) as usize - ptr as usize },\n        136usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_stmm6)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_stmm7) as usize - ptr as usize },\n        152usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_stmm7)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm0) as usize - ptr as usize },\n        168usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_xmm0)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm1) as usize - ptr as usize },\n        184usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_xmm1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm2) as usize - ptr as usize },\n        200usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_xmm2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm3) as usize - ptr as usize },\n        216usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_xmm3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm4) as usize - ptr as usize },\n        232usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_xmm4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm5) as usize - ptr as usize },\n        248usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_xmm5)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm6) as usize - ptr as usize },\n        264usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_xmm6)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm7) as usize - ptr as usize },\n        280usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_xmm7)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm8) as usize - ptr as usize },\n        296usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_xmm8)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm9) as usize - ptr as usize },\n        312usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_xmm9)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm10) as usize - ptr as usize },\n        328usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_xmm10)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm11) as usize - ptr as usize },\n        344usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_xmm11)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm12) as usize - ptr as usize },\n        360usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_xmm12)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm13) as usize - ptr as usize },\n        376usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_xmm13)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm14) as usize - ptr as usize },\n        392usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_xmm14)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_xmm15) as usize - ptr as usize },\n        408usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_xmm15)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_rsrv4) as usize - ptr as usize },\n        424usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_rsrv4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_reserved1) as usize - ptr as usize },\n        520usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_reserved1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__avx_reserved1) as usize - ptr as usize },\n        524usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__avx_reserved1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh0) as usize - ptr as usize },\n        588usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_ymmh0)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh1) as usize - ptr as usize },\n        604usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_ymmh1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh2) as usize - ptr as usize },\n        620usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_ymmh2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh3) as usize - ptr as usize },\n        636usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_ymmh3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh4) as usize - ptr as usize },\n        652usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_ymmh4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh5) as usize - ptr as usize },\n        668usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_ymmh5)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh6) as usize - ptr as usize },\n        684usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_ymmh6)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh7) as usize - ptr as usize },\n        700usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_ymmh7)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh8) as usize - ptr as usize },\n        716usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_ymmh8)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh9) as usize - ptr as usize },\n        732usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_ymmh9)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh10) as usize - ptr as usize },\n        748usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_ymmh10)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh11) as usize - ptr as usize },\n        764usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_ymmh11)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh12) as usize - ptr as usize },\n        780usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_ymmh12)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh13) as usize - ptr as usize },\n        796usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_ymmh13)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh14) as usize - ptr as usize },\n        812usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_ymmh14)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_ymmh15) as usize - ptr as usize },\n        828usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_ymmh15)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_k0) as usize - ptr as usize },\n        844usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_k0)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_k1) as usize - ptr as usize },\n        852usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_k1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_k2) as usize - ptr as usize },\n        860usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_k2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_k3) as usize - ptr as usize },\n        868usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_k3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_k4) as usize - ptr as usize },\n        876usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_k4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_k5) as usize - ptr as usize },\n        884usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_k5)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_k6) as usize - ptr as usize },\n        892usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_k6)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_k7) as usize - ptr as usize },\n        900usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_k7)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmmh0) as usize - ptr as usize },\n        908usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmmh0)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmmh1) as usize - ptr as usize },\n        940usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmmh1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmmh2) as usize - ptr as usize },\n        972usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmmh2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmmh3) as usize - ptr as usize },\n        1004usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmmh3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmmh4) as usize - ptr as usize },\n        1036usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmmh4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmmh5) as usize - ptr as usize },\n        1068usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmmh5)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmmh6) as usize - ptr as usize },\n        1100usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmmh6)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmmh7) as usize - ptr as usize },\n        1132usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmmh7)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmmh8) as usize - ptr as usize },\n        1164usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmmh8)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmmh9) as usize - ptr as usize },\n        1196usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmmh9)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmmh10) as usize - ptr as usize },\n        1228usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmmh10)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmmh11) as usize - ptr as usize },\n        1260usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmmh11)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmmh12) as usize - ptr as usize },\n        1292usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmmh12)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmmh13) as usize - ptr as usize },\n        1324usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmmh13)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmmh14) as usize - ptr as usize },\n        1356usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmmh14)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmmh15) as usize - ptr as usize },\n        1388usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmmh15)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmm16) as usize - ptr as usize },\n        1420usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmm16)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmm17) as usize - ptr as usize },\n        1484usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmm17)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmm18) as usize - ptr as usize },\n        1548usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmm18)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmm19) as usize - ptr as usize },\n        1612usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmm19)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmm20) as usize - ptr as usize },\n        1676usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmm20)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmm21) as usize - ptr as usize },\n        1740usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmm21)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmm22) as usize - ptr as usize },\n        1804usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmm22)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmm23) as usize - ptr as usize },\n        1868usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmm23)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmm24) as usize - ptr as usize },\n        1932usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmm24)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmm25) as usize - ptr as usize },\n        1996usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmm25)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmm26) as usize - ptr as usize },\n        2060usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmm26)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmm27) as usize - ptr as usize },\n        2124usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmm27)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmm28) as usize - ptr as usize },\n        2188usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmm28)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmm29) as usize - ptr as usize },\n        2252usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmm29)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmm30) as usize - ptr as usize },\n        2316usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmm30)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fpu_zmm31) as usize - ptr as usize },\n        2380usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_avx512_state64),\n            \"::\",\n            stringify!(__fpu_zmm31)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_x86_exception_state64 {\n    pub __trapno: __uint16_t,\n    pub __cpu: __uint16_t,\n    pub __err: __uint32_t,\n    pub __faultvaddr: __uint64_t,\n}\n#[test]\nfn bindgen_test_layout___darwin_x86_exception_state64() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_x86_exception_state64> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_x86_exception_state64>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(__darwin_x86_exception_state64))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_x86_exception_state64>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__darwin_x86_exception_state64))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__trapno) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_exception_state64),\n            \"::\",\n            stringify!(__trapno)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__cpu) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_exception_state64),\n            \"::\",\n            stringify!(__cpu)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__err) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_exception_state64),\n            \"::\",\n            stringify!(__err)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__faultvaddr) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_exception_state64),\n            \"::\",\n            stringify!(__faultvaddr)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_x86_debug_state64 {\n    pub __dr0: __uint64_t,\n    pub __dr1: __uint64_t,\n    pub __dr2: __uint64_t,\n    pub __dr3: __uint64_t,\n    pub __dr4: __uint64_t,\n    pub __dr5: __uint64_t,\n    pub __dr6: __uint64_t,\n    pub __dr7: __uint64_t,\n}\n#[test]\nfn bindgen_test_layout___darwin_x86_debug_state64() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_x86_debug_state64> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_x86_debug_state64>(),\n        64usize,\n        concat!(\"Size of: \", stringify!(__darwin_x86_debug_state64))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_x86_debug_state64>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__darwin_x86_debug_state64))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__dr0) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_debug_state64),\n            \"::\",\n            stringify!(__dr0)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__dr1) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_debug_state64),\n            \"::\",\n            stringify!(__dr1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__dr2) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_debug_state64),\n            \"::\",\n            stringify!(__dr2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__dr3) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_debug_state64),\n            \"::\",\n            stringify!(__dr3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__dr4) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_debug_state64),\n            \"::\",\n            stringify!(__dr4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__dr5) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_debug_state64),\n            \"::\",\n            stringify!(__dr5)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__dr6) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_debug_state64),\n            \"::\",\n            stringify!(__dr6)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__dr7) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_debug_state64),\n            \"::\",\n            stringify!(__dr7)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_x86_cpmu_state64 {\n    pub __ctrs: [__uint64_t; 16usize],\n}\n#[test]\nfn bindgen_test_layout___darwin_x86_cpmu_state64() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_x86_cpmu_state64> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_x86_cpmu_state64>(),\n        128usize,\n        concat!(\"Size of: \", stringify!(__darwin_x86_cpmu_state64))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_x86_cpmu_state64>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__darwin_x86_cpmu_state64))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ctrs) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_x86_cpmu_state64),\n            \"::\",\n            stringify!(__ctrs)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_mcontext32 {\n    pub __es: __darwin_i386_exception_state,\n    pub __ss: __darwin_i386_thread_state,\n    pub __fs: __darwin_i386_float_state,\n}\n#[test]\nfn bindgen_test_layout___darwin_mcontext32() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_mcontext32> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_mcontext32>(),\n        600usize,\n        concat!(\"Size of: \", stringify!(__darwin_mcontext32))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_mcontext32>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(__darwin_mcontext32))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__es) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mcontext32),\n            \"::\",\n            stringify!(__es)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ss) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mcontext32),\n            \"::\",\n            stringify!(__ss)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fs) as usize - ptr as usize },\n        76usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mcontext32),\n            \"::\",\n            stringify!(__fs)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_mcontext_avx32 {\n    pub __es: __darwin_i386_exception_state,\n    pub __ss: __darwin_i386_thread_state,\n    pub __fs: __darwin_i386_avx_state,\n}\n#[test]\nfn bindgen_test_layout___darwin_mcontext_avx32() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_mcontext_avx32> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_mcontext_avx32>(),\n        792usize,\n        concat!(\"Size of: \", stringify!(__darwin_mcontext_avx32))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_mcontext_avx32>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(__darwin_mcontext_avx32))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__es) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mcontext_avx32),\n            \"::\",\n            stringify!(__es)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ss) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mcontext_avx32),\n            \"::\",\n            stringify!(__ss)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fs) as usize - ptr as usize },\n        76usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mcontext_avx32),\n            \"::\",\n            stringify!(__fs)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_mcontext_avx512_32 {\n    pub __es: __darwin_i386_exception_state,\n    pub __ss: __darwin_i386_thread_state,\n    pub __fs: __darwin_i386_avx512_state,\n}\n#[test]\nfn bindgen_test_layout___darwin_mcontext_avx512_32() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_mcontext_avx512_32> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_mcontext_avx512_32>(),\n        1112usize,\n        concat!(\"Size of: \", stringify!(__darwin_mcontext_avx512_32))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_mcontext_avx512_32>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(__darwin_mcontext_avx512_32))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__es) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mcontext_avx512_32),\n            \"::\",\n            stringify!(__es)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ss) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mcontext_avx512_32),\n            \"::\",\n            stringify!(__ss)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fs) as usize - ptr as usize },\n        76usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mcontext_avx512_32),\n            \"::\",\n            stringify!(__fs)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_mcontext64 {\n    pub __es: __darwin_x86_exception_state64,\n    pub __ss: __darwin_x86_thread_state64,\n    pub __fs: __darwin_x86_float_state64,\n}\n#[test]\nfn bindgen_test_layout___darwin_mcontext64() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_mcontext64> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_mcontext64>(),\n        712usize,\n        concat!(\"Size of: \", stringify!(__darwin_mcontext64))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_mcontext64>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__darwin_mcontext64))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__es) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mcontext64),\n            \"::\",\n            stringify!(__es)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ss) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mcontext64),\n            \"::\",\n            stringify!(__ss)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fs) as usize - ptr as usize },\n        184usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mcontext64),\n            \"::\",\n            stringify!(__fs)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_mcontext64_full {\n    pub __es: __darwin_x86_exception_state64,\n    pub __ss: __darwin_x86_thread_full_state64,\n    pub __fs: __darwin_x86_float_state64,\n}\n#[test]\nfn bindgen_test_layout___darwin_mcontext64_full() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_mcontext64_full> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_mcontext64_full>(),\n        744usize,\n        concat!(\"Size of: \", stringify!(__darwin_mcontext64_full))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_mcontext64_full>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__darwin_mcontext64_full))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__es) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mcontext64_full),\n            \"::\",\n            stringify!(__es)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ss) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mcontext64_full),\n            \"::\",\n            stringify!(__ss)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fs) as usize - ptr as usize },\n        216usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mcontext64_full),\n            \"::\",\n            stringify!(__fs)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_mcontext_avx64 {\n    pub __es: __darwin_x86_exception_state64,\n    pub __ss: __darwin_x86_thread_state64,\n    pub __fs: __darwin_x86_avx_state64,\n}\n#[test]\nfn bindgen_test_layout___darwin_mcontext_avx64() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_mcontext_avx64> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_mcontext_avx64>(),\n        1032usize,\n        concat!(\"Size of: \", stringify!(__darwin_mcontext_avx64))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_mcontext_avx64>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__darwin_mcontext_avx64))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__es) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mcontext_avx64),\n            \"::\",\n            stringify!(__es)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ss) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mcontext_avx64),\n            \"::\",\n            stringify!(__ss)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fs) as usize - ptr as usize },\n        184usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mcontext_avx64),\n            \"::\",\n            stringify!(__fs)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_mcontext_avx64_full {\n    pub __es: __darwin_x86_exception_state64,\n    pub __ss: __darwin_x86_thread_full_state64,\n    pub __fs: __darwin_x86_avx_state64,\n}\n#[test]\nfn bindgen_test_layout___darwin_mcontext_avx64_full() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_mcontext_avx64_full> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_mcontext_avx64_full>(),\n        1064usize,\n        concat!(\"Size of: \", stringify!(__darwin_mcontext_avx64_full))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_mcontext_avx64_full>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__darwin_mcontext_avx64_full))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__es) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mcontext_avx64_full),\n            \"::\",\n            stringify!(__es)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ss) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mcontext_avx64_full),\n            \"::\",\n            stringify!(__ss)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fs) as usize - ptr as usize },\n        216usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mcontext_avx64_full),\n            \"::\",\n            stringify!(__fs)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_mcontext_avx512_64 {\n    pub __es: __darwin_x86_exception_state64,\n    pub __ss: __darwin_x86_thread_state64,\n    pub __fs: __darwin_x86_avx512_state64,\n}\n#[test]\nfn bindgen_test_layout___darwin_mcontext_avx512_64() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_mcontext_avx512_64> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_mcontext_avx512_64>(),\n        2632usize,\n        concat!(\"Size of: \", stringify!(__darwin_mcontext_avx512_64))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_mcontext_avx512_64>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__darwin_mcontext_avx512_64))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__es) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mcontext_avx512_64),\n            \"::\",\n            stringify!(__es)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ss) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mcontext_avx512_64),\n            \"::\",\n            stringify!(__ss)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fs) as usize - ptr as usize },\n        184usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mcontext_avx512_64),\n            \"::\",\n            stringify!(__fs)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_mcontext_avx512_64_full {\n    pub __es: __darwin_x86_exception_state64,\n    pub __ss: __darwin_x86_thread_full_state64,\n    pub __fs: __darwin_x86_avx512_state64,\n}\n#[test]\nfn bindgen_test_layout___darwin_mcontext_avx512_64_full() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_mcontext_avx512_64_full> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_mcontext_avx512_64_full>(),\n        2664usize,\n        concat!(\"Size of: \", stringify!(__darwin_mcontext_avx512_64_full))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_mcontext_avx512_64_full>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__darwin_mcontext_avx512_64_full))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__es) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mcontext_avx512_64_full),\n            \"::\",\n            stringify!(__es)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ss) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mcontext_avx512_64_full),\n            \"::\",\n            stringify!(__ss)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__fs) as usize - ptr as usize },\n        216usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_mcontext_avx512_64_full),\n            \"::\",\n            stringify!(__fs)\n        )\n    );\n}\npub type mcontext_t = *mut __darwin_mcontext64;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_sigaltstack {\n    pub ss_sp: *mut ::std::os::raw::c_void,\n    pub ss_size: __darwin_size_t,\n    pub ss_flags: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout___darwin_sigaltstack() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_sigaltstack> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_sigaltstack>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(__darwin_sigaltstack))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_sigaltstack>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__darwin_sigaltstack))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ss_sp) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_sigaltstack),\n            \"::\",\n            stringify!(ss_sp)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ss_size) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_sigaltstack),\n            \"::\",\n            stringify!(ss_size)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ss_flags) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_sigaltstack),\n            \"::\",\n            stringify!(ss_flags)\n        )\n    );\n}\npub type stack_t = __darwin_sigaltstack;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __darwin_ucontext {\n    pub uc_onstack: ::std::os::raw::c_int,\n    pub uc_sigmask: __darwin_sigset_t,\n    pub uc_stack: __darwin_sigaltstack,\n    pub uc_link: *mut __darwin_ucontext,\n    pub uc_mcsize: __darwin_size_t,\n    pub uc_mcontext: *mut __darwin_mcontext64,\n}\n#[test]\nfn bindgen_test_layout___darwin_ucontext() {\n    const UNINIT: ::std::mem::MaybeUninit<__darwin_ucontext> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__darwin_ucontext>(),\n        56usize,\n        concat!(\"Size of: \", stringify!(__darwin_ucontext))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__darwin_ucontext>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__darwin_ucontext))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uc_onstack) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_ucontext),\n            \"::\",\n            stringify!(uc_onstack)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uc_sigmask) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_ucontext),\n            \"::\",\n            stringify!(uc_sigmask)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uc_stack) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_ucontext),\n            \"::\",\n            stringify!(uc_stack)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uc_link) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_ucontext),\n            \"::\",\n            stringify!(uc_link)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uc_mcsize) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_ucontext),\n            \"::\",\n            stringify!(uc_mcsize)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uc_mcontext) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__darwin_ucontext),\n            \"::\",\n            stringify!(uc_mcontext)\n        )\n    );\n}\npub type ucontext_t = __darwin_ucontext;\npub type sigset_t = __darwin_sigset_t;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union sigval {\n    pub sival_int: ::std::os::raw::c_int,\n    pub sival_ptr: *mut ::std::os::raw::c_void,\n}\n#[test]\nfn bindgen_test_layout_sigval() {\n    const UNINIT: ::std::mem::MaybeUninit<sigval> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sigval>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(sigval))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sigval>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(sigval))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sival_int) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sigval), \"::\", stringify!(sival_int))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sival_ptr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sigval), \"::\", stringify!(sival_ptr))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct sigevent {\n    pub sigev_notify: ::std::os::raw::c_int,\n    pub sigev_signo: ::std::os::raw::c_int,\n    pub sigev_value: sigval,\n    pub sigev_notify_function: ::std::option::Option<unsafe extern \"C\" fn(arg1: sigval)>,\n    pub sigev_notify_attributes: *mut pthread_attr_t,\n}\n#[test]\nfn bindgen_test_layout_sigevent() {\n    const UNINIT: ::std::mem::MaybeUninit<sigevent> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sigevent>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(sigevent))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sigevent>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(sigevent))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sigev_notify) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sigevent),\n            \"::\",\n            stringify!(sigev_notify)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sigev_signo) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(sigevent), \"::\", stringify!(sigev_signo))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sigev_value) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(sigevent), \"::\", stringify!(sigev_value))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sigev_notify_function) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sigevent),\n            \"::\",\n            stringify!(sigev_notify_function)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sigev_notify_attributes) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sigevent),\n            \"::\",\n            stringify!(sigev_notify_attributes)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct __siginfo {\n    pub si_signo: ::std::os::raw::c_int,\n    pub si_errno: ::std::os::raw::c_int,\n    pub si_code: ::std::os::raw::c_int,\n    pub si_pid: pid_t,\n    pub si_uid: uid_t,\n    pub si_status: ::std::os::raw::c_int,\n    pub si_addr: *mut ::std::os::raw::c_void,\n    pub si_value: sigval,\n    pub si_band: ::std::os::raw::c_long,\n    pub __pad: [::std::os::raw::c_ulong; 7usize],\n}\n#[test]\nfn bindgen_test_layout___siginfo() {\n    const UNINIT: ::std::mem::MaybeUninit<__siginfo> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__siginfo>(),\n        104usize,\n        concat!(\"Size of: \", stringify!(__siginfo))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__siginfo>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__siginfo))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).si_signo) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(__siginfo), \"::\", stringify!(si_signo))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).si_errno) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(__siginfo), \"::\", stringify!(si_errno))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).si_code) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(__siginfo), \"::\", stringify!(si_code))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).si_pid) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(__siginfo), \"::\", stringify!(si_pid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).si_uid) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(__siginfo), \"::\", stringify!(si_uid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).si_status) as usize - ptr as usize },\n        20usize,\n        concat!(\"Offset of field: \", stringify!(__siginfo), \"::\", stringify!(si_status))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).si_addr) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(__siginfo), \"::\", stringify!(si_addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).si_value) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(__siginfo), \"::\", stringify!(si_value))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).si_band) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(__siginfo), \"::\", stringify!(si_band))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__pad) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(__siginfo), \"::\", stringify!(__pad))\n    );\n}\npub type siginfo_t = __siginfo;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union __sigaction_u {\n    pub __sa_handler: ::std::option::Option<unsafe extern \"C\" fn(arg1: ::std::os::raw::c_int)>,\n    pub __sa_sigaction: ::std::option::Option<\n        unsafe extern \"C\" fn(arg1: ::std::os::raw::c_int, arg2: *mut __siginfo, arg3: *mut ::std::os::raw::c_void),\n    >,\n}\n#[test]\nfn bindgen_test_layout___sigaction_u() {\n    const UNINIT: ::std::mem::MaybeUninit<__sigaction_u> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__sigaction_u>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(__sigaction_u))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__sigaction_u>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__sigaction_u))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__sa_handler) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__sigaction_u),\n            \"::\",\n            stringify!(__sa_handler)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__sa_sigaction) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__sigaction_u),\n            \"::\",\n            stringify!(__sa_sigaction)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct __sigaction {\n    pub __sigaction_u: __sigaction_u,\n    pub sa_tramp: ::std::option::Option<\n        unsafe extern \"C\" fn(\n            arg1: *mut ::std::os::raw::c_void,\n            arg2: ::std::os::raw::c_int,\n            arg3: ::std::os::raw::c_int,\n            arg4: *mut siginfo_t,\n            arg5: *mut ::std::os::raw::c_void,\n        ),\n    >,\n    pub sa_mask: sigset_t,\n    pub sa_flags: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout___sigaction() {\n    const UNINIT: ::std::mem::MaybeUninit<__sigaction> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__sigaction>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(__sigaction))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__sigaction>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__sigaction))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__sigaction_u) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__sigaction),\n            \"::\",\n            stringify!(__sigaction_u)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sa_tramp) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(__sigaction), \"::\", stringify!(sa_tramp))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sa_mask) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(__sigaction), \"::\", stringify!(sa_mask))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sa_flags) as usize - ptr as usize },\n        20usize,\n        concat!(\"Offset of field: \", stringify!(__sigaction), \"::\", stringify!(sa_flags))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct sigaction {\n    pub __sigaction_u: __sigaction_u,\n    pub sa_mask: sigset_t,\n    pub sa_flags: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_sigaction() {\n    const UNINIT: ::std::mem::MaybeUninit<sigaction> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sigaction>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(sigaction))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sigaction>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(sigaction))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__sigaction_u) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sigaction),\n            \"::\",\n            stringify!(__sigaction_u)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sa_mask) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(sigaction), \"::\", stringify!(sa_mask))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sa_flags) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(sigaction), \"::\", stringify!(sa_flags))\n    );\n}\npub type sig_t = ::std::option::Option<unsafe extern \"C\" fn(arg1: ::std::os::raw::c_int)>;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sigvec {\n    pub sv_handler: ::std::option::Option<unsafe extern \"C\" fn(arg1: ::std::os::raw::c_int)>,\n    pub sv_mask: ::std::os::raw::c_int,\n    pub sv_flags: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_sigvec() {\n    const UNINIT: ::std::mem::MaybeUninit<sigvec> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sigvec>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(sigvec))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sigvec>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(sigvec))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sv_handler) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sigvec), \"::\", stringify!(sv_handler))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sv_mask) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(sigvec), \"::\", stringify!(sv_mask))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sv_flags) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(sigvec), \"::\", stringify!(sv_flags))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sigstack {\n    pub ss_sp: *mut ::std::os::raw::c_char,\n    pub ss_onstack: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_sigstack() {\n    const UNINIT: ::std::mem::MaybeUninit<sigstack> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sigstack>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(sigstack))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sigstack>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(sigstack))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ss_sp) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sigstack), \"::\", stringify!(ss_sp))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ss_onstack) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(sigstack), \"::\", stringify!(ss_onstack))\n    );\n}\nunsafe extern \"C\" {\n    pub fn signal(\n        arg1: ::std::os::raw::c_int,\n        arg2: ::std::option::Option<unsafe extern \"C\" fn(arg1: ::std::os::raw::c_int)>,\n    ) -> ::std::option::Option<\n        unsafe extern \"C\" fn(\n            arg1: ::std::os::raw::c_int,\n            arg2: ::std::option::Option<unsafe extern \"C\" fn(arg1: ::std::os::raw::c_int)>,\n        ),\n    >;\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct radix_node {\n    pub rn_mklist: *mut radix_mask,\n    pub rn_parent: *mut radix_node,\n    pub rn_bit: ::std::os::raw::c_short,\n    pub rn_bmask: ::std::os::raw::c_char,\n    pub rn_flags: u_char,\n    pub rn_u: radix_node__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union radix_node__bindgen_ty_1 {\n    pub rn_leaf: radix_node__bindgen_ty_1__bindgen_ty_1,\n    pub rn_node: radix_node__bindgen_ty_1__bindgen_ty_2,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct radix_node__bindgen_ty_1__bindgen_ty_1 {\n    pub rn_Key: caddr_t,\n    pub rn_Mask: caddr_t,\n    pub rn_Dupedkey: *mut radix_node,\n}\n#[test]\nfn bindgen_test_layout_radix_node__bindgen_ty_1__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<radix_node__bindgen_ty_1__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<radix_node__bindgen_ty_1__bindgen_ty_1>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(radix_node__bindgen_ty_1__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<radix_node__bindgen_ty_1__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(radix_node__bindgen_ty_1__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_Key) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(rn_Key)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_Mask) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(rn_Mask)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_Dupedkey) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(rn_Dupedkey)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct radix_node__bindgen_ty_1__bindgen_ty_2 {\n    pub rn_Off: ::std::os::raw::c_int,\n    pub rn_L: *mut radix_node,\n    pub rn_R: *mut radix_node,\n}\n#[test]\nfn bindgen_test_layout_radix_node__bindgen_ty_1__bindgen_ty_2() {\n    const UNINIT: ::std::mem::MaybeUninit<radix_node__bindgen_ty_1__bindgen_ty_2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<radix_node__bindgen_ty_1__bindgen_ty_2>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(radix_node__bindgen_ty_1__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<radix_node__bindgen_ty_1__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(radix_node__bindgen_ty_1__bindgen_ty_2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_Off) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node__bindgen_ty_1__bindgen_ty_2),\n            \"::\",\n            stringify!(rn_Off)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_L) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node__bindgen_ty_1__bindgen_ty_2),\n            \"::\",\n            stringify!(rn_L)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_R) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node__bindgen_ty_1__bindgen_ty_2),\n            \"::\",\n            stringify!(rn_R)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_radix_node__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<radix_node__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<radix_node__bindgen_ty_1>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(radix_node__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<radix_node__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(radix_node__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_leaf) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node__bindgen_ty_1),\n            \"::\",\n            stringify!(rn_leaf)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_node) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node__bindgen_ty_1),\n            \"::\",\n            stringify!(rn_node)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_radix_node() {\n    const UNINIT: ::std::mem::MaybeUninit<radix_node> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<radix_node>(),\n        48usize,\n        concat!(\"Size of: \", stringify!(radix_node))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<radix_node>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(radix_node))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_mklist) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(radix_node), \"::\", stringify!(rn_mklist))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_parent) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(radix_node), \"::\", stringify!(rn_parent))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_bit) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(radix_node), \"::\", stringify!(rn_bit))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_bmask) as usize - ptr as usize },\n        18usize,\n        concat!(\"Offset of field: \", stringify!(radix_node), \"::\", stringify!(rn_bmask))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_flags) as usize - ptr as usize },\n        19usize,\n        concat!(\"Offset of field: \", stringify!(radix_node), \"::\", stringify!(rn_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_u) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(radix_node), \"::\", stringify!(rn_u))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct radix_mask {\n    pub rm_bit: ::std::os::raw::c_short,\n    pub rm_unused: ::std::os::raw::c_char,\n    pub rm_flags: u_char,\n    pub rm_mklist: *mut radix_mask,\n    pub rm_rmu: radix_mask__bindgen_ty_1,\n    pub rm_refs: ::std::os::raw::c_int,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union radix_mask__bindgen_ty_1 {\n    pub rmu_mask: caddr_t,\n    pub rmu_leaf: *mut radix_node,\n}\n#[test]\nfn bindgen_test_layout_radix_mask__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<radix_mask__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<radix_mask__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(radix_mask__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<radix_mask__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(radix_mask__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmu_mask) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_mask__bindgen_ty_1),\n            \"::\",\n            stringify!(rmu_mask)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmu_leaf) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_mask__bindgen_ty_1),\n            \"::\",\n            stringify!(rmu_leaf)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_radix_mask() {\n    const UNINIT: ::std::mem::MaybeUninit<radix_mask> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<radix_mask>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(radix_mask))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<radix_mask>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(radix_mask))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rm_bit) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(radix_mask), \"::\", stringify!(rm_bit))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rm_unused) as usize - ptr as usize },\n        2usize,\n        concat!(\"Offset of field: \", stringify!(radix_mask), \"::\", stringify!(rm_unused))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rm_flags) as usize - ptr as usize },\n        3usize,\n        concat!(\"Offset of field: \", stringify!(radix_mask), \"::\", stringify!(rm_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rm_mklist) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(radix_mask), \"::\", stringify!(rm_mklist))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rm_rmu) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(radix_mask), \"::\", stringify!(rm_rmu))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rm_refs) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(radix_mask), \"::\", stringify!(rm_refs))\n    );\n}\npub type walktree_f_t = ::std::option::Option<\n    unsafe extern \"C\" fn(arg1: *mut radix_node, arg2: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int,\n>;\npub type rn_matchf_t = ::std::option::Option<\n    unsafe extern \"C\" fn(arg1: *mut radix_node, arg2: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int,\n>;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct radix_node_head {\n    pub rnh_treetop: *mut radix_node,\n    pub rnh_addrsize: ::std::os::raw::c_int,\n    pub rnh_pktsize: ::std::os::raw::c_int,\n    pub rnh_addaddr: ::std::option::Option<\n        unsafe extern \"C\" fn(\n            v: *mut ::std::os::raw::c_void,\n            mask: *mut ::std::os::raw::c_void,\n            head: *mut radix_node_head,\n            nodes: *mut radix_node,\n        ) -> *mut radix_node,\n    >,\n    pub rnh_addpkt: ::std::option::Option<\n        unsafe extern \"C\" fn(\n            v: *mut ::std::os::raw::c_void,\n            mask: *mut ::std::os::raw::c_void,\n            head: *mut radix_node_head,\n            nodes: *mut radix_node,\n        ) -> *mut radix_node,\n    >,\n    pub rnh_deladdr: ::std::option::Option<\n        unsafe extern \"C\" fn(\n            v: *mut ::std::os::raw::c_void,\n            mask: *mut ::std::os::raw::c_void,\n            head: *mut radix_node_head,\n        ) -> *mut radix_node,\n    >,\n    pub rnh_delpkt: ::std::option::Option<\n        unsafe extern \"C\" fn(\n            v: *mut ::std::os::raw::c_void,\n            mask: *mut ::std::os::raw::c_void,\n            head: *mut radix_node_head,\n        ) -> *mut radix_node,\n    >,\n    pub rnh_matchaddr: ::std::option::Option<\n        unsafe extern \"C\" fn(v: *mut ::std::os::raw::c_void, head: *mut radix_node_head) -> *mut radix_node,\n    >,\n    pub rnh_matchaddr_args: ::std::option::Option<\n        unsafe extern \"C\" fn(\n            v: *mut ::std::os::raw::c_void,\n            head: *mut radix_node_head,\n            f: rn_matchf_t,\n            w: *mut ::std::os::raw::c_void,\n        ) -> *mut radix_node,\n    >,\n    pub rnh_lookup: ::std::option::Option<\n        unsafe extern \"C\" fn(\n            v: *mut ::std::os::raw::c_void,\n            mask: *mut ::std::os::raw::c_void,\n            head: *mut radix_node_head,\n        ) -> *mut radix_node,\n    >,\n    pub rnh_lookup_args: ::std::option::Option<\n        unsafe extern \"C\" fn(\n            v: *mut ::std::os::raw::c_void,\n            mask: *mut ::std::os::raw::c_void,\n            head: *mut radix_node_head,\n            f: rn_matchf_t,\n            arg1: *mut ::std::os::raw::c_void,\n        ) -> *mut radix_node,\n    >,\n    pub rnh_matchpkt: ::std::option::Option<\n        unsafe extern \"C\" fn(v: *mut ::std::os::raw::c_void, head: *mut radix_node_head) -> *mut radix_node,\n    >,\n    pub rnh_walktree: ::std::option::Option<\n        unsafe extern \"C\" fn(\n            head: *mut radix_node_head,\n            f: walktree_f_t,\n            w: *mut ::std::os::raw::c_void,\n        ) -> ::std::os::raw::c_int,\n    >,\n    pub rnh_walktree_from: ::std::option::Option<\n        unsafe extern \"C\" fn(\n            head: *mut radix_node_head,\n            a: *mut ::std::os::raw::c_void,\n            m: *mut ::std::os::raw::c_void,\n            f: walktree_f_t,\n            w: *mut ::std::os::raw::c_void,\n        ) -> ::std::os::raw::c_int,\n    >,\n    pub rnh_close: ::std::option::Option<unsafe extern \"C\" fn(rn: *mut radix_node, head: *mut radix_node_head)>,\n    pub rnh_nodes: [radix_node; 3usize],\n    pub rnh_cnt: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_radix_node_head() {\n    const UNINIT: ::std::mem::MaybeUninit<radix_node_head> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<radix_node_head>(),\n        264usize,\n        concat!(\"Size of: \", stringify!(radix_node_head))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<radix_node_head>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(radix_node_head))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_treetop) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_treetop)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_addrsize) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_addrsize)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_pktsize) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_pktsize)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_addaddr) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_addaddr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_addpkt) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_addpkt)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_deladdr) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_deladdr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_delpkt) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_delpkt)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_matchaddr) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_matchaddr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_matchaddr_args) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_matchaddr_args)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_lookup) as usize - ptr as usize },\n        64usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_lookup)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_lookup_args) as usize - ptr as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_lookup_args)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_matchpkt) as usize - ptr as usize },\n        80usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_matchpkt)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_walktree) as usize - ptr as usize },\n        88usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_walktree)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_walktree_from) as usize - ptr as usize },\n        96usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_walktree_from)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_close) as usize - ptr as usize },\n        104usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_close)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_nodes) as usize - ptr as usize },\n        112usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_nodes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_cnt) as usize - ptr as usize },\n        256usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_cnt)\n        )\n    );\n}\nunsafe extern \"C\" {\n    pub fn rn_init();\n}\nunsafe extern \"C\" {\n    pub fn rn_inithead(arg1: *mut *mut ::std::os::raw::c_void, arg2: ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn rn_refines(arg1: *mut ::std::os::raw::c_void, arg2: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn rn_addmask(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: ::std::os::raw::c_int,\n        arg3: ::std::os::raw::c_int,\n    ) -> *mut radix_node;\n}\nunsafe extern \"C\" {\n    pub fn rn_addroute(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: *mut ::std::os::raw::c_void,\n        arg3: *mut radix_node_head,\n        arg4: *mut radix_node,\n    ) -> *mut radix_node;\n}\nunsafe extern \"C\" {\n    pub fn rn_delete(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: *mut ::std::os::raw::c_void,\n        arg3: *mut radix_node_head,\n    ) -> *mut radix_node;\n}\nunsafe extern \"C\" {\n    pub fn rn_lookup(\n        v_arg: *mut ::std::os::raw::c_void,\n        m_arg: *mut ::std::os::raw::c_void,\n        head: *mut radix_node_head,\n    ) -> *mut radix_node;\n}\nunsafe extern \"C\" {\n    pub fn rn_lookup_args(\n        v_arg: *mut ::std::os::raw::c_void,\n        m_arg: *mut ::std::os::raw::c_void,\n        head: *mut radix_node_head,\n        arg1: rn_matchf_t,\n        arg2: *mut ::std::os::raw::c_void,\n    ) -> *mut radix_node;\n}\nunsafe extern \"C\" {\n    pub fn rn_match(arg1: *mut ::std::os::raw::c_void, arg2: *mut radix_node_head) -> *mut radix_node;\n}\nunsafe extern \"C\" {\n    pub fn rn_match_args(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: *mut radix_node_head,\n        arg3: rn_matchf_t,\n        arg4: *mut ::std::os::raw::c_void,\n    ) -> *mut radix_node;\n}\npub type int_least8_t = i8;\npub type int_least16_t = i16;\npub type int_least32_t = i32;\npub type int_least64_t = i64;\npub type uint_least8_t = u8;\npub type uint_least16_t = u16;\npub type uint_least32_t = u32;\npub type uint_least64_t = u64;\npub type int_fast8_t = i8;\npub type int_fast16_t = i16;\npub type int_fast32_t = i32;\npub type int_fast64_t = i64;\npub type uint_fast8_t = u8;\npub type uint_fast16_t = u16;\npub type uint_fast32_t = u32;\npub type uint_fast64_t = u64;\npub type intmax_t = ::std::os::raw::c_long;\npub type uintmax_t = ::std::os::raw::c_ulong;\npub type uuid_t = __darwin_uuid_t;\npub type uuid_string_t = __darwin_uuid_string_t;\nunsafe extern \"C\" {\n    pub static UUID_NULL: uuid_t;\n}\nunsafe extern \"C\" {\n    pub fn uuid_clear(uu: *mut ::std::os::raw::c_uchar);\n}\nunsafe extern \"C\" {\n    pub fn uuid_compare(uu1: *mut ::std::os::raw::c_uchar, uu2: *mut ::std::os::raw::c_uchar) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn uuid_copy(dst: *mut ::std::os::raw::c_uchar, src: *mut ::std::os::raw::c_uchar);\n}\nunsafe extern \"C\" {\n    pub fn uuid_generate(out: *mut ::std::os::raw::c_uchar);\n}\nunsafe extern \"C\" {\n    pub fn uuid_generate_random(out: *mut ::std::os::raw::c_uchar);\n}\nunsafe extern \"C\" {\n    pub fn uuid_generate_time(out: *mut ::std::os::raw::c_uchar);\n}\nunsafe extern \"C\" {\n    pub fn uuid_generate_early_random(out: *mut ::std::os::raw::c_uchar);\n}\nunsafe extern \"C\" {\n    pub fn uuid_is_null(uu: *mut ::std::os::raw::c_uchar) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn uuid_parse(in_: *mut ::std::os::raw::c_char, uu: *mut ::std::os::raw::c_uchar) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn uuid_unparse(uu: *mut ::std::os::raw::c_uchar, out: *mut ::std::os::raw::c_char);\n}\nunsafe extern \"C\" {\n    pub fn uuid_unparse_lower(uu: *mut ::std::os::raw::c_uchar, out: *mut ::std::os::raw::c_char);\n}\nunsafe extern \"C\" {\n    pub fn uuid_unparse_upper(uu: *mut ::std::os::raw::c_uchar, out: *mut ::std::os::raw::c_char);\n}\npub type sa_family_t = __uint8_t;\npub type socklen_t = __darwin_socklen_t;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct iovec {\n    pub iov_base: *mut ::std::os::raw::c_void,\n    pub iov_len: usize,\n}\n#[test]\nfn bindgen_test_layout_iovec() {\n    const UNINIT: ::std::mem::MaybeUninit<iovec> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<iovec>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(iovec))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<iovec>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(iovec))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).iov_base) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(iovec), \"::\", stringify!(iov_base))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).iov_len) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(iovec), \"::\", stringify!(iov_len))\n    );\n}\nunsafe extern \"C\" {\n    pub static sotc_by_netservicetype: [::std::os::raw::c_int; 9usize];\n}\npub type sae_associd_t = __uint32_t;\npub type sae_connid_t = __uint32_t;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sa_endpoints {\n    pub sae_srcif: ::std::os::raw::c_uint,\n    pub sae_srcaddr: *const sockaddr,\n    pub sae_srcaddrlen: socklen_t,\n    pub sae_dstaddr: *const sockaddr,\n    pub sae_dstaddrlen: socklen_t,\n}\n#[test]\nfn bindgen_test_layout_sa_endpoints() {\n    const UNINIT: ::std::mem::MaybeUninit<sa_endpoints> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sa_endpoints>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(sa_endpoints))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sa_endpoints>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(sa_endpoints))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sae_srcif) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sa_endpoints),\n            \"::\",\n            stringify!(sae_srcif)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sae_srcaddr) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sa_endpoints),\n            \"::\",\n            stringify!(sae_srcaddr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sae_srcaddrlen) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sa_endpoints),\n            \"::\",\n            stringify!(sae_srcaddrlen)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sae_dstaddr) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sa_endpoints),\n            \"::\",\n            stringify!(sae_dstaddr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sae_dstaddrlen) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sa_endpoints),\n            \"::\",\n            stringify!(sae_dstaddrlen)\n        )\n    );\n}\npub type sa_endpoints_t = sa_endpoints;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct linger {\n    pub l_onoff: ::std::os::raw::c_int,\n    pub l_linger: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_linger() {\n    const UNINIT: ::std::mem::MaybeUninit<linger> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<linger>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(linger))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<linger>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(linger))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).l_onoff) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(linger), \"::\", stringify!(l_onoff))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).l_linger) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(linger), \"::\", stringify!(l_linger))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct so_np_extensions {\n    pub npx_flags: u_int32_t,\n    pub npx_mask: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_so_np_extensions() {\n    const UNINIT: ::std::mem::MaybeUninit<so_np_extensions> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<so_np_extensions>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(so_np_extensions))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<so_np_extensions>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(so_np_extensions))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).npx_flags) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(so_np_extensions),\n            \"::\",\n            stringify!(npx_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).npx_mask) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(so_np_extensions),\n            \"::\",\n            stringify!(npx_mask)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sockaddr {\n    pub sa_len: __uint8_t,\n    pub sa_family: sa_family_t,\n    pub sa_data: [::std::os::raw::c_char; 14usize],\n}\n#[test]\nfn bindgen_test_layout_sockaddr() {\n    const UNINIT: ::std::mem::MaybeUninit<sockaddr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sockaddr>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(sockaddr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sockaddr>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(sockaddr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sa_len) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr), \"::\", stringify!(sa_len))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sa_family) as usize - ptr as usize },\n        1usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr), \"::\", stringify!(sa_family))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sa_data) as usize - ptr as usize },\n        2usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr), \"::\", stringify!(sa_data))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sockproto {\n    pub sp_family: __uint16_t,\n    pub sp_protocol: __uint16_t,\n}\n#[test]\nfn bindgen_test_layout_sockproto() {\n    const UNINIT: ::std::mem::MaybeUninit<sockproto> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sockproto>(),\n        4usize,\n        concat!(\"Size of: \", stringify!(sockproto))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sockproto>(),\n        2usize,\n        concat!(\"Alignment of \", stringify!(sockproto))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sp_family) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sockproto), \"::\", stringify!(sp_family))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sp_protocol) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockproto),\n            \"::\",\n            stringify!(sp_protocol)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sockaddr_storage {\n    pub ss_len: __uint8_t,\n    pub ss_family: sa_family_t,\n    pub __ss_pad1: [::std::os::raw::c_char; 6usize],\n    pub __ss_align: __int64_t,\n    pub __ss_pad2: [::std::os::raw::c_char; 112usize],\n}\n#[test]\nfn bindgen_test_layout_sockaddr_storage() {\n    const UNINIT: ::std::mem::MaybeUninit<sockaddr_storage> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sockaddr_storage>(),\n        128usize,\n        concat!(\"Size of: \", stringify!(sockaddr_storage))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sockaddr_storage>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(sockaddr_storage))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ss_len) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_storage),\n            \"::\",\n            stringify!(ss_len)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ss_family) as usize - ptr as usize },\n        1usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_storage),\n            \"::\",\n            stringify!(ss_family)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ss_pad1) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_storage),\n            \"::\",\n            stringify!(__ss_pad1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ss_align) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_storage),\n            \"::\",\n            stringify!(__ss_align)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ss_pad2) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_storage),\n            \"::\",\n            stringify!(__ss_pad2)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct msghdr {\n    pub msg_name: *mut ::std::os::raw::c_void,\n    pub msg_namelen: socklen_t,\n    pub msg_iov: *mut iovec,\n    pub msg_iovlen: ::std::os::raw::c_int,\n    pub msg_control: *mut ::std::os::raw::c_void,\n    pub msg_controllen: socklen_t,\n    pub msg_flags: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_msghdr() {\n    const UNINIT: ::std::mem::MaybeUninit<msghdr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<msghdr>(),\n        48usize,\n        concat!(\"Size of: \", stringify!(msghdr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<msghdr>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(msghdr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_name) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(msghdr), \"::\", stringify!(msg_name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_namelen) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(msghdr), \"::\", stringify!(msg_namelen))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_iov) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(msghdr), \"::\", stringify!(msg_iov))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_iovlen) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(msghdr), \"::\", stringify!(msg_iovlen))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_control) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(msghdr), \"::\", stringify!(msg_control))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_controllen) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(msghdr),\n            \"::\",\n            stringify!(msg_controllen)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_flags) as usize - ptr as usize },\n        44usize,\n        concat!(\"Offset of field: \", stringify!(msghdr), \"::\", stringify!(msg_flags))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct msghdr_x {\n    pub msg_name: *mut ::std::os::raw::c_void,\n    pub msg_namelen: socklen_t,\n    pub msg_iov: *mut iovec,\n    pub msg_iovlen: ::std::os::raw::c_int,\n    pub msg_control: *mut ::std::os::raw::c_void,\n    pub msg_controllen: socklen_t,\n    pub msg_flags: ::std::os::raw::c_int,\n    pub msg_datalen: usize,\n}\n#[test]\nfn bindgen_test_layout_msghdr_x() {\n    const UNINIT: ::std::mem::MaybeUninit<msghdr_x> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<msghdr_x>(),\n        56usize,\n        concat!(\"Size of: \", stringify!(msghdr_x))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<msghdr_x>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(msghdr_x))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_name) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(msghdr_x), \"::\", stringify!(msg_name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_namelen) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(msghdr_x), \"::\", stringify!(msg_namelen))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_iov) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(msghdr_x), \"::\", stringify!(msg_iov))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_iovlen) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(msghdr_x), \"::\", stringify!(msg_iovlen))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_control) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(msghdr_x), \"::\", stringify!(msg_control))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_controllen) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(msghdr_x),\n            \"::\",\n            stringify!(msg_controllen)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_flags) as usize - ptr as usize },\n        44usize,\n        concat!(\"Offset of field: \", stringify!(msghdr_x), \"::\", stringify!(msg_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_datalen) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(msghdr_x), \"::\", stringify!(msg_datalen))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct cmsghdr {\n    pub cmsg_len: socklen_t,\n    pub cmsg_level: ::std::os::raw::c_int,\n    pub cmsg_type: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_cmsghdr() {\n    const UNINIT: ::std::mem::MaybeUninit<cmsghdr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<cmsghdr>(),\n        12usize,\n        concat!(\"Size of: \", stringify!(cmsghdr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<cmsghdr>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(cmsghdr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cmsg_len) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(cmsghdr), \"::\", stringify!(cmsg_len))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cmsg_level) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(cmsghdr), \"::\", stringify!(cmsg_level))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cmsg_type) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(cmsghdr), \"::\", stringify!(cmsg_type))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sf_hdtr {\n    pub headers: *mut iovec,\n    pub hdr_cnt: ::std::os::raw::c_int,\n    pub trailers: *mut iovec,\n    pub trl_cnt: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_sf_hdtr() {\n    const UNINIT: ::std::mem::MaybeUninit<sf_hdtr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sf_hdtr>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(sf_hdtr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sf_hdtr>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(sf_hdtr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).headers) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sf_hdtr), \"::\", stringify!(headers))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).hdr_cnt) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(sf_hdtr), \"::\", stringify!(hdr_cnt))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).trailers) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(sf_hdtr), \"::\", stringify!(trailers))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).trl_cnt) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(sf_hdtr), \"::\", stringify!(trl_cnt))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct so_aidreq {\n    pub sar_cnt: __uint32_t,\n    pub sar_aidp: *mut sae_associd_t,\n}\n#[test]\nfn bindgen_test_layout_so_aidreq() {\n    const UNINIT: ::std::mem::MaybeUninit<so_aidreq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<so_aidreq>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(so_aidreq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<so_aidreq>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(so_aidreq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sar_cnt) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(so_aidreq), \"::\", stringify!(sar_cnt))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sar_aidp) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(so_aidreq), \"::\", stringify!(sar_aidp))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct so_cidreq {\n    pub scr_aid: sae_associd_t,\n    pub scr_cnt: __uint32_t,\n    pub scr_cidp: *mut sae_connid_t,\n}\n#[test]\nfn bindgen_test_layout_so_cidreq() {\n    const UNINIT: ::std::mem::MaybeUninit<so_cidreq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<so_cidreq>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(so_cidreq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<so_cidreq>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(so_cidreq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scr_aid) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(so_cidreq), \"::\", stringify!(scr_aid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scr_cnt) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(so_cidreq), \"::\", stringify!(scr_cnt))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scr_cidp) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(so_cidreq), \"::\", stringify!(scr_cidp))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct so_cinforeq {\n    pub scir_cid: sae_connid_t,\n    pub scir_flags: __uint32_t,\n    pub scir_ifindex: __uint32_t,\n    pub scir_error: __int32_t,\n    pub scir_src: *mut sockaddr,\n    pub scir_src_len: socklen_t,\n    pub scir_dst: *mut sockaddr,\n    pub scir_dst_len: socklen_t,\n    pub scir_aux_type: __uint32_t,\n    pub scir_aux_data: *mut ::std::os::raw::c_void,\n    pub scir_aux_len: __uint32_t,\n}\n#[test]\nfn bindgen_test_layout_so_cinforeq() {\n    const UNINIT: ::std::mem::MaybeUninit<so_cinforeq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<so_cinforeq>(),\n        64usize,\n        concat!(\"Size of: \", stringify!(so_cinforeq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<so_cinforeq>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(so_cinforeq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scir_cid) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(so_cinforeq), \"::\", stringify!(scir_cid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scir_flags) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(so_cinforeq),\n            \"::\",\n            stringify!(scir_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scir_ifindex) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(so_cinforeq),\n            \"::\",\n            stringify!(scir_ifindex)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scir_error) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(so_cinforeq),\n            \"::\",\n            stringify!(scir_error)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scir_src) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(so_cinforeq), \"::\", stringify!(scir_src))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scir_src_len) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(so_cinforeq),\n            \"::\",\n            stringify!(scir_src_len)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scir_dst) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(so_cinforeq), \"::\", stringify!(scir_dst))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scir_dst_len) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(so_cinforeq),\n            \"::\",\n            stringify!(scir_dst_len)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scir_aux_type) as usize - ptr as usize },\n        44usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(so_cinforeq),\n            \"::\",\n            stringify!(scir_aux_type)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scir_aux_data) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(so_cinforeq),\n            \"::\",\n            stringify!(scir_aux_data)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scir_aux_len) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(so_cinforeq),\n            \"::\",\n            stringify!(scir_aux_len)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct so_cordreq {\n    pub sco_cid: sae_connid_t,\n    pub sco_rank: __uint32_t,\n}\n#[test]\nfn bindgen_test_layout_so_cordreq() {\n    const UNINIT: ::std::mem::MaybeUninit<so_cordreq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<so_cordreq>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(so_cordreq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<so_cordreq>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(so_cordreq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sco_cid) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(so_cordreq), \"::\", stringify!(sco_cid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sco_rank) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(so_cordreq), \"::\", stringify!(sco_rank))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct netpolicy_event_data {\n    pub eupid: __uint64_t,\n    pub epid: __uint64_t,\n    pub euuid: uuid_t,\n}\n#[test]\nfn bindgen_test_layout_netpolicy_event_data() {\n    const UNINIT: ::std::mem::MaybeUninit<netpolicy_event_data> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<netpolicy_event_data>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(netpolicy_event_data))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<netpolicy_event_data>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(netpolicy_event_data))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).eupid) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(netpolicy_event_data),\n            \"::\",\n            stringify!(eupid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).epid) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(netpolicy_event_data),\n            \"::\",\n            stringify!(epid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).euuid) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(netpolicy_event_data),\n            \"::\",\n            stringify!(euuid)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct kev_netpolicy_ifdenied {\n    pub ev_data: netpolicy_event_data,\n    pub ev_if_functional_type: __uint32_t,\n}\n#[test]\nfn bindgen_test_layout_kev_netpolicy_ifdenied() {\n    const UNINIT: ::std::mem::MaybeUninit<kev_netpolicy_ifdenied> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<kev_netpolicy_ifdenied>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(kev_netpolicy_ifdenied))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<kev_netpolicy_ifdenied>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(kev_netpolicy_ifdenied))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ev_data) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(kev_netpolicy_ifdenied),\n            \"::\",\n            stringify!(ev_data)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ev_if_functional_type) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(kev_netpolicy_ifdenied),\n            \"::\",\n            stringify!(ev_if_functional_type)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct kev_netpolicy_netdenied {\n    pub ev_data: netpolicy_event_data,\n    pub ev_network_type: __uint32_t,\n}\n#[test]\nfn bindgen_test_layout_kev_netpolicy_netdenied() {\n    const UNINIT: ::std::mem::MaybeUninit<kev_netpolicy_netdenied> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<kev_netpolicy_netdenied>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(kev_netpolicy_netdenied))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<kev_netpolicy_netdenied>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(kev_netpolicy_netdenied))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ev_data) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(kev_netpolicy_netdenied),\n            \"::\",\n            stringify!(ev_data)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ev_network_type) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(kev_netpolicy_netdenied),\n            \"::\",\n            stringify!(ev_network_type)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct netsvctype_dscp_map {\n    pub netsvctype: ::std::os::raw::c_int,\n    pub dscp: u_int8_t,\n}\n#[test]\nfn bindgen_test_layout_netsvctype_dscp_map() {\n    const UNINIT: ::std::mem::MaybeUninit<netsvctype_dscp_map> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<netsvctype_dscp_map>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(netsvctype_dscp_map))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<netsvctype_dscp_map>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(netsvctype_dscp_map))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).netsvctype) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(netsvctype_dscp_map),\n            \"::\",\n            stringify!(netsvctype)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dscp) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(netsvctype_dscp_map),\n            \"::\",\n            stringify!(dscp)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct so_mpkl_send_info {\n    pub mpkl_uuid: uuid_t,\n    pub mpkl_proto: __uint8_t,\n}\n#[test]\nfn bindgen_test_layout_so_mpkl_send_info() {\n    const UNINIT: ::std::mem::MaybeUninit<so_mpkl_send_info> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<so_mpkl_send_info>(),\n        17usize,\n        concat!(\"Size of: \", stringify!(so_mpkl_send_info))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<so_mpkl_send_info>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(so_mpkl_send_info))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mpkl_uuid) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(so_mpkl_send_info),\n            \"::\",\n            stringify!(mpkl_uuid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mpkl_proto) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(so_mpkl_send_info),\n            \"::\",\n            stringify!(mpkl_proto)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct so_mpkl_recv_info {\n    pub mpkl_seq: __uint32_t,\n    pub mpkl_proto: __uint8_t,\n}\n#[test]\nfn bindgen_test_layout_so_mpkl_recv_info() {\n    const UNINIT: ::std::mem::MaybeUninit<so_mpkl_recv_info> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<so_mpkl_recv_info>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(so_mpkl_recv_info))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<so_mpkl_recv_info>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(so_mpkl_recv_info))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mpkl_seq) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(so_mpkl_recv_info),\n            \"::\",\n            stringify!(mpkl_seq)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mpkl_proto) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(so_mpkl_recv_info),\n            \"::\",\n            stringify!(mpkl_proto)\n        )\n    );\n}\nunsafe extern \"C\" {\n    pub fn peeloff(s: ::std::os::raw::c_int, arg1: sae_associd_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn socket_delegate(\n        arg1: ::std::os::raw::c_int,\n        arg2: ::std::os::raw::c_int,\n        arg3: ::std::os::raw::c_int,\n        arg4: pid_t,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn recvmsg_x(\n        s: ::std::os::raw::c_int,\n        msgp: *const msghdr_x,\n        cnt: u_int,\n        flags: ::std::os::raw::c_int,\n    ) -> isize;\n}\nunsafe extern \"C\" {\n    pub fn sendmsg_x(\n        s: ::std::os::raw::c_int,\n        msgp: *const msghdr_x,\n        cnt: u_int,\n        flags: ::std::os::raw::c_int,\n    ) -> isize;\n}\nunsafe extern \"C\" {\n    #[link_name = \"\\u{1}_accept$UNIX2003\"]\n    pub fn accept(arg1: ::std::os::raw::c_int, arg2: *mut sockaddr, arg3: *mut socklen_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    #[link_name = \"\\u{1}_bind$UNIX2003\"]\n    pub fn bind(arg1: ::std::os::raw::c_int, arg2: *const sockaddr, arg3: socklen_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    #[link_name = \"\\u{1}_connect$UNIX2003\"]\n    pub fn connect(arg1: ::std::os::raw::c_int, arg2: *const sockaddr, arg3: socklen_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    #[link_name = \"\\u{1}_getpeername$UNIX2003\"]\n    pub fn getpeername(arg1: ::std::os::raw::c_int, arg2: *mut sockaddr, arg3: *mut socklen_t)\n    -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    #[link_name = \"\\u{1}_getsockname$UNIX2003\"]\n    pub fn getsockname(arg1: ::std::os::raw::c_int, arg2: *mut sockaddr, arg3: *mut socklen_t)\n    -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn getsockopt(\n        arg1: ::std::os::raw::c_int,\n        arg2: ::std::os::raw::c_int,\n        arg3: ::std::os::raw::c_int,\n        arg4: *mut ::std::os::raw::c_void,\n        arg5: *mut socklen_t,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    #[link_name = \"\\u{1}_listen$UNIX2003\"]\n    pub fn listen(arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    #[link_name = \"\\u{1}_recv$UNIX2003\"]\n    pub fn recv(\n        arg1: ::std::os::raw::c_int,\n        arg2: *mut ::std::os::raw::c_void,\n        arg3: usize,\n        arg4: ::std::os::raw::c_int,\n    ) -> isize;\n}\nunsafe extern \"C\" {\n    #[link_name = \"\\u{1}_recvfrom$UNIX2003\"]\n    pub fn recvfrom(\n        arg1: ::std::os::raw::c_int,\n        arg2: *mut ::std::os::raw::c_void,\n        arg3: usize,\n        arg4: ::std::os::raw::c_int,\n        arg5: *mut sockaddr,\n        arg6: *mut socklen_t,\n    ) -> isize;\n}\nunsafe extern \"C\" {\n    #[link_name = \"\\u{1}_recvmsg$UNIX2003\"]\n    pub fn recvmsg(arg1: ::std::os::raw::c_int, arg2: *mut msghdr, arg3: ::std::os::raw::c_int) -> isize;\n}\nunsafe extern \"C\" {\n    #[link_name = \"\\u{1}_send$UNIX2003\"]\n    pub fn send(\n        arg1: ::std::os::raw::c_int,\n        arg2: *const ::std::os::raw::c_void,\n        arg3: usize,\n        arg4: ::std::os::raw::c_int,\n    ) -> isize;\n}\nunsafe extern \"C\" {\n    #[link_name = \"\\u{1}_sendmsg$UNIX2003\"]\n    pub fn sendmsg(arg1: ::std::os::raw::c_int, arg2: *const msghdr, arg3: ::std::os::raw::c_int) -> isize;\n}\nunsafe extern \"C\" {\n    #[link_name = \"\\u{1}_sendto$UNIX2003\"]\n    pub fn sendto(\n        arg1: ::std::os::raw::c_int,\n        arg2: *const ::std::os::raw::c_void,\n        arg3: usize,\n        arg4: ::std::os::raw::c_int,\n        arg5: *const sockaddr,\n        arg6: socklen_t,\n    ) -> isize;\n}\nunsafe extern \"C\" {\n    pub fn setsockopt(\n        arg1: ::std::os::raw::c_int,\n        arg2: ::std::os::raw::c_int,\n        arg3: ::std::os::raw::c_int,\n        arg4: *const ::std::os::raw::c_void,\n        arg5: socklen_t,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn shutdown(arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn sockatmark(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn socket(\n        arg1: ::std::os::raw::c_int,\n        arg2: ::std::os::raw::c_int,\n        arg3: ::std::os::raw::c_int,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    #[link_name = \"\\u{1}_socketpair$UNIX2003\"]\n    pub fn socketpair(\n        arg1: ::std::os::raw::c_int,\n        arg2: ::std::os::raw::c_int,\n        arg3: ::std::os::raw::c_int,\n        arg4: *mut ::std::os::raw::c_int,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn sendfile(\n        arg1: ::std::os::raw::c_int,\n        arg2: ::std::os::raw::c_int,\n        arg3: off_t,\n        arg4: *mut off_t,\n        arg5: *mut sf_hdtr,\n        arg6: ::std::os::raw::c_int,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn pfctlinput(arg1: ::std::os::raw::c_int, arg2: *mut sockaddr);\n}\nunsafe extern \"C\" {\n    pub fn connectx(\n        arg1: ::std::os::raw::c_int,\n        arg2: *const sa_endpoints_t,\n        arg3: sae_associd_t,\n        arg4: ::std::os::raw::c_uint,\n        arg5: *const iovec,\n        arg6: ::std::os::raw::c_uint,\n        arg7: *mut usize,\n        arg8: *mut sae_connid_t,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn disconnectx(arg1: ::std::os::raw::c_int, arg2: sae_associd_t, arg3: sae_connid_t) -> ::std::os::raw::c_int;\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct in_addr {\n    pub s_addr: in_addr_t,\n}\n#[test]\nfn bindgen_test_layout_in_addr() {\n    const UNINIT: ::std::mem::MaybeUninit<in_addr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<in_addr>(),\n        4usize,\n        concat!(\"Size of: \", stringify!(in_addr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<in_addr>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(in_addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).s_addr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(in_addr), \"::\", stringify!(s_addr))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sockaddr_in {\n    pub sin_len: __uint8_t,\n    pub sin_family: sa_family_t,\n    pub sin_port: in_port_t,\n    pub sin_addr: in_addr,\n    pub sin_zero: [::std::os::raw::c_char; 8usize],\n}\n#[test]\nfn bindgen_test_layout_sockaddr_in() {\n    const UNINIT: ::std::mem::MaybeUninit<sockaddr_in> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sockaddr_in>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(sockaddr_in))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sockaddr_in>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(sockaddr_in))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin_len) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr_in), \"::\", stringify!(sin_len))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin_family) as usize - ptr as usize },\n        1usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_in),\n            \"::\",\n            stringify!(sin_family)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin_port) as usize - ptr as usize },\n        2usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr_in), \"::\", stringify!(sin_port))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin_addr) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr_in), \"::\", stringify!(sin_addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin_zero) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr_in), \"::\", stringify!(sin_zero))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct sockaddr_inifscope {\n    pub sin_len: __uint8_t,\n    pub sin_family: sa_family_t,\n    pub sin_port: in_port_t,\n    pub sin_addr: in_addr,\n    pub un: sockaddr_inifscope__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union sockaddr_inifscope__bindgen_ty_1 {\n    pub sin_zero: [::std::os::raw::c_char; 8usize],\n    pub _in_index: sockaddr_inifscope__bindgen_ty_1__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sockaddr_inifscope__bindgen_ty_1__bindgen_ty_1 {\n    pub ifscope: __uint32_t,\n}\n#[test]\nfn bindgen_test_layout_sockaddr_inifscope__bindgen_ty_1__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<sockaddr_inifscope__bindgen_ty_1__bindgen_ty_1> =\n        ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sockaddr_inifscope__bindgen_ty_1__bindgen_ty_1>(),\n        4usize,\n        concat!(\"Size of: \", stringify!(sockaddr_inifscope__bindgen_ty_1__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sockaddr_inifscope__bindgen_ty_1__bindgen_ty_1>(),\n        4usize,\n        concat!(\n            \"Alignment of \",\n            stringify!(sockaddr_inifscope__bindgen_ty_1__bindgen_ty_1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifscope) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_inifscope__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(ifscope)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_sockaddr_inifscope__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<sockaddr_inifscope__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sockaddr_inifscope__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(sockaddr_inifscope__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sockaddr_inifscope__bindgen_ty_1>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(sockaddr_inifscope__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin_zero) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_inifscope__bindgen_ty_1),\n            \"::\",\n            stringify!(sin_zero)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._in_index) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_inifscope__bindgen_ty_1),\n            \"::\",\n            stringify!(_in_index)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_sockaddr_inifscope() {\n    const UNINIT: ::std::mem::MaybeUninit<sockaddr_inifscope> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sockaddr_inifscope>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(sockaddr_inifscope))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sockaddr_inifscope>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(sockaddr_inifscope))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin_len) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_inifscope),\n            \"::\",\n            stringify!(sin_len)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin_family) as usize - ptr as usize },\n        1usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_inifscope),\n            \"::\",\n            stringify!(sin_family)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin_port) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_inifscope),\n            \"::\",\n            stringify!(sin_port)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin_addr) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_inifscope),\n            \"::\",\n            stringify!(sin_addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).un) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_inifscope),\n            \"::\",\n            stringify!(un)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ip_opts {\n    pub ip_dst: in_addr,\n    pub ip_opts: [::std::os::raw::c_char; 40usize],\n}\n#[test]\nfn bindgen_test_layout_ip_opts() {\n    const UNINIT: ::std::mem::MaybeUninit<ip_opts> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ip_opts>(),\n        44usize,\n        concat!(\"Size of: \", stringify!(ip_opts))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ip_opts>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(ip_opts))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ip_dst) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(ip_opts), \"::\", stringify!(ip_dst))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ip_opts) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(ip_opts), \"::\", stringify!(ip_opts))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ip_mreq {\n    pub imr_multiaddr: in_addr,\n    pub imr_interface: in_addr,\n}\n#[test]\nfn bindgen_test_layout_ip_mreq() {\n    const UNINIT: ::std::mem::MaybeUninit<ip_mreq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ip_mreq>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(ip_mreq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ip_mreq>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(ip_mreq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).imr_multiaddr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ip_mreq),\n            \"::\",\n            stringify!(imr_multiaddr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).imr_interface) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ip_mreq),\n            \"::\",\n            stringify!(imr_interface)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ip_mreqn {\n    pub imr_multiaddr: in_addr,\n    pub imr_address: in_addr,\n    pub imr_ifindex: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_ip_mreqn() {\n    const UNINIT: ::std::mem::MaybeUninit<ip_mreqn> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ip_mreqn>(),\n        12usize,\n        concat!(\"Size of: \", stringify!(ip_mreqn))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ip_mreqn>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(ip_mreqn))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).imr_multiaddr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ip_mreqn),\n            \"::\",\n            stringify!(imr_multiaddr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).imr_address) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(ip_mreqn), \"::\", stringify!(imr_address))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).imr_ifindex) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(ip_mreqn), \"::\", stringify!(imr_ifindex))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ip_mreq_source {\n    pub imr_multiaddr: in_addr,\n    pub imr_sourceaddr: in_addr,\n    pub imr_interface: in_addr,\n}\n#[test]\nfn bindgen_test_layout_ip_mreq_source() {\n    const UNINIT: ::std::mem::MaybeUninit<ip_mreq_source> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ip_mreq_source>(),\n        12usize,\n        concat!(\"Size of: \", stringify!(ip_mreq_source))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ip_mreq_source>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(ip_mreq_source))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).imr_multiaddr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ip_mreq_source),\n            \"::\",\n            stringify!(imr_multiaddr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).imr_sourceaddr) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ip_mreq_source),\n            \"::\",\n            stringify!(imr_sourceaddr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).imr_interface) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ip_mreq_source),\n            \"::\",\n            stringify!(imr_interface)\n        )\n    );\n}\n#[repr(C, packed(4))]\n#[derive(Debug, Copy, Clone)]\npub struct group_req {\n    pub gr_interface: u32,\n    pub gr_group: sockaddr_storage,\n}\n#[test]\nfn bindgen_test_layout_group_req() {\n    const UNINIT: ::std::mem::MaybeUninit<group_req> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<group_req>(),\n        132usize,\n        concat!(\"Size of: \", stringify!(group_req))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<group_req>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(group_req))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).gr_interface) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(group_req),\n            \"::\",\n            stringify!(gr_interface)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).gr_group) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(group_req), \"::\", stringify!(gr_group))\n    );\n}\n#[repr(C, packed(4))]\n#[derive(Debug, Copy, Clone)]\npub struct group_source_req {\n    pub gsr_interface: u32,\n    pub gsr_group: sockaddr_storage,\n    pub gsr_source: sockaddr_storage,\n}\n#[test]\nfn bindgen_test_layout_group_source_req() {\n    const UNINIT: ::std::mem::MaybeUninit<group_source_req> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<group_source_req>(),\n        260usize,\n        concat!(\"Size of: \", stringify!(group_source_req))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<group_source_req>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(group_source_req))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).gsr_interface) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(group_source_req),\n            \"::\",\n            stringify!(gsr_interface)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).gsr_group) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(group_source_req),\n            \"::\",\n            stringify!(gsr_group)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).gsr_source) as usize - ptr as usize },\n        132usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(group_source_req),\n            \"::\",\n            stringify!(gsr_source)\n        )\n    );\n}\n#[repr(C, packed(4))]\n#[derive(Debug, Copy, Clone)]\npub struct __msfilterreq {\n    pub msfr_ifindex: u32,\n    pub msfr_fmode: u32,\n    pub msfr_nsrcs: u32,\n    pub __msfr_align: u32,\n    pub msfr_group: sockaddr_storage,\n    pub msfr_srcs: *mut sockaddr_storage,\n}\n#[test]\nfn bindgen_test_layout___msfilterreq() {\n    const UNINIT: ::std::mem::MaybeUninit<__msfilterreq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__msfilterreq>(),\n        152usize,\n        concat!(\"Size of: \", stringify!(__msfilterreq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__msfilterreq>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(__msfilterreq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msfr_ifindex) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__msfilterreq),\n            \"::\",\n            stringify!(msfr_ifindex)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msfr_fmode) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__msfilterreq),\n            \"::\",\n            stringify!(msfr_fmode)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msfr_nsrcs) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__msfilterreq),\n            \"::\",\n            stringify!(msfr_nsrcs)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__msfr_align) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__msfilterreq),\n            \"::\",\n            stringify!(__msfr_align)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msfr_group) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__msfilterreq),\n            \"::\",\n            stringify!(msfr_group)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msfr_srcs) as usize - ptr as usize },\n        144usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__msfilterreq),\n            \"::\",\n            stringify!(msfr_srcs)\n        )\n    );\n}\nunsafe extern \"C\" {\n    pub fn setipv4sourcefilter(\n        arg1: ::std::os::raw::c_int,\n        arg2: in_addr,\n        arg3: in_addr,\n        arg4: u32,\n        arg5: u32,\n        arg6: *mut in_addr,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn getipv4sourcefilter(\n        arg1: ::std::os::raw::c_int,\n        arg2: in_addr,\n        arg3: in_addr,\n        arg4: *mut u32,\n        arg5: *mut u32,\n        arg6: *mut in_addr,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn setsourcefilter(\n        arg1: ::std::os::raw::c_int,\n        arg2: u32,\n        arg3: *mut sockaddr,\n        arg4: socklen_t,\n        arg5: u32,\n        arg6: u32,\n        arg7: *mut sockaddr_storage,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn getsourcefilter(\n        arg1: ::std::os::raw::c_int,\n        arg2: u32,\n        arg3: *mut sockaddr,\n        arg4: socklen_t,\n        arg5: *mut u32,\n        arg6: *mut u32,\n        arg7: *mut sockaddr_storage,\n    ) -> ::std::os::raw::c_int;\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct in_pktinfo {\n    pub ipi_ifindex: ::std::os::raw::c_uint,\n    pub ipi_spec_dst: in_addr,\n    pub ipi_addr: in_addr,\n}\n#[test]\nfn bindgen_test_layout_in_pktinfo() {\n    const UNINIT: ::std::mem::MaybeUninit<in_pktinfo> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<in_pktinfo>(),\n        12usize,\n        concat!(\"Size of: \", stringify!(in_pktinfo))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<in_pktinfo>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(in_pktinfo))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ipi_ifindex) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(in_pktinfo),\n            \"::\",\n            stringify!(ipi_ifindex)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ipi_spec_dst) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(in_pktinfo),\n            \"::\",\n            stringify!(ipi_spec_dst)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ipi_addr) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(in_pktinfo), \"::\", stringify!(ipi_addr))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct in6_addr {\n    pub __u6_addr: in6_addr__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union in6_addr__bindgen_ty_1 {\n    pub __u6_addr8: [__uint8_t; 16usize],\n    pub __u6_addr16: [__uint16_t; 8usize],\n    pub __u6_addr32: [__uint32_t; 4usize],\n}\n#[test]\nfn bindgen_test_layout_in6_addr__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<in6_addr__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<in6_addr__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(in6_addr__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<in6_addr__bindgen_ty_1>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(in6_addr__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__u6_addr8) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(in6_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(__u6_addr8)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__u6_addr16) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(in6_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(__u6_addr16)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__u6_addr32) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(in6_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(__u6_addr32)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_in6_addr() {\n    const UNINIT: ::std::mem::MaybeUninit<in6_addr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<in6_addr>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(in6_addr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<in6_addr>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(in6_addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__u6_addr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(in6_addr), \"::\", stringify!(__u6_addr))\n    );\n}\npub type in6_addr_t = in6_addr;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct sockaddr_in6 {\n    pub sin6_len: __uint8_t,\n    pub sin6_family: sa_family_t,\n    pub sin6_port: in_port_t,\n    pub sin6_flowinfo: __uint32_t,\n    pub sin6_addr: in6_addr,\n    pub sin6_scope_id: __uint32_t,\n}\n#[test]\nfn bindgen_test_layout_sockaddr_in6() {\n    const UNINIT: ::std::mem::MaybeUninit<sockaddr_in6> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sockaddr_in6>(),\n        28usize,\n        concat!(\"Size of: \", stringify!(sockaddr_in6))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sockaddr_in6>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(sockaddr_in6))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin6_len) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_in6),\n            \"::\",\n            stringify!(sin6_len)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin6_family) as usize - ptr as usize },\n        1usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_in6),\n            \"::\",\n            stringify!(sin6_family)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin6_port) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_in6),\n            \"::\",\n            stringify!(sin6_port)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin6_flowinfo) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_in6),\n            \"::\",\n            stringify!(sin6_flowinfo)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin6_addr) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_in6),\n            \"::\",\n            stringify!(sin6_addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin6_scope_id) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_in6),\n            \"::\",\n            stringify!(sin6_scope_id)\n        )\n    );\n}\nunsafe extern \"C\" {\n    pub static in6addr_any: in6_addr;\n}\nunsafe extern \"C\" {\n    pub static in6addr_loopback: in6_addr;\n}\nunsafe extern \"C\" {\n    pub static in6addr_nodelocal_allnodes: in6_addr;\n}\nunsafe extern \"C\" {\n    pub static in6addr_linklocal_allnodes: in6_addr;\n}\nunsafe extern \"C\" {\n    pub static in6addr_linklocal_allrouters: in6_addr;\n}\nunsafe extern \"C\" {\n    pub static in6addr_linklocal_allv2routers: in6_addr;\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct route_in6_old {\n    pub ro_rt: *mut ::std::os::raw::c_void,\n    pub ro_flags: u32,\n    pub ro_dst: sockaddr_in6,\n}\n#[test]\nfn bindgen_test_layout_route_in6_old() {\n    const UNINIT: ::std::mem::MaybeUninit<route_in6_old> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<route_in6_old>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(route_in6_old))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<route_in6_old>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(route_in6_old))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ro_rt) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(route_in6_old), \"::\", stringify!(ro_rt))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ro_flags) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(route_in6_old),\n            \"::\",\n            stringify!(ro_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ro_dst) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(route_in6_old), \"::\", stringify!(ro_dst))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct ipv6_mreq {\n    pub ipv6mr_multiaddr: in6_addr,\n    pub ipv6mr_interface: ::std::os::raw::c_uint,\n}\n#[test]\nfn bindgen_test_layout_ipv6_mreq() {\n    const UNINIT: ::std::mem::MaybeUninit<ipv6_mreq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ipv6_mreq>(),\n        20usize,\n        concat!(\"Size of: \", stringify!(ipv6_mreq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ipv6_mreq>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(ipv6_mreq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ipv6mr_multiaddr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ipv6_mreq),\n            \"::\",\n            stringify!(ipv6mr_multiaddr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ipv6mr_interface) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ipv6_mreq),\n            \"::\",\n            stringify!(ipv6mr_interface)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct in6_pktinfo {\n    pub ipi6_addr: in6_addr,\n    pub ipi6_ifindex: ::std::os::raw::c_uint,\n}\n#[test]\nfn bindgen_test_layout_in6_pktinfo() {\n    const UNINIT: ::std::mem::MaybeUninit<in6_pktinfo> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<in6_pktinfo>(),\n        20usize,\n        concat!(\"Size of: \", stringify!(in6_pktinfo))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<in6_pktinfo>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(in6_pktinfo))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ipi6_addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(in6_pktinfo),\n            \"::\",\n            stringify!(ipi6_addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ipi6_ifindex) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(in6_pktinfo),\n            \"::\",\n            stringify!(ipi6_ifindex)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct ip6_mtuinfo {\n    pub ip6m_addr: sockaddr_in6,\n    pub ip6m_mtu: u32,\n}\n#[test]\nfn bindgen_test_layout_ip6_mtuinfo() {\n    const UNINIT: ::std::mem::MaybeUninit<ip6_mtuinfo> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ip6_mtuinfo>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(ip6_mtuinfo))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ip6_mtuinfo>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(ip6_mtuinfo))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ip6m_addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ip6_mtuinfo),\n            \"::\",\n            stringify!(ip6m_addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ip6m_mtu) as usize - ptr as usize },\n        28usize,\n        concat!(\"Offset of field: \", stringify!(ip6_mtuinfo), \"::\", stringify!(ip6m_mtu))\n    );\n}\npub const in6_clat46_evhdlr_code_t_IN6_CLAT46_EVENT_V4_FLOW: in6_clat46_evhdlr_code_t = 0;\npub const in6_clat46_evhdlr_code_t_IN6_CLAT46_EVENT_V6_ADDR_CONFFAIL: in6_clat46_evhdlr_code_t = 1;\npub type in6_clat46_evhdlr_code_t = ::std::os::raw::c_uint;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct kev_netevent_clat46_data {\n    pub clat46_event_code: in6_clat46_evhdlr_code_t,\n    pub epid: pid_t,\n    pub euuid: uuid_t,\n}\n#[test]\nfn bindgen_test_layout_kev_netevent_clat46_data() {\n    const UNINIT: ::std::mem::MaybeUninit<kev_netevent_clat46_data> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<kev_netevent_clat46_data>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(kev_netevent_clat46_data))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<kev_netevent_clat46_data>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(kev_netevent_clat46_data))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).clat46_event_code) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(kev_netevent_clat46_data),\n            \"::\",\n            stringify!(clat46_event_code)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).epid) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(kev_netevent_clat46_data),\n            \"::\",\n            stringify!(epid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).euuid) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(kev_netevent_clat46_data),\n            \"::\",\n            stringify!(euuid)\n        )\n    );\n}\nunsafe extern \"C\" {\n    pub fn inet6_option_space(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_option_init(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: *mut *mut cmsghdr,\n        arg3: ::std::os::raw::c_int,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_option_append(\n        arg1: *mut cmsghdr,\n        arg2: *const __uint8_t,\n        arg3: ::std::os::raw::c_int,\n        arg4: ::std::os::raw::c_int,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_option_alloc(\n        arg1: *mut cmsghdr,\n        arg2: ::std::os::raw::c_int,\n        arg3: ::std::os::raw::c_int,\n        arg4: ::std::os::raw::c_int,\n    ) -> *mut __uint8_t;\n}\nunsafe extern \"C\" {\n    pub fn inet6_option_next(arg1: *const cmsghdr, arg2: *mut *mut __uint8_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_option_find(\n        arg1: *const cmsghdr,\n        arg2: *mut *mut __uint8_t,\n        arg3: ::std::os::raw::c_int,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rthdr_space(arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int) -> usize;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rthdr_init(arg1: *mut ::std::os::raw::c_void, arg2: ::std::os::raw::c_int) -> *mut cmsghdr;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rthdr_add(\n        arg1: *mut cmsghdr,\n        arg2: *const in6_addr,\n        arg3: ::std::os::raw::c_uint,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rthdr_lasthop(arg1: *mut cmsghdr, arg2: ::std::os::raw::c_uint) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rthdr_segments(arg1: *const cmsghdr) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rthdr_getaddr(arg1: *mut cmsghdr, arg2: ::std::os::raw::c_int) -> *mut in6_addr;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rthdr_getflags(arg1: *const cmsghdr, arg2: ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_opt_init(arg1: *mut ::std::os::raw::c_void, arg2: socklen_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_opt_append(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: socklen_t,\n        arg3: ::std::os::raw::c_int,\n        arg4: __uint8_t,\n        arg5: socklen_t,\n        arg6: __uint8_t,\n        arg7: *mut *mut ::std::os::raw::c_void,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_opt_finish(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: socklen_t,\n        arg3: ::std::os::raw::c_int,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_opt_set_val(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: ::std::os::raw::c_int,\n        arg3: *mut ::std::os::raw::c_void,\n        arg4: socklen_t,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_opt_next(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: socklen_t,\n        arg3: ::std::os::raw::c_int,\n        arg4: *mut __uint8_t,\n        arg5: *mut socklen_t,\n        arg6: *mut *mut ::std::os::raw::c_void,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_opt_find(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: socklen_t,\n        arg3: ::std::os::raw::c_int,\n        arg4: __uint8_t,\n        arg5: *mut socklen_t,\n        arg6: *mut *mut ::std::os::raw::c_void,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_opt_get_val(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: ::std::os::raw::c_int,\n        arg3: *mut ::std::os::raw::c_void,\n        arg4: socklen_t,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rth_space(arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int) -> socklen_t;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rth_init(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: socklen_t,\n        arg3: ::std::os::raw::c_int,\n        arg4: ::std::os::raw::c_int,\n    ) -> *mut ::std::os::raw::c_void;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rth_add(arg1: *mut ::std::os::raw::c_void, arg2: *const in6_addr) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rth_reverse(\n        arg1: *const ::std::os::raw::c_void,\n        arg2: *mut ::std::os::raw::c_void,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rth_segments(arg1: *const ::std::os::raw::c_void) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rth_getaddr(arg1: *const ::std::os::raw::c_void, arg2: ::std::os::raw::c_int) -> *mut in6_addr;\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union sockaddr_in_4_6 {\n    pub sa: sockaddr,\n    pub sin: sockaddr_in,\n    pub sin6: sockaddr_in6,\n}\n#[test]\nfn bindgen_test_layout_sockaddr_in_4_6() {\n    const UNINIT: ::std::mem::MaybeUninit<sockaddr_in_4_6> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sockaddr_in_4_6>(),\n        28usize,\n        concat!(\"Size of: \", stringify!(sockaddr_in_4_6))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sockaddr_in_4_6>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(sockaddr_in_4_6))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sa) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr_in_4_6), \"::\", stringify!(sa))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr_in_4_6), \"::\", stringify!(sin))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin6) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr_in_4_6), \"::\", stringify!(sin6))\n    );\n}\nunsafe extern \"C\" {\n    pub fn bindresvport(arg1: ::std::os::raw::c_int, arg2: *mut sockaddr_in) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn bindresvport_sa(arg1: ::std::os::raw::c_int, arg2: *mut sockaddr) -> ::std::os::raw::c_int;\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct timespec {\n    pub tv_sec: __darwin_time_t,\n    pub tv_nsec: ::std::os::raw::c_long,\n}\n#[test]\nfn bindgen_test_layout_timespec() {\n    const UNINIT: ::std::mem::MaybeUninit<timespec> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<timespec>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(timespec))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<timespec>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(timespec))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tv_sec) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(timespec), \"::\", stringify!(tv_sec))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tv_nsec) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(timespec), \"::\", stringify!(tv_nsec))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct timeval {\n    pub tv_sec: __darwin_time_t,\n    pub tv_usec: __darwin_suseconds_t,\n}\n#[test]\nfn bindgen_test_layout_timeval() {\n    const UNINIT: ::std::mem::MaybeUninit<timeval> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<timeval>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(timeval))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<timeval>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(timeval))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tv_sec) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(timeval), \"::\", stringify!(tv_sec))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tv_usec) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(timeval), \"::\", stringify!(tv_usec))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct timeval64 {\n    pub tv_sec: __int64_t,\n    pub tv_usec: __int64_t,\n}\n#[test]\nfn bindgen_test_layout_timeval64() {\n    const UNINIT: ::std::mem::MaybeUninit<timeval64> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<timeval64>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(timeval64))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<timeval64>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(timeval64))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tv_sec) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(timeval64), \"::\", stringify!(tv_sec))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tv_usec) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(timeval64), \"::\", stringify!(tv_usec))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct itimerval {\n    pub it_interval: timeval,\n    pub it_value: timeval,\n}\n#[test]\nfn bindgen_test_layout_itimerval() {\n    const UNINIT: ::std::mem::MaybeUninit<itimerval> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<itimerval>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(itimerval))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<itimerval>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(itimerval))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).it_interval) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(itimerval),\n            \"::\",\n            stringify!(it_interval)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).it_value) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(itimerval), \"::\", stringify!(it_value))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct timezone {\n    pub tz_minuteswest: ::std::os::raw::c_int,\n    pub tz_dsttime: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_timezone() {\n    const UNINIT: ::std::mem::MaybeUninit<timezone> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<timezone>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(timezone))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<timezone>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(timezone))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tz_minuteswest) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(timezone),\n            \"::\",\n            stringify!(tz_minuteswest)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tz_dsttime) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(timezone), \"::\", stringify!(tz_dsttime))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct clockinfo {\n    pub hz: ::std::os::raw::c_int,\n    pub tick: ::std::os::raw::c_int,\n    pub tickadj: ::std::os::raw::c_int,\n    pub stathz: ::std::os::raw::c_int,\n    pub profhz: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_clockinfo() {\n    const UNINIT: ::std::mem::MaybeUninit<clockinfo> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<clockinfo>(),\n        20usize,\n        concat!(\"Size of: \", stringify!(clockinfo))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<clockinfo>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(clockinfo))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).hz) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(clockinfo), \"::\", stringify!(hz))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tick) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(clockinfo), \"::\", stringify!(tick))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tickadj) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(clockinfo), \"::\", stringify!(tickadj))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).stathz) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(clockinfo), \"::\", stringify!(stathz))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).profhz) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(clockinfo), \"::\", stringify!(profhz))\n    );\n}\npub type __darwin_nl_item = ::std::os::raw::c_int;\npub type __darwin_wctrans_t = ::std::os::raw::c_int;\npub type __darwin_wctype_t = __uint32_t;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct tm {\n    pub tm_sec: ::std::os::raw::c_int,\n    pub tm_min: ::std::os::raw::c_int,\n    pub tm_hour: ::std::os::raw::c_int,\n    pub tm_mday: ::std::os::raw::c_int,\n    pub tm_mon: ::std::os::raw::c_int,\n    pub tm_year: ::std::os::raw::c_int,\n    pub tm_wday: ::std::os::raw::c_int,\n    pub tm_yday: ::std::os::raw::c_int,\n    pub tm_isdst: ::std::os::raw::c_int,\n    pub tm_gmtoff: ::std::os::raw::c_long,\n    pub tm_zone: *mut ::std::os::raw::c_char,\n}\n#[test]\nfn bindgen_test_layout_tm() {\n    const UNINIT: ::std::mem::MaybeUninit<tm> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<tm>(),\n        56usize,\n        concat!(\"Size of: \", stringify!(tm))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<tm>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(tm))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_sec) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_sec))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_min) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_min))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_hour) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_hour))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_mday) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_mday))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_mon) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_mon))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_year) as usize - ptr as usize },\n        20usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_year))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_wday) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_wday))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_yday) as usize - ptr as usize },\n        28usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_yday))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_isdst) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_isdst))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_gmtoff) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_gmtoff))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_zone) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_zone))\n    );\n}\nunsafe extern \"C\" {\n    pub static mut tzname: [*mut ::std::os::raw::c_char; 0usize];\n}\nunsafe extern \"C\" {\n    pub static mut getdate_err: ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    #[link_name = \"\\u{1}_timezone$UNIX2003\"]\n    pub static mut timezone: ::std::os::raw::c_long;\n}\nunsafe extern \"C\" {\n    pub static mut daylight: ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn asctime(arg1: *const tm) -> *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    #[link_name = \"\\u{1}_clock$UNIX2003\"]\n    pub fn clock() -> clock_t;\n}\nunsafe extern \"C\" {\n    pub fn ctime(arg1: *const time_t) -> *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn difftime(arg1: time_t, arg2: time_t) -> f64;\n}\nunsafe extern \"C\" {\n    pub fn getdate(arg1: *const ::std::os::raw::c_char) -> *mut tm;\n}\nunsafe extern \"C\" {\n    pub fn gmtime(arg1: *const time_t) -> *mut tm;\n}\nunsafe extern \"C\" {\n    pub fn localtime(arg1: *const time_t) -> *mut tm;\n}\nunsafe extern \"C\" {\n    #[link_name = \"\\u{1}_mktime$UNIX2003\"]\n    pub fn mktime(arg1: *mut tm) -> time_t;\n}\nunsafe extern \"C\" {\n    #[link_name = \"\\u{1}_strftime$UNIX2003\"]\n    pub fn strftime(\n        arg1: *mut ::std::os::raw::c_char,\n        arg2: usize,\n        arg3: *const ::std::os::raw::c_char,\n        arg4: *const tm,\n    ) -> usize;\n}\nunsafe extern \"C\" {\n    #[link_name = \"\\u{1}_strptime$UNIX2003\"]\n    pub fn strptime(\n        arg1: *const ::std::os::raw::c_char,\n        arg2: *const ::std::os::raw::c_char,\n        arg3: *mut tm,\n    ) -> *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn time(arg1: *mut time_t) -> time_t;\n}\nunsafe extern \"C\" {\n    pub fn tzset();\n}\nunsafe extern \"C\" {\n    pub fn asctime_r(arg1: *const tm, arg2: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn ctime_r(arg1: *const time_t, arg2: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn gmtime_r(arg1: *const time_t, arg2: *mut tm) -> *mut tm;\n}\nunsafe extern \"C\" {\n    pub fn localtime_r(arg1: *const time_t, arg2: *mut tm) -> *mut tm;\n}\nunsafe extern \"C\" {\n    pub fn posix2time(arg1: time_t) -> time_t;\n}\nunsafe extern \"C\" {\n    pub fn tzsetwall();\n}\nunsafe extern \"C\" {\n    pub fn time2posix(arg1: time_t) -> time_t;\n}\nunsafe extern \"C\" {\n    pub fn timelocal(arg1: *mut tm) -> time_t;\n}\nunsafe extern \"C\" {\n    pub fn timegm(arg1: *mut tm) -> time_t;\n}\nunsafe extern \"C\" {\n    #[link_name = \"\\u{1}_nanosleep$UNIX2003\"]\n    pub fn nanosleep(__rqtp: *const timespec, __rmtp: *mut timespec) -> ::std::os::raw::c_int;\n}\npub const clockid_t__CLOCK_REALTIME: clockid_t = 0;\npub const clockid_t__CLOCK_MONOTONIC: clockid_t = 6;\npub const clockid_t__CLOCK_MONOTONIC_RAW: clockid_t = 4;\npub const clockid_t__CLOCK_MONOTONIC_RAW_APPROX: clockid_t = 5;\npub const clockid_t__CLOCK_UPTIME_RAW: clockid_t = 8;\npub const clockid_t__CLOCK_UPTIME_RAW_APPROX: clockid_t = 9;\npub const clockid_t__CLOCK_PROCESS_CPUTIME_ID: clockid_t = 12;\npub const clockid_t__CLOCK_THREAD_CPUTIME_ID: clockid_t = 16;\npub type clockid_t = ::std::os::raw::c_uint;\nunsafe extern \"C\" {\n    pub fn clock_getres(__clock_id: clockid_t, __res: *mut timespec) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn clock_gettime(__clock_id: clockid_t, __tp: *mut timespec) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn clock_gettime_nsec_np(__clock_id: clockid_t) -> __uint64_t;\n}\nunsafe extern \"C\" {\n    pub fn clock_settime(__clock_id: clockid_t, __tp: *const timespec) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn timespec_get(ts: *mut timespec, base: ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn adjtime(arg1: *const timeval, arg2: *mut timeval) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn futimes(arg1: ::std::os::raw::c_int, arg2: *const timeval) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn lutimes(arg1: *const ::std::os::raw::c_char, arg2: *const timeval) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn settimeofday(arg1: *const timeval, arg2: *const timezone) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn getitimer(arg1: ::std::os::raw::c_int, arg2: *mut itimerval) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn gettimeofday(arg1: *mut timeval, arg2: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    #[link_name = \"\\u{1}_select$1050\"]\n    pub fn select(\n        arg1: ::std::os::raw::c_int,\n        arg2: *mut fd_set,\n        arg3: *mut fd_set,\n        arg4: *mut fd_set,\n        arg5: *mut timeval,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn setitimer(\n        arg1: ::std::os::raw::c_int,\n        arg2: *const itimerval,\n        arg3: *mut itimerval,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn utimes(arg1: *const ::std::os::raw::c_char, arg2: *const timeval) -> ::std::os::raw::c_int;\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct rt_metrics {\n    pub rmx_locks: u_int32_t,\n    pub rmx_mtu: u_int32_t,\n    pub rmx_hopcount: u_int32_t,\n    pub rmx_expire: i32,\n    pub rmx_recvpipe: u_int32_t,\n    pub rmx_sendpipe: u_int32_t,\n    pub rmx_ssthresh: u_int32_t,\n    pub rmx_rtt: u_int32_t,\n    pub rmx_rttvar: u_int32_t,\n    pub rmx_pksent: u_int32_t,\n    pub rmx_state: u_int32_t,\n    pub rmx_filler: [u_int32_t; 3usize],\n}\n#[test]\nfn bindgen_test_layout_rt_metrics() {\n    const UNINIT: ::std::mem::MaybeUninit<rt_metrics> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<rt_metrics>(),\n        56usize,\n        concat!(\"Size of: \", stringify!(rt_metrics))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<rt_metrics>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(rt_metrics))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmx_locks) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(rt_metrics), \"::\", stringify!(rmx_locks))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmx_mtu) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(rt_metrics), \"::\", stringify!(rmx_mtu))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmx_hopcount) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_metrics),\n            \"::\",\n            stringify!(rmx_hopcount)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmx_expire) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_metrics),\n            \"::\",\n            stringify!(rmx_expire)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmx_recvpipe) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_metrics),\n            \"::\",\n            stringify!(rmx_recvpipe)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmx_sendpipe) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_metrics),\n            \"::\",\n            stringify!(rmx_sendpipe)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmx_ssthresh) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_metrics),\n            \"::\",\n            stringify!(rmx_ssthresh)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmx_rtt) as usize - ptr as usize },\n        28usize,\n        concat!(\"Offset of field: \", stringify!(rt_metrics), \"::\", stringify!(rmx_rtt))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmx_rttvar) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_metrics),\n            \"::\",\n            stringify!(rmx_rttvar)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmx_pksent) as usize - ptr as usize },\n        36usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_metrics),\n            \"::\",\n            stringify!(rmx_pksent)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmx_state) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(rt_metrics), \"::\", stringify!(rmx_state))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmx_filler) as usize - ptr as usize },\n        44usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_metrics),\n            \"::\",\n            stringify!(rmx_filler)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct route_old {\n    pub ro_rt: *mut ::std::os::raw::c_void,\n    pub ro_flags: u32,\n    pub ro_dst: sockaddr,\n}\n#[test]\nfn bindgen_test_layout_route_old() {\n    const UNINIT: ::std::mem::MaybeUninit<route_old> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<route_old>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(route_old))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<route_old>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(route_old))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ro_rt) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(route_old), \"::\", stringify!(ro_rt))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ro_flags) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(route_old), \"::\", stringify!(ro_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ro_dst) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(route_old), \"::\", stringify!(ro_dst))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct rtstat {\n    pub rts_badredirect: ::std::os::raw::c_short,\n    pub rts_dynamic: ::std::os::raw::c_short,\n    pub rts_newgateway: ::std::os::raw::c_short,\n    pub rts_unreach: ::std::os::raw::c_short,\n    pub rts_wildcard: ::std::os::raw::c_short,\n    pub rts_badrtgwroute: ::std::os::raw::c_short,\n}\n#[test]\nfn bindgen_test_layout_rtstat() {\n    const UNINIT: ::std::mem::MaybeUninit<rtstat> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<rtstat>(),\n        12usize,\n        concat!(\"Size of: \", stringify!(rtstat))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<rtstat>(),\n        2usize,\n        concat!(\"Alignment of \", stringify!(rtstat))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rts_badredirect) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rtstat),\n            \"::\",\n            stringify!(rts_badredirect)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rts_dynamic) as usize - ptr as usize },\n        2usize,\n        concat!(\"Offset of field: \", stringify!(rtstat), \"::\", stringify!(rts_dynamic))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rts_newgateway) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rtstat),\n            \"::\",\n            stringify!(rts_newgateway)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rts_unreach) as usize - ptr as usize },\n        6usize,\n        concat!(\"Offset of field: \", stringify!(rtstat), \"::\", stringify!(rts_unreach))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rts_wildcard) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(rtstat), \"::\", stringify!(rts_wildcard))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rts_badrtgwroute) as usize - ptr as usize },\n        10usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rtstat),\n            \"::\",\n            stringify!(rts_badrtgwroute)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct rt_msghdr {\n    pub rtm_msglen: u_short,\n    pub rtm_version: u_char,\n    pub rtm_type: u_char,\n    pub rtm_index: u_short,\n    pub rtm_flags: ::std::os::raw::c_int,\n    pub rtm_addrs: ::std::os::raw::c_int,\n    pub rtm_pid: pid_t,\n    pub rtm_seq: ::std::os::raw::c_int,\n    pub rtm_errno: ::std::os::raw::c_int,\n    pub rtm_use: ::std::os::raw::c_int,\n    pub rtm_inits: u_int32_t,\n    pub rtm_rmx: rt_metrics,\n}\n#[test]\nfn bindgen_test_layout_rt_msghdr() {\n    const UNINIT: ::std::mem::MaybeUninit<rt_msghdr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<rt_msghdr>(),\n        92usize,\n        concat!(\"Size of: \", stringify!(rt_msghdr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<rt_msghdr>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(rt_msghdr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_msglen) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr), \"::\", stringify!(rtm_msglen))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_version) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_msghdr),\n            \"::\",\n            stringify!(rtm_version)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_type) as usize - ptr as usize },\n        3usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr), \"::\", stringify!(rtm_type))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_index) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr), \"::\", stringify!(rtm_index))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_flags) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr), \"::\", stringify!(rtm_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_addrs) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr), \"::\", stringify!(rtm_addrs))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_pid) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr), \"::\", stringify!(rtm_pid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_seq) as usize - ptr as usize },\n        20usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr), \"::\", stringify!(rtm_seq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_errno) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr), \"::\", stringify!(rtm_errno))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_use) as usize - ptr as usize },\n        28usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr), \"::\", stringify!(rtm_use))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_inits) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr), \"::\", stringify!(rtm_inits))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_rmx) as usize - ptr as usize },\n        36usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr), \"::\", stringify!(rtm_rmx))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct rt_msghdr2 {\n    pub rtm_msglen: u_short,\n    pub rtm_version: u_char,\n    pub rtm_type: u_char,\n    pub rtm_index: u_short,\n    pub rtm_flags: ::std::os::raw::c_int,\n    pub rtm_addrs: ::std::os::raw::c_int,\n    pub rtm_refcnt: i32,\n    pub rtm_parentflags: ::std::os::raw::c_int,\n    pub rtm_reserved: ::std::os::raw::c_int,\n    pub rtm_use: ::std::os::raw::c_int,\n    pub rtm_inits: u_int32_t,\n    pub rtm_rmx: rt_metrics,\n}\n#[test]\nfn bindgen_test_layout_rt_msghdr2() {\n    const UNINIT: ::std::mem::MaybeUninit<rt_msghdr2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<rt_msghdr2>(),\n        92usize,\n        concat!(\"Size of: \", stringify!(rt_msghdr2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<rt_msghdr2>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(rt_msghdr2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_msglen) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_msghdr2),\n            \"::\",\n            stringify!(rtm_msglen)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_version) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_msghdr2),\n            \"::\",\n            stringify!(rtm_version)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_type) as usize - ptr as usize },\n        3usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr2), \"::\", stringify!(rtm_type))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_index) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr2), \"::\", stringify!(rtm_index))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_flags) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr2), \"::\", stringify!(rtm_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_addrs) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr2), \"::\", stringify!(rtm_addrs))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_refcnt) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_msghdr2),\n            \"::\",\n            stringify!(rtm_refcnt)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_parentflags) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_msghdr2),\n            \"::\",\n            stringify!(rtm_parentflags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_reserved) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_msghdr2),\n            \"::\",\n            stringify!(rtm_reserved)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_use) as usize - ptr as usize },\n        28usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr2), \"::\", stringify!(rtm_use))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_inits) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr2), \"::\", stringify!(rtm_inits))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_rmx) as usize - ptr as usize },\n        36usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr2), \"::\", stringify!(rtm_rmx))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct kev_netevent_apnfallbk_data {\n    pub epid: pid_t,\n    pub euuid: uuid_t,\n}\n#[test]\nfn bindgen_test_layout_kev_netevent_apnfallbk_data() {\n    const UNINIT: ::std::mem::MaybeUninit<kev_netevent_apnfallbk_data> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<kev_netevent_apnfallbk_data>(),\n        20usize,\n        concat!(\"Size of: \", stringify!(kev_netevent_apnfallbk_data))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<kev_netevent_apnfallbk_data>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(kev_netevent_apnfallbk_data))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).epid) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(kev_netevent_apnfallbk_data),\n            \"::\",\n            stringify!(epid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).euuid) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(kev_netevent_apnfallbk_data),\n            \"::\",\n            stringify!(euuid)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct rt_reach_info {\n    pub ri_refcnt: u_int32_t,\n    pub ri_probes: u_int32_t,\n    pub ri_snd_expire: u_int64_t,\n    pub ri_rcv_expire: u_int64_t,\n    pub ri_rssi: i32,\n    pub ri_lqm: i32,\n    pub ri_npm: i32,\n}\n#[test]\nfn bindgen_test_layout_rt_reach_info() {\n    const UNINIT: ::std::mem::MaybeUninit<rt_reach_info> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<rt_reach_info>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(rt_reach_info))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<rt_reach_info>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(rt_reach_info))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ri_refcnt) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_reach_info),\n            \"::\",\n            stringify!(ri_refcnt)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ri_probes) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_reach_info),\n            \"::\",\n            stringify!(ri_probes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ri_snd_expire) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_reach_info),\n            \"::\",\n            stringify!(ri_snd_expire)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ri_rcv_expire) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_reach_info),\n            \"::\",\n            stringify!(ri_rcv_expire)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ri_rssi) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_reach_info),\n            \"::\",\n            stringify!(ri_rssi)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ri_lqm) as usize - ptr as usize },\n        28usize,\n        concat!(\"Offset of field: \", stringify!(rt_reach_info), \"::\", stringify!(ri_lqm))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ri_npm) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(rt_reach_info), \"::\", stringify!(ri_npm))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct rt_msghdr_ext {\n    pub rtm_msglen: u_short,\n    pub rtm_version: u_char,\n    pub rtm_type: u_char,\n    pub rtm_index: u_int32_t,\n    pub rtm_flags: u_int32_t,\n    pub rtm_reserved: u_int32_t,\n    pub rtm_addrs: u_int32_t,\n    pub rtm_pid: pid_t,\n    pub rtm_seq: ::std::os::raw::c_int,\n    pub rtm_errno: ::std::os::raw::c_int,\n    pub rtm_use: u_int32_t,\n    pub rtm_inits: u_int32_t,\n    pub rtm_rmx: rt_metrics,\n    pub rtm_ri: rt_reach_info,\n}\n#[test]\nfn bindgen_test_layout_rt_msghdr_ext() {\n    const UNINIT: ::std::mem::MaybeUninit<rt_msghdr_ext> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<rt_msghdr_ext>(),\n        136usize,\n        concat!(\"Size of: \", stringify!(rt_msghdr_ext))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<rt_msghdr_ext>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(rt_msghdr_ext))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_msglen) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_msghdr_ext),\n            \"::\",\n            stringify!(rtm_msglen)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_version) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_msghdr_ext),\n            \"::\",\n            stringify!(rtm_version)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_type) as usize - ptr as usize },\n        3usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_msghdr_ext),\n            \"::\",\n            stringify!(rtm_type)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_index) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_msghdr_ext),\n            \"::\",\n            stringify!(rtm_index)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_flags) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_msghdr_ext),\n            \"::\",\n            stringify!(rtm_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_reserved) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_msghdr_ext),\n            \"::\",\n            stringify!(rtm_reserved)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_addrs) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_msghdr_ext),\n            \"::\",\n            stringify!(rtm_addrs)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_pid) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_msghdr_ext),\n            \"::\",\n            stringify!(rtm_pid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_seq) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_msghdr_ext),\n            \"::\",\n            stringify!(rtm_seq)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_errno) as usize - ptr as usize },\n        28usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_msghdr_ext),\n            \"::\",\n            stringify!(rtm_errno)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_use) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_msghdr_ext),\n            \"::\",\n            stringify!(rtm_use)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_inits) as usize - ptr as usize },\n        36usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_msghdr_ext),\n            \"::\",\n            stringify!(rtm_inits)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_rmx) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_msghdr_ext),\n            \"::\",\n            stringify!(rtm_rmx)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_ri) as usize - ptr as usize },\n        96usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr_ext), \"::\", stringify!(rtm_ri))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct rt_addrinfo {\n    pub rti_addrs: ::std::os::raw::c_int,\n    pub rti_info: [*mut sockaddr; 8usize],\n}\n#[test]\nfn bindgen_test_layout_rt_addrinfo() {\n    const UNINIT: ::std::mem::MaybeUninit<rt_addrinfo> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<rt_addrinfo>(),\n        72usize,\n        concat!(\"Size of: \", stringify!(rt_addrinfo))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<rt_addrinfo>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(rt_addrinfo))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rti_addrs) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_addrinfo),\n            \"::\",\n            stringify!(rti_addrs)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rti_info) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(rt_addrinfo), \"::\", stringify!(rti_info))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct net_event_data {\n    pub if_family: u_int32_t,\n    pub if_unit: u_int32_t,\n    pub if_name: [::std::os::raw::c_char; 16usize],\n}\n#[test]\nfn bindgen_test_layout_net_event_data() {\n    const UNINIT: ::std::mem::MaybeUninit<net_event_data> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<net_event_data>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(net_event_data))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<net_event_data>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(net_event_data))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).if_family) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(net_event_data),\n            \"::\",\n            stringify!(if_family)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).if_unit) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(net_event_data),\n            \"::\",\n            stringify!(if_unit)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).if_name) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(net_event_data),\n            \"::\",\n            stringify!(if_name)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct timeval32 {\n    pub tv_sec: __int32_t,\n    pub tv_usec: __int32_t,\n}\n#[test]\nfn bindgen_test_layout_timeval32() {\n    const UNINIT: ::std::mem::MaybeUninit<timeval32> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<timeval32>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(timeval32))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<timeval32>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(timeval32))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tv_sec) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(timeval32), \"::\", stringify!(tv_sec))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tv_usec) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(timeval32), \"::\", stringify!(tv_usec))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct if_data {\n    pub ifi_type: u_char,\n    pub ifi_typelen: u_char,\n    pub ifi_physical: u_char,\n    pub ifi_addrlen: u_char,\n    pub ifi_hdrlen: u_char,\n    pub ifi_recvquota: u_char,\n    pub ifi_xmitquota: u_char,\n    pub ifi_unused1: u_char,\n    pub ifi_mtu: u_int32_t,\n    pub ifi_metric: u_int32_t,\n    pub ifi_baudrate: u_int32_t,\n    pub ifi_ipackets: u_int32_t,\n    pub ifi_ierrors: u_int32_t,\n    pub ifi_opackets: u_int32_t,\n    pub ifi_oerrors: u_int32_t,\n    pub ifi_collisions: u_int32_t,\n    pub ifi_ibytes: u_int32_t,\n    pub ifi_obytes: u_int32_t,\n    pub ifi_imcasts: u_int32_t,\n    pub ifi_omcasts: u_int32_t,\n    pub ifi_iqdrops: u_int32_t,\n    pub ifi_noproto: u_int32_t,\n    pub ifi_recvtiming: u_int32_t,\n    pub ifi_xmittiming: u_int32_t,\n    pub ifi_lastchange: timeval32,\n    pub ifi_unused2: u_int32_t,\n    pub ifi_hwassist: u_int32_t,\n    pub ifi_reserved1: u_int32_t,\n    pub ifi_reserved2: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_if_data() {\n    const UNINIT: ::std::mem::MaybeUninit<if_data> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_data>(),\n        96usize,\n        concat!(\"Size of: \", stringify!(if_data))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_data>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(if_data))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_type) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_type))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_typelen) as usize - ptr as usize },\n        1usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_typelen))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_physical) as usize - ptr as usize },\n        2usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_physical))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_addrlen) as usize - ptr as usize },\n        3usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_addrlen))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_hdrlen) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_hdrlen))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_recvquota) as usize - ptr as usize },\n        5usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data),\n            \"::\",\n            stringify!(ifi_recvquota)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_xmitquota) as usize - ptr as usize },\n        6usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data),\n            \"::\",\n            stringify!(ifi_xmitquota)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_unused1) as usize - ptr as usize },\n        7usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_unused1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_mtu) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_mtu))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_metric) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_metric))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_baudrate) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_baudrate))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_ipackets) as usize - ptr as usize },\n        20usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_ipackets))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_ierrors) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_ierrors))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_opackets) as usize - ptr as usize },\n        28usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_opackets))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_oerrors) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_oerrors))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_collisions) as usize - ptr as usize },\n        36usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data),\n            \"::\",\n            stringify!(ifi_collisions)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_ibytes) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_ibytes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_obytes) as usize - ptr as usize },\n        44usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_obytes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_imcasts) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_imcasts))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_omcasts) as usize - ptr as usize },\n        52usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_omcasts))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_iqdrops) as usize - ptr as usize },\n        56usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_iqdrops))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_noproto) as usize - ptr as usize },\n        60usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_noproto))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_recvtiming) as usize - ptr as usize },\n        64usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data),\n            \"::\",\n            stringify!(ifi_recvtiming)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_xmittiming) as usize - ptr as usize },\n        68usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data),\n            \"::\",\n            stringify!(ifi_xmittiming)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_lastchange) as usize - ptr as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data),\n            \"::\",\n            stringify!(ifi_lastchange)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_unused2) as usize - ptr as usize },\n        80usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_unused2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_hwassist) as usize - ptr as usize },\n        84usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_hwassist))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_reserved1) as usize - ptr as usize },\n        88usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data),\n            \"::\",\n            stringify!(ifi_reserved1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_reserved2) as usize - ptr as usize },\n        92usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data),\n            \"::\",\n            stringify!(ifi_reserved2)\n        )\n    );\n}\n#[repr(C, packed(4))]\n#[derive(Debug, Copy, Clone)]\npub struct if_data64 {\n    pub ifi_type: u_char,\n    pub ifi_typelen: u_char,\n    pub ifi_physical: u_char,\n    pub ifi_addrlen: u_char,\n    pub ifi_hdrlen: u_char,\n    pub ifi_recvquota: u_char,\n    pub ifi_xmitquota: u_char,\n    pub ifi_unused1: u_char,\n    pub ifi_mtu: u_int32_t,\n    pub ifi_metric: u_int32_t,\n    pub ifi_baudrate: u_int64_t,\n    pub ifi_ipackets: u_int64_t,\n    pub ifi_ierrors: u_int64_t,\n    pub ifi_opackets: u_int64_t,\n    pub ifi_oerrors: u_int64_t,\n    pub ifi_collisions: u_int64_t,\n    pub ifi_ibytes: u_int64_t,\n    pub ifi_obytes: u_int64_t,\n    pub ifi_imcasts: u_int64_t,\n    pub ifi_omcasts: u_int64_t,\n    pub ifi_iqdrops: u_int64_t,\n    pub ifi_noproto: u_int64_t,\n    pub ifi_recvtiming: u_int32_t,\n    pub ifi_xmittiming: u_int32_t,\n    pub ifi_lastchange: timeval32,\n}\n#[test]\nfn bindgen_test_layout_if_data64() {\n    const UNINIT: ::std::mem::MaybeUninit<if_data64> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_data64>(),\n        128usize,\n        concat!(\"Size of: \", stringify!(if_data64))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_data64>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(if_data64))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_type) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(if_data64), \"::\", stringify!(ifi_type))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_typelen) as usize - ptr as usize },\n        1usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data64),\n            \"::\",\n            stringify!(ifi_typelen)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_physical) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data64),\n            \"::\",\n            stringify!(ifi_physical)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_addrlen) as usize - ptr as usize },\n        3usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data64),\n            \"::\",\n            stringify!(ifi_addrlen)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_hdrlen) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(if_data64), \"::\", stringify!(ifi_hdrlen))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_recvquota) as usize - ptr as usize },\n        5usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data64),\n            \"::\",\n            stringify!(ifi_recvquota)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_xmitquota) as usize - ptr as usize },\n        6usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data64),\n            \"::\",\n            stringify!(ifi_xmitquota)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_unused1) as usize - ptr as usize },\n        7usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data64),\n            \"::\",\n            stringify!(ifi_unused1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_mtu) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(if_data64), \"::\", stringify!(ifi_mtu))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_metric) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(if_data64), \"::\", stringify!(ifi_metric))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_baudrate) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data64),\n            \"::\",\n            stringify!(ifi_baudrate)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_ipackets) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data64),\n            \"::\",\n            stringify!(ifi_ipackets)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_ierrors) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data64),\n            \"::\",\n            stringify!(ifi_ierrors)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_opackets) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data64),\n            \"::\",\n            stringify!(ifi_opackets)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_oerrors) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data64),\n            \"::\",\n            stringify!(ifi_oerrors)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_collisions) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data64),\n            \"::\",\n            stringify!(ifi_collisions)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_ibytes) as usize - ptr as usize },\n        64usize,\n        concat!(\"Offset of field: \", stringify!(if_data64), \"::\", stringify!(ifi_ibytes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_obytes) as usize - ptr as usize },\n        72usize,\n        concat!(\"Offset of field: \", stringify!(if_data64), \"::\", stringify!(ifi_obytes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_imcasts) as usize - ptr as usize },\n        80usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data64),\n            \"::\",\n            stringify!(ifi_imcasts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_omcasts) as usize - ptr as usize },\n        88usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data64),\n            \"::\",\n            stringify!(ifi_omcasts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_iqdrops) as usize - ptr as usize },\n        96usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data64),\n            \"::\",\n            stringify!(ifi_iqdrops)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_noproto) as usize - ptr as usize },\n        104usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data64),\n            \"::\",\n            stringify!(ifi_noproto)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_recvtiming) as usize - ptr as usize },\n        112usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data64),\n            \"::\",\n            stringify!(ifi_recvtiming)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_xmittiming) as usize - ptr as usize },\n        116usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data64),\n            \"::\",\n            stringify!(ifi_xmittiming)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_lastchange) as usize - ptr as usize },\n        120usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data64),\n            \"::\",\n            stringify!(ifi_lastchange)\n        )\n    );\n}\n#[repr(C, packed(4))]\n#[derive(Debug, Copy, Clone)]\npub struct if_traffic_class {\n    pub ifi_ibepackets: u_int64_t,\n    pub ifi_ibebytes: u_int64_t,\n    pub ifi_obepackets: u_int64_t,\n    pub ifi_obebytes: u_int64_t,\n    pub ifi_ibkpackets: u_int64_t,\n    pub ifi_ibkbytes: u_int64_t,\n    pub ifi_obkpackets: u_int64_t,\n    pub ifi_obkbytes: u_int64_t,\n    pub ifi_ivipackets: u_int64_t,\n    pub ifi_ivibytes: u_int64_t,\n    pub ifi_ovipackets: u_int64_t,\n    pub ifi_ovibytes: u_int64_t,\n    pub ifi_ivopackets: u_int64_t,\n    pub ifi_ivobytes: u_int64_t,\n    pub ifi_ovopackets: u_int64_t,\n    pub ifi_ovobytes: u_int64_t,\n    pub ifi_ipvpackets: u_int64_t,\n    pub ifi_ipvbytes: u_int64_t,\n    pub ifi_opvpackets: u_int64_t,\n    pub ifi_opvbytes: u_int64_t,\n}\n#[test]\nfn bindgen_test_layout_if_traffic_class() {\n    const UNINIT: ::std::mem::MaybeUninit<if_traffic_class> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_traffic_class>(),\n        160usize,\n        concat!(\"Size of: \", stringify!(if_traffic_class))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_traffic_class>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(if_traffic_class))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_ibepackets) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_traffic_class),\n            \"::\",\n            stringify!(ifi_ibepackets)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_ibebytes) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_traffic_class),\n            \"::\",\n            stringify!(ifi_ibebytes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_obepackets) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_traffic_class),\n            \"::\",\n            stringify!(ifi_obepackets)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_obebytes) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_traffic_class),\n            \"::\",\n            stringify!(ifi_obebytes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_ibkpackets) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_traffic_class),\n            \"::\",\n            stringify!(ifi_ibkpackets)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_ibkbytes) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_traffic_class),\n            \"::\",\n            stringify!(ifi_ibkbytes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_obkpackets) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_traffic_class),\n            \"::\",\n            stringify!(ifi_obkpackets)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_obkbytes) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_traffic_class),\n            \"::\",\n            stringify!(ifi_obkbytes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_ivipackets) as usize - ptr as usize },\n        64usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_traffic_class),\n            \"::\",\n            stringify!(ifi_ivipackets)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_ivibytes) as usize - ptr as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_traffic_class),\n            \"::\",\n            stringify!(ifi_ivibytes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_ovipackets) as usize - ptr as usize },\n        80usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_traffic_class),\n            \"::\",\n            stringify!(ifi_ovipackets)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_ovibytes) as usize - ptr as usize },\n        88usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_traffic_class),\n            \"::\",\n            stringify!(ifi_ovibytes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_ivopackets) as usize - ptr as usize },\n        96usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_traffic_class),\n            \"::\",\n            stringify!(ifi_ivopackets)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_ivobytes) as usize - ptr as usize },\n        104usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_traffic_class),\n            \"::\",\n            stringify!(ifi_ivobytes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_ovopackets) as usize - ptr as usize },\n        112usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_traffic_class),\n            \"::\",\n            stringify!(ifi_ovopackets)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_ovobytes) as usize - ptr as usize },\n        120usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_traffic_class),\n            \"::\",\n            stringify!(ifi_ovobytes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_ipvpackets) as usize - ptr as usize },\n        128usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_traffic_class),\n            \"::\",\n            stringify!(ifi_ipvpackets)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_ipvbytes) as usize - ptr as usize },\n        136usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_traffic_class),\n            \"::\",\n            stringify!(ifi_ipvbytes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_opvpackets) as usize - ptr as usize },\n        144usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_traffic_class),\n            \"::\",\n            stringify!(ifi_opvpackets)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_opvbytes) as usize - ptr as usize },\n        152usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_traffic_class),\n            \"::\",\n            stringify!(ifi_opvbytes)\n        )\n    );\n}\n#[repr(C, packed(4))]\n#[derive(Debug, Copy, Clone)]\npub struct if_data_extended {\n    pub ifi_alignerrs: u_int64_t,\n    pub ifi_dt_bytes: u_int64_t,\n    pub ifi_fpackets: u_int64_t,\n    pub ifi_fbytes: u_int64_t,\n    pub reserved: [u_int64_t; 12usize],\n}\n#[test]\nfn bindgen_test_layout_if_data_extended() {\n    const UNINIT: ::std::mem::MaybeUninit<if_data_extended> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_data_extended>(),\n        128usize,\n        concat!(\"Size of: \", stringify!(if_data_extended))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_data_extended>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(if_data_extended))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_alignerrs) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data_extended),\n            \"::\",\n            stringify!(ifi_alignerrs)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_dt_bytes) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data_extended),\n            \"::\",\n            stringify!(ifi_dt_bytes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_fpackets) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data_extended),\n            \"::\",\n            stringify!(ifi_fpackets)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_fbytes) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data_extended),\n            \"::\",\n            stringify!(ifi_fbytes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).reserved) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data_extended),\n            \"::\",\n            stringify!(reserved)\n        )\n    );\n}\n#[repr(C, packed(4))]\n#[derive(Debug, Copy, Clone)]\npub struct if_packet_stats {\n    pub ifi_tcp_badformat: u_int64_t,\n    pub ifi_tcp_unspecv6: u_int64_t,\n    pub ifi_tcp_synfin: u_int64_t,\n    pub ifi_tcp_badformatipsec: u_int64_t,\n    pub ifi_tcp_noconnnolist: u_int64_t,\n    pub ifi_tcp_noconnlist: u_int64_t,\n    pub ifi_tcp_listbadsyn: u_int64_t,\n    pub ifi_tcp_icmp6unreach: u_int64_t,\n    pub ifi_tcp_deprecate6: u_int64_t,\n    pub ifi_tcp_rstinsynrcv: u_int64_t,\n    pub ifi_tcp_ooopacket: u_int64_t,\n    pub ifi_tcp_dospacket: u_int64_t,\n    pub ifi_tcp_cleanup: u_int64_t,\n    pub ifi_tcp_synwindow: u_int64_t,\n    pub reserved: [u_int64_t; 6usize],\n    pub ifi_udp_port_unreach: u_int64_t,\n    pub ifi_udp_faithprefix: u_int64_t,\n    pub ifi_udp_port0: u_int64_t,\n    pub ifi_udp_badlength: u_int64_t,\n    pub ifi_udp_badchksum: u_int64_t,\n    pub ifi_udp_badmcast: u_int64_t,\n    pub ifi_udp_cleanup: u_int64_t,\n    pub ifi_udp_badipsec: u_int64_t,\n    pub _reserved: [u_int64_t; 4usize],\n}\n#[test]\nfn bindgen_test_layout_if_packet_stats() {\n    const UNINIT: ::std::mem::MaybeUninit<if_packet_stats> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_packet_stats>(),\n        256usize,\n        concat!(\"Size of: \", stringify!(if_packet_stats))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_packet_stats>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(if_packet_stats))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_tcp_badformat) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_packet_stats),\n            \"::\",\n            stringify!(ifi_tcp_badformat)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_tcp_unspecv6) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_packet_stats),\n            \"::\",\n            stringify!(ifi_tcp_unspecv6)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_tcp_synfin) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_packet_stats),\n            \"::\",\n            stringify!(ifi_tcp_synfin)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_tcp_badformatipsec) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_packet_stats),\n            \"::\",\n            stringify!(ifi_tcp_badformatipsec)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_tcp_noconnnolist) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_packet_stats),\n            \"::\",\n            stringify!(ifi_tcp_noconnnolist)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_tcp_noconnlist) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_packet_stats),\n            \"::\",\n            stringify!(ifi_tcp_noconnlist)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_tcp_listbadsyn) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_packet_stats),\n            \"::\",\n            stringify!(ifi_tcp_listbadsyn)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_tcp_icmp6unreach) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_packet_stats),\n            \"::\",\n            stringify!(ifi_tcp_icmp6unreach)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_tcp_deprecate6) as usize - ptr as usize },\n        64usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_packet_stats),\n            \"::\",\n            stringify!(ifi_tcp_deprecate6)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_tcp_rstinsynrcv) as usize - ptr as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_packet_stats),\n            \"::\",\n            stringify!(ifi_tcp_rstinsynrcv)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_tcp_ooopacket) as usize - ptr as usize },\n        80usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_packet_stats),\n            \"::\",\n            stringify!(ifi_tcp_ooopacket)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_tcp_dospacket) as usize - ptr as usize },\n        88usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_packet_stats),\n            \"::\",\n            stringify!(ifi_tcp_dospacket)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_tcp_cleanup) as usize - ptr as usize },\n        96usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_packet_stats),\n            \"::\",\n            stringify!(ifi_tcp_cleanup)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_tcp_synwindow) as usize - ptr as usize },\n        104usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_packet_stats),\n            \"::\",\n            stringify!(ifi_tcp_synwindow)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).reserved) as usize - ptr as usize },\n        112usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_packet_stats),\n            \"::\",\n            stringify!(reserved)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_udp_port_unreach) as usize - ptr as usize },\n        160usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_packet_stats),\n            \"::\",\n            stringify!(ifi_udp_port_unreach)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_udp_faithprefix) as usize - ptr as usize },\n        168usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_packet_stats),\n            \"::\",\n            stringify!(ifi_udp_faithprefix)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_udp_port0) as usize - ptr as usize },\n        176usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_packet_stats),\n            \"::\",\n            stringify!(ifi_udp_port0)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_udp_badlength) as usize - ptr as usize },\n        184usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_packet_stats),\n            \"::\",\n            stringify!(ifi_udp_badlength)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_udp_badchksum) as usize - ptr as usize },\n        192usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_packet_stats),\n            \"::\",\n            stringify!(ifi_udp_badchksum)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_udp_badmcast) as usize - ptr as usize },\n        200usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_packet_stats),\n            \"::\",\n            stringify!(ifi_udp_badmcast)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_udp_cleanup) as usize - ptr as usize },\n        208usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_packet_stats),\n            \"::\",\n            stringify!(ifi_udp_cleanup)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_udp_badipsec) as usize - ptr as usize },\n        216usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_packet_stats),\n            \"::\",\n            stringify!(ifi_udp_badipsec)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._reserved) as usize - ptr as usize },\n        224usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_packet_stats),\n            \"::\",\n            stringify!(_reserved)\n        )\n    );\n}\n#[repr(C, packed(4))]\n#[derive(Debug, Copy, Clone)]\npub struct if_description {\n    pub ifd_maxlen: u_int32_t,\n    pub ifd_len: u_int32_t,\n    pub ifd_desc: *mut u_int8_t,\n}\n#[test]\nfn bindgen_test_layout_if_description() {\n    const UNINIT: ::std::mem::MaybeUninit<if_description> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_description>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(if_description))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_description>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(if_description))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifd_maxlen) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_description),\n            \"::\",\n            stringify!(ifd_maxlen)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifd_len) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_description),\n            \"::\",\n            stringify!(ifd_len)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifd_desc) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_description),\n            \"::\",\n            stringify!(ifd_desc)\n        )\n    );\n}\n#[repr(C, packed(4))]\n#[derive(Debug, Copy, Clone)]\npub struct if_bandwidths {\n    pub eff_bw: u64,\n    pub max_bw: u64,\n}\n#[test]\nfn bindgen_test_layout_if_bandwidths() {\n    const UNINIT: ::std::mem::MaybeUninit<if_bandwidths> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_bandwidths>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(if_bandwidths))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_bandwidths>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(if_bandwidths))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).eff_bw) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(if_bandwidths), \"::\", stringify!(eff_bw))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_bw) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(if_bandwidths), \"::\", stringify!(max_bw))\n    );\n}\n#[repr(C, packed(4))]\n#[derive(Debug, Copy, Clone)]\npub struct if_latencies {\n    pub eff_lt: u_int64_t,\n    pub max_lt: u_int64_t,\n}\n#[test]\nfn bindgen_test_layout_if_latencies() {\n    const UNINIT: ::std::mem::MaybeUninit<if_latencies> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_latencies>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(if_latencies))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_latencies>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(if_latencies))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).eff_lt) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(if_latencies), \"::\", stringify!(eff_lt))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_lt) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(if_latencies), \"::\", stringify!(max_lt))\n    );\n}\n#[repr(C, packed(4))]\n#[derive(Debug, Copy, Clone)]\npub struct if_netem_params {\n    pub ifnetem_bandwidth_bps: u64,\n    pub ifnetem_latency_ms: u32,\n    pub ifnetem_jitter_ms: u32,\n    pub ifnetem_corruption_p: u32,\n    pub ifnetem_duplication_p: u32,\n    pub ifnetem_loss_p_gr_gl: u32,\n    pub ifnetem_loss_p_gr_bl: u32,\n    pub ifnetem_loss_p_bl_br: u32,\n    pub ifnetem_loss_p_bl_gr: u32,\n    pub ifnetem_loss_p_br_bl: u32,\n    pub ifnetem_reordering_p: u32,\n}\n#[test]\nfn bindgen_test_layout_if_netem_params() {\n    const UNINIT: ::std::mem::MaybeUninit<if_netem_params> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_netem_params>(),\n        48usize,\n        concat!(\"Size of: \", stringify!(if_netem_params))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_netem_params>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(if_netem_params))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifnetem_bandwidth_bps) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_netem_params),\n            \"::\",\n            stringify!(ifnetem_bandwidth_bps)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifnetem_latency_ms) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_netem_params),\n            \"::\",\n            stringify!(ifnetem_latency_ms)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifnetem_jitter_ms) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_netem_params),\n            \"::\",\n            stringify!(ifnetem_jitter_ms)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifnetem_corruption_p) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_netem_params),\n            \"::\",\n            stringify!(ifnetem_corruption_p)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifnetem_duplication_p) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_netem_params),\n            \"::\",\n            stringify!(ifnetem_duplication_p)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifnetem_loss_p_gr_gl) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_netem_params),\n            \"::\",\n            stringify!(ifnetem_loss_p_gr_gl)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifnetem_loss_p_gr_bl) as usize - ptr as usize },\n        28usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_netem_params),\n            \"::\",\n            stringify!(ifnetem_loss_p_gr_bl)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifnetem_loss_p_bl_br) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_netem_params),\n            \"::\",\n            stringify!(ifnetem_loss_p_bl_br)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifnetem_loss_p_bl_gr) as usize - ptr as usize },\n        36usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_netem_params),\n            \"::\",\n            stringify!(ifnetem_loss_p_bl_gr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifnetem_loss_p_br_bl) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_netem_params),\n            \"::\",\n            stringify!(ifnetem_loss_p_br_bl)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifnetem_reordering_p) as usize - ptr as usize },\n        44usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_netem_params),\n            \"::\",\n            stringify!(ifnetem_reordering_p)\n        )\n    );\n}\n#[repr(C, packed(4))]\n#[derive(Debug, Copy, Clone)]\npub struct if_rxpoll_stats {\n    pub ifi_poll_off_req: u_int32_t,\n    pub ifi_poll_off_err: u_int32_t,\n    pub ifi_poll_on_req: u_int32_t,\n    pub ifi_poll_on_err: u_int32_t,\n    pub ifi_poll_wakeups_avg: u_int32_t,\n    pub ifi_poll_wakeups_lowat: u_int32_t,\n    pub ifi_poll_wakeups_hiwat: u_int32_t,\n    pub ifi_poll_packets: u_int64_t,\n    pub ifi_poll_packets_avg: u_int32_t,\n    pub ifi_poll_packets_min: u_int32_t,\n    pub ifi_poll_packets_max: u_int32_t,\n    pub ifi_poll_packets_lowat: u_int32_t,\n    pub ifi_poll_packets_hiwat: u_int32_t,\n    pub ifi_poll_bytes: u_int64_t,\n    pub ifi_poll_bytes_avg: u_int32_t,\n    pub ifi_poll_bytes_min: u_int32_t,\n    pub ifi_poll_bytes_max: u_int32_t,\n    pub ifi_poll_bytes_lowat: u_int32_t,\n    pub ifi_poll_bytes_hiwat: u_int32_t,\n    pub ifi_poll_packets_limit: u_int32_t,\n    pub ifi_poll_interval_time: u_int64_t,\n}\n#[test]\nfn bindgen_test_layout_if_rxpoll_stats() {\n    const UNINIT: ::std::mem::MaybeUninit<if_rxpoll_stats> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_rxpoll_stats>(),\n        96usize,\n        concat!(\"Size of: \", stringify!(if_rxpoll_stats))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_rxpoll_stats>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(if_rxpoll_stats))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_poll_off_req) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_rxpoll_stats),\n            \"::\",\n            stringify!(ifi_poll_off_req)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_poll_off_err) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_rxpoll_stats),\n            \"::\",\n            stringify!(ifi_poll_off_err)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_poll_on_req) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_rxpoll_stats),\n            \"::\",\n            stringify!(ifi_poll_on_req)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_poll_on_err) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_rxpoll_stats),\n            \"::\",\n            stringify!(ifi_poll_on_err)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_poll_wakeups_avg) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_rxpoll_stats),\n            \"::\",\n            stringify!(ifi_poll_wakeups_avg)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_poll_wakeups_lowat) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_rxpoll_stats),\n            \"::\",\n            stringify!(ifi_poll_wakeups_lowat)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_poll_wakeups_hiwat) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_rxpoll_stats),\n            \"::\",\n            stringify!(ifi_poll_wakeups_hiwat)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_poll_packets) as usize - ptr as usize },\n        28usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_rxpoll_stats),\n            \"::\",\n            stringify!(ifi_poll_packets)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_poll_packets_avg) as usize - ptr as usize },\n        36usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_rxpoll_stats),\n            \"::\",\n            stringify!(ifi_poll_packets_avg)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_poll_packets_min) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_rxpoll_stats),\n            \"::\",\n            stringify!(ifi_poll_packets_min)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_poll_packets_max) as usize - ptr as usize },\n        44usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_rxpoll_stats),\n            \"::\",\n            stringify!(ifi_poll_packets_max)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_poll_packets_lowat) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_rxpoll_stats),\n            \"::\",\n            stringify!(ifi_poll_packets_lowat)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_poll_packets_hiwat) as usize - ptr as usize },\n        52usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_rxpoll_stats),\n            \"::\",\n            stringify!(ifi_poll_packets_hiwat)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_poll_bytes) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_rxpoll_stats),\n            \"::\",\n            stringify!(ifi_poll_bytes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_poll_bytes_avg) as usize - ptr as usize },\n        64usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_rxpoll_stats),\n            \"::\",\n            stringify!(ifi_poll_bytes_avg)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_poll_bytes_min) as usize - ptr as usize },\n        68usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_rxpoll_stats),\n            \"::\",\n            stringify!(ifi_poll_bytes_min)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_poll_bytes_max) as usize - ptr as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_rxpoll_stats),\n            \"::\",\n            stringify!(ifi_poll_bytes_max)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_poll_bytes_lowat) as usize - ptr as usize },\n        76usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_rxpoll_stats),\n            \"::\",\n            stringify!(ifi_poll_bytes_lowat)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_poll_bytes_hiwat) as usize - ptr as usize },\n        80usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_rxpoll_stats),\n            \"::\",\n            stringify!(ifi_poll_bytes_hiwat)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_poll_packets_limit) as usize - ptr as usize },\n        84usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_rxpoll_stats),\n            \"::\",\n            stringify!(ifi_poll_packets_limit)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_poll_interval_time) as usize - ptr as usize },\n        88usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_rxpoll_stats),\n            \"::\",\n            stringify!(ifi_poll_interval_time)\n        )\n    );\n}\n#[repr(C, packed(4))]\n#[derive(Debug, Copy, Clone)]\npub struct if_netif_stats {\n    pub ifn_rx_mit_interval: u_int64_t,\n    pub ifn_rx_mit_mode: u_int32_t,\n    pub ifn_rx_mit_packets_avg: u_int32_t,\n    pub ifn_rx_mit_packets_min: u_int32_t,\n    pub ifn_rx_mit_packets_max: u_int32_t,\n    pub ifn_rx_mit_bytes_avg: u_int32_t,\n    pub ifn_rx_mit_bytes_min: u_int32_t,\n    pub ifn_rx_mit_bytes_max: u_int32_t,\n    pub ifn_rx_mit_cfg_idx: u_int32_t,\n    pub ifn_rx_mit_cfg_packets_lowat: u_int32_t,\n    pub ifn_rx_mit_cfg_packets_hiwat: u_int32_t,\n    pub ifn_rx_mit_cfg_bytes_lowat: u_int32_t,\n    pub ifn_rx_mit_cfg_bytes_hiwat: u_int32_t,\n    pub ifn_rx_mit_cfg_interval: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_if_netif_stats() {\n    const UNINIT: ::std::mem::MaybeUninit<if_netif_stats> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_netif_stats>(),\n        60usize,\n        concat!(\"Size of: \", stringify!(if_netif_stats))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_netif_stats>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(if_netif_stats))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifn_rx_mit_interval) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_netif_stats),\n            \"::\",\n            stringify!(ifn_rx_mit_interval)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifn_rx_mit_mode) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_netif_stats),\n            \"::\",\n            stringify!(ifn_rx_mit_mode)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifn_rx_mit_packets_avg) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_netif_stats),\n            \"::\",\n            stringify!(ifn_rx_mit_packets_avg)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifn_rx_mit_packets_min) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_netif_stats),\n            \"::\",\n            stringify!(ifn_rx_mit_packets_min)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifn_rx_mit_packets_max) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_netif_stats),\n            \"::\",\n            stringify!(ifn_rx_mit_packets_max)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifn_rx_mit_bytes_avg) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_netif_stats),\n            \"::\",\n            stringify!(ifn_rx_mit_bytes_avg)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifn_rx_mit_bytes_min) as usize - ptr as usize },\n        28usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_netif_stats),\n            \"::\",\n            stringify!(ifn_rx_mit_bytes_min)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifn_rx_mit_bytes_max) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_netif_stats),\n            \"::\",\n            stringify!(ifn_rx_mit_bytes_max)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifn_rx_mit_cfg_idx) as usize - ptr as usize },\n        36usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_netif_stats),\n            \"::\",\n            stringify!(ifn_rx_mit_cfg_idx)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifn_rx_mit_cfg_packets_lowat) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_netif_stats),\n            \"::\",\n            stringify!(ifn_rx_mit_cfg_packets_lowat)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifn_rx_mit_cfg_packets_hiwat) as usize - ptr as usize },\n        44usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_netif_stats),\n            \"::\",\n            stringify!(ifn_rx_mit_cfg_packets_hiwat)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifn_rx_mit_cfg_bytes_lowat) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_netif_stats),\n            \"::\",\n            stringify!(ifn_rx_mit_cfg_bytes_lowat)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifn_rx_mit_cfg_bytes_hiwat) as usize - ptr as usize },\n        52usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_netif_stats),\n            \"::\",\n            stringify!(ifn_rx_mit_cfg_bytes_hiwat)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifn_rx_mit_cfg_interval) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_netif_stats),\n            \"::\",\n            stringify!(ifn_rx_mit_cfg_interval)\n        )\n    );\n}\n#[repr(C, packed(4))]\n#[derive(Debug, Copy, Clone)]\npub struct if_tcp_ecn_perf_stat {\n    pub total_txpkts: u_int64_t,\n    pub total_rxmitpkts: u_int64_t,\n    pub total_rxpkts: u_int64_t,\n    pub total_oopkts: u_int64_t,\n    pub total_reorderpkts: u_int64_t,\n    pub rtt_avg: u_int64_t,\n    pub rtt_var: u_int64_t,\n    pub sack_episodes: u_int64_t,\n    pub rxmit_drop: u_int64_t,\n    pub rst_drop: u_int64_t,\n    pub oo_percent: u_int64_t,\n    pub reorder_percent: u_int64_t,\n    pub rxmit_percent: u_int64_t,\n}\n#[test]\nfn bindgen_test_layout_if_tcp_ecn_perf_stat() {\n    const UNINIT: ::std::mem::MaybeUninit<if_tcp_ecn_perf_stat> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_tcp_ecn_perf_stat>(),\n        104usize,\n        concat!(\"Size of: \", stringify!(if_tcp_ecn_perf_stat))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_tcp_ecn_perf_stat>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(if_tcp_ecn_perf_stat))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).total_txpkts) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_perf_stat),\n            \"::\",\n            stringify!(total_txpkts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).total_rxmitpkts) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_perf_stat),\n            \"::\",\n            stringify!(total_rxmitpkts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).total_rxpkts) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_perf_stat),\n            \"::\",\n            stringify!(total_rxpkts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).total_oopkts) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_perf_stat),\n            \"::\",\n            stringify!(total_oopkts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).total_reorderpkts) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_perf_stat),\n            \"::\",\n            stringify!(total_reorderpkts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtt_avg) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_perf_stat),\n            \"::\",\n            stringify!(rtt_avg)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtt_var) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_perf_stat),\n            \"::\",\n            stringify!(rtt_var)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sack_episodes) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_perf_stat),\n            \"::\",\n            stringify!(sack_episodes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rxmit_drop) as usize - ptr as usize },\n        64usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_perf_stat),\n            \"::\",\n            stringify!(rxmit_drop)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rst_drop) as usize - ptr as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_perf_stat),\n            \"::\",\n            stringify!(rst_drop)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).oo_percent) as usize - ptr as usize },\n        80usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_perf_stat),\n            \"::\",\n            stringify!(oo_percent)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).reorder_percent) as usize - ptr as usize },\n        88usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_perf_stat),\n            \"::\",\n            stringify!(reorder_percent)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rxmit_percent) as usize - ptr as usize },\n        96usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_perf_stat),\n            \"::\",\n            stringify!(rxmit_percent)\n        )\n    );\n}\n#[repr(C, packed(4))]\n#[derive(Debug, Copy, Clone)]\npub struct if_tcp_ecn_stat {\n    pub timestamp: u_int64_t,\n    pub ecn_client_setup: u_int64_t,\n    pub ecn_server_setup: u_int64_t,\n    pub ecn_client_success: u_int64_t,\n    pub ecn_server_success: u_int64_t,\n    pub ecn_peer_nosupport: u_int64_t,\n    pub ecn_syn_lost: u_int64_t,\n    pub ecn_synack_lost: u_int64_t,\n    pub ecn_recv_ce: u_int64_t,\n    pub ecn_recv_ece: u_int64_t,\n    pub ecn_conn_recv_ce: u_int64_t,\n    pub ecn_conn_recv_ece: u_int64_t,\n    pub ecn_conn_plnoce: u_int64_t,\n    pub ecn_conn_plce: u_int64_t,\n    pub ecn_conn_noplce: u_int64_t,\n    pub ecn_fallback_synloss: u_int64_t,\n    pub ecn_fallback_reorder: u_int64_t,\n    pub ecn_fallback_ce: u_int64_t,\n    pub ecn_off_conn: u_int64_t,\n    pub ecn_total_conn: u_int64_t,\n    pub ecn_fallback_droprst: u_int64_t,\n    pub ecn_fallback_droprxmt: u_int64_t,\n    pub ecn_fallback_synrst: u_int64_t,\n    pub ecn_on: if_tcp_ecn_perf_stat,\n    pub ecn_off: if_tcp_ecn_perf_stat,\n}\n#[test]\nfn bindgen_test_layout_if_tcp_ecn_stat() {\n    const UNINIT: ::std::mem::MaybeUninit<if_tcp_ecn_stat> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_tcp_ecn_stat>(),\n        392usize,\n        concat!(\"Size of: \", stringify!(if_tcp_ecn_stat))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_tcp_ecn_stat>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(if_tcp_ecn_stat))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).timestamp) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_stat),\n            \"::\",\n            stringify!(timestamp)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ecn_client_setup) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_stat),\n            \"::\",\n            stringify!(ecn_client_setup)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ecn_server_setup) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_stat),\n            \"::\",\n            stringify!(ecn_server_setup)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ecn_client_success) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_stat),\n            \"::\",\n            stringify!(ecn_client_success)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ecn_server_success) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_stat),\n            \"::\",\n            stringify!(ecn_server_success)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ecn_peer_nosupport) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_stat),\n            \"::\",\n            stringify!(ecn_peer_nosupport)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ecn_syn_lost) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_stat),\n            \"::\",\n            stringify!(ecn_syn_lost)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ecn_synack_lost) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_stat),\n            \"::\",\n            stringify!(ecn_synack_lost)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ecn_recv_ce) as usize - ptr as usize },\n        64usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_stat),\n            \"::\",\n            stringify!(ecn_recv_ce)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ecn_recv_ece) as usize - ptr as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_stat),\n            \"::\",\n            stringify!(ecn_recv_ece)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ecn_conn_recv_ce) as usize - ptr as usize },\n        80usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_stat),\n            \"::\",\n            stringify!(ecn_conn_recv_ce)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ecn_conn_recv_ece) as usize - ptr as usize },\n        88usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_stat),\n            \"::\",\n            stringify!(ecn_conn_recv_ece)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ecn_conn_plnoce) as usize - ptr as usize },\n        96usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_stat),\n            \"::\",\n            stringify!(ecn_conn_plnoce)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ecn_conn_plce) as usize - ptr as usize },\n        104usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_stat),\n            \"::\",\n            stringify!(ecn_conn_plce)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ecn_conn_noplce) as usize - ptr as usize },\n        112usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_stat),\n            \"::\",\n            stringify!(ecn_conn_noplce)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ecn_fallback_synloss) as usize - ptr as usize },\n        120usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_stat),\n            \"::\",\n            stringify!(ecn_fallback_synloss)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ecn_fallback_reorder) as usize - ptr as usize },\n        128usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_stat),\n            \"::\",\n            stringify!(ecn_fallback_reorder)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ecn_fallback_ce) as usize - ptr as usize },\n        136usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_stat),\n            \"::\",\n            stringify!(ecn_fallback_ce)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ecn_off_conn) as usize - ptr as usize },\n        144usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_stat),\n            \"::\",\n            stringify!(ecn_off_conn)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ecn_total_conn) as usize - ptr as usize },\n        152usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_stat),\n            \"::\",\n            stringify!(ecn_total_conn)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ecn_fallback_droprst) as usize - ptr as usize },\n        160usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_stat),\n            \"::\",\n            stringify!(ecn_fallback_droprst)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ecn_fallback_droprxmt) as usize - ptr as usize },\n        168usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_stat),\n            \"::\",\n            stringify!(ecn_fallback_droprxmt)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ecn_fallback_synrst) as usize - ptr as usize },\n        176usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_stat),\n            \"::\",\n            stringify!(ecn_fallback_synrst)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ecn_on) as usize - ptr as usize },\n        184usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_stat),\n            \"::\",\n            stringify!(ecn_on)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ecn_off) as usize - ptr as usize },\n        288usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_tcp_ecn_stat),\n            \"::\",\n            stringify!(ecn_off)\n        )\n    );\n}\n#[repr(C, packed(4))]\n#[derive(Debug, Copy, Clone)]\npub struct if_lim_perf_stat {\n    pub lim_dl_max_bandwidth: u_int64_t,\n    pub lim_ul_max_bandwidth: u_int64_t,\n    pub lim_total_txpkts: u_int64_t,\n    pub lim_total_rxpkts: u_int64_t,\n    pub lim_total_retxpkts: u_int64_t,\n    pub lim_packet_loss_percent: u_int64_t,\n    pub lim_total_oopkts: u_int64_t,\n    pub lim_packet_ooo_percent: u_int64_t,\n    pub lim_rtt_variance: u_int64_t,\n    pub lim_rtt_average: u_int64_t,\n    pub lim_rtt_min: u_int64_t,\n    pub lim_conn_timeouts: u_int64_t,\n    pub lim_conn_attempts: u_int64_t,\n    pub lim_conn_timeout_percent: u_int64_t,\n    pub lim_bk_txpkts: u_int64_t,\n    pub _bitfield_align_1: [u8; 0],\n    pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>,\n    pub __bindgen_padding_0: [u8; 3usize],\n}\n#[test]\nfn bindgen_test_layout_if_lim_perf_stat() {\n    const UNINIT: ::std::mem::MaybeUninit<if_lim_perf_stat> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_lim_perf_stat>(),\n        124usize,\n        concat!(\"Size of: \", stringify!(if_lim_perf_stat))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_lim_perf_stat>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(if_lim_perf_stat))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lim_dl_max_bandwidth) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_lim_perf_stat),\n            \"::\",\n            stringify!(lim_dl_max_bandwidth)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lim_ul_max_bandwidth) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_lim_perf_stat),\n            \"::\",\n            stringify!(lim_ul_max_bandwidth)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lim_total_txpkts) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_lim_perf_stat),\n            \"::\",\n            stringify!(lim_total_txpkts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lim_total_rxpkts) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_lim_perf_stat),\n            \"::\",\n            stringify!(lim_total_rxpkts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lim_total_retxpkts) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_lim_perf_stat),\n            \"::\",\n            stringify!(lim_total_retxpkts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lim_packet_loss_percent) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_lim_perf_stat),\n            \"::\",\n            stringify!(lim_packet_loss_percent)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lim_total_oopkts) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_lim_perf_stat),\n            \"::\",\n            stringify!(lim_total_oopkts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lim_packet_ooo_percent) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_lim_perf_stat),\n            \"::\",\n            stringify!(lim_packet_ooo_percent)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lim_rtt_variance) as usize - ptr as usize },\n        64usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_lim_perf_stat),\n            \"::\",\n            stringify!(lim_rtt_variance)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lim_rtt_average) as usize - ptr as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_lim_perf_stat),\n            \"::\",\n            stringify!(lim_rtt_average)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lim_rtt_min) as usize - ptr as usize },\n        80usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_lim_perf_stat),\n            \"::\",\n            stringify!(lim_rtt_min)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lim_conn_timeouts) as usize - ptr as usize },\n        88usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_lim_perf_stat),\n            \"::\",\n            stringify!(lim_conn_timeouts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lim_conn_attempts) as usize - ptr as usize },\n        96usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_lim_perf_stat),\n            \"::\",\n            stringify!(lim_conn_attempts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lim_conn_timeout_percent) as usize - ptr as usize },\n        104usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_lim_perf_stat),\n            \"::\",\n            stringify!(lim_conn_timeout_percent)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lim_bk_txpkts) as usize - ptr as usize },\n        112usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_lim_perf_stat),\n            \"::\",\n            stringify!(lim_bk_txpkts)\n        )\n    );\n}\nimpl if_lim_perf_stat {\n    #[inline]\n    pub fn lim_dl_detected(&self) -> u_int64_t {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u64) }\n    }\n\n    #[inline]\n    pub fn set_lim_dl_detected(&mut self, val: u_int64_t) {\n        unsafe {\n            let val: u64 = ::std::mem::transmute(val);\n            self._bitfield_1.set(0usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn lim_ul_detected(&self) -> u_int64_t {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u64) }\n    }\n\n    #[inline]\n    pub fn set_lim_ul_detected(&mut self, val: u_int64_t) {\n        unsafe {\n            let val: u64 = ::std::mem::transmute(val);\n            self._bitfield_1.set(1usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn new_bitfield_1(\n        lim_dl_detected: u_int64_t,\n        lim_ul_detected: u_int64_t,\n    ) -> __BindgenBitfieldUnit<[u8; 1usize]> {\n        let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default();\n        __bindgen_bitfield_unit.set(0usize, 1u8, {\n            let lim_dl_detected: u64 = unsafe { ::std::mem::transmute(lim_dl_detected) };\n            lim_dl_detected as u64\n        });\n        __bindgen_bitfield_unit.set(1usize, 1u8, {\n            let lim_ul_detected: u64 = unsafe { ::std::mem::transmute(lim_ul_detected) };\n            lim_ul_detected as u64\n        });\n        __bindgen_bitfield_unit\n    }\n}\n#[repr(C, packed(4))]\n#[derive(Debug, Copy, Clone)]\npub struct ifnet_stats_per_flow {\n    pub bk_txpackets: u_int64_t,\n    pub txpackets: u_int64_t,\n    pub rxpackets: u_int64_t,\n    pub txretransmitbytes: u_int32_t,\n    pub rxoutoforderbytes: u_int32_t,\n    pub rxmitpkts: u_int32_t,\n    pub rcvoopack: u_int32_t,\n    pub pawsdrop: u_int32_t,\n    pub sack_recovery_episodes: u_int32_t,\n    pub reordered_pkts: u_int32_t,\n    pub dsack_sent: u_int32_t,\n    pub dsack_recvd: u_int32_t,\n    pub srtt: u_int32_t,\n    pub rttupdated: u_int32_t,\n    pub rttvar: u_int32_t,\n    pub rttmin: u_int32_t,\n    pub bw_sndbw_max: u_int32_t,\n    pub bw_rcvbw_max: u_int32_t,\n    pub ecn_recv_ece: u_int32_t,\n    pub ecn_recv_ce: u_int32_t,\n    pub ecn_flags: u_int16_t,\n    pub _bitfield_align_1: [u8; 0],\n    pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>,\n}\n#[test]\nfn bindgen_test_layout_ifnet_stats_per_flow() {\n    const UNINIT: ::std::mem::MaybeUninit<ifnet_stats_per_flow> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifnet_stats_per_flow>(),\n        96usize,\n        concat!(\"Size of: \", stringify!(ifnet_stats_per_flow))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifnet_stats_per_flow>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(ifnet_stats_per_flow))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).bk_txpackets) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_stats_per_flow),\n            \"::\",\n            stringify!(bk_txpackets)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).txpackets) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_stats_per_flow),\n            \"::\",\n            stringify!(txpackets)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rxpackets) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_stats_per_flow),\n            \"::\",\n            stringify!(rxpackets)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).txretransmitbytes) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_stats_per_flow),\n            \"::\",\n            stringify!(txretransmitbytes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rxoutoforderbytes) as usize - ptr as usize },\n        28usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_stats_per_flow),\n            \"::\",\n            stringify!(rxoutoforderbytes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rxmitpkts) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_stats_per_flow),\n            \"::\",\n            stringify!(rxmitpkts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rcvoopack) as usize - ptr as usize },\n        36usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_stats_per_flow),\n            \"::\",\n            stringify!(rcvoopack)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pawsdrop) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_stats_per_flow),\n            \"::\",\n            stringify!(pawsdrop)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sack_recovery_episodes) as usize - ptr as usize },\n        44usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_stats_per_flow),\n            \"::\",\n            stringify!(sack_recovery_episodes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).reordered_pkts) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_stats_per_flow),\n            \"::\",\n            stringify!(reordered_pkts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dsack_sent) as usize - ptr as usize },\n        52usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_stats_per_flow),\n            \"::\",\n            stringify!(dsack_sent)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dsack_recvd) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_stats_per_flow),\n            \"::\",\n            stringify!(dsack_recvd)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).srtt) as usize - ptr as usize },\n        60usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_stats_per_flow),\n            \"::\",\n            stringify!(srtt)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rttupdated) as usize - ptr as usize },\n        64usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_stats_per_flow),\n            \"::\",\n            stringify!(rttupdated)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rttvar) as usize - ptr as usize },\n        68usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_stats_per_flow),\n            \"::\",\n            stringify!(rttvar)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rttmin) as usize - ptr as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_stats_per_flow),\n            \"::\",\n            stringify!(rttmin)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).bw_sndbw_max) as usize - ptr as usize },\n        76usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_stats_per_flow),\n            \"::\",\n            stringify!(bw_sndbw_max)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).bw_rcvbw_max) as usize - ptr as usize },\n        80usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_stats_per_flow),\n            \"::\",\n            stringify!(bw_rcvbw_max)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ecn_recv_ece) as usize - ptr as usize },\n        84usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_stats_per_flow),\n            \"::\",\n            stringify!(ecn_recv_ece)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ecn_recv_ce) as usize - ptr as usize },\n        88usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_stats_per_flow),\n            \"::\",\n            stringify!(ecn_recv_ce)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ecn_flags) as usize - ptr as usize },\n        92usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_stats_per_flow),\n            \"::\",\n            stringify!(ecn_flags)\n        )\n    );\n}\nimpl ifnet_stats_per_flow {\n    #[inline]\n    pub fn ipv4(&self) -> u_int16_t {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set_ipv4(&mut self, val: u_int16_t) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(0usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn local(&self) -> u_int16_t {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set_local(&mut self, val: u_int16_t) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(1usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn connreset(&self) -> u_int16_t {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set_connreset(&mut self, val: u_int16_t) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(2usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn conntimeout(&self) -> u_int16_t {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set_conntimeout(&mut self, val: u_int16_t) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(3usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn rxmit_drop(&self) -> u_int16_t {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set_rxmit_drop(&mut self, val: u_int16_t) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(4usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn ecn_fallback_synloss(&self) -> u_int16_t {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set_ecn_fallback_synloss(&mut self, val: u_int16_t) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(5usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn ecn_fallback_droprst(&self) -> u_int16_t {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(6usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set_ecn_fallback_droprst(&mut self, val: u_int16_t) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(6usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn ecn_fallback_droprxmt(&self) -> u_int16_t {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set_ecn_fallback_droprxmt(&mut self, val: u_int16_t) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(7usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn ecn_fallback_ce(&self) -> u_int16_t {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set_ecn_fallback_ce(&mut self, val: u_int16_t) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(8usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn ecn_fallback_reorder(&self) -> u_int16_t {\n        unsafe { ::std::mem::transmute(self._bitfield_1.get(9usize, 1u8) as u16) }\n    }\n\n    #[inline]\n    pub fn set_ecn_fallback_reorder(&mut self, val: u_int16_t) {\n        unsafe {\n            let val: u16 = ::std::mem::transmute(val);\n            self._bitfield_1.set(9usize, 1u8, val as u64)\n        }\n    }\n\n    #[inline]\n    pub fn new_bitfield_1(\n        ipv4: u_int16_t,\n        local: u_int16_t,\n        connreset: u_int16_t,\n        conntimeout: u_int16_t,\n        rxmit_drop: u_int16_t,\n        ecn_fallback_synloss: u_int16_t,\n        ecn_fallback_droprst: u_int16_t,\n        ecn_fallback_droprxmt: u_int16_t,\n        ecn_fallback_ce: u_int16_t,\n        ecn_fallback_reorder: u_int16_t,\n    ) -> __BindgenBitfieldUnit<[u8; 2usize]> {\n        let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = Default::default();\n        __bindgen_bitfield_unit.set(0usize, 1u8, {\n            let ipv4: u16 = unsafe { ::std::mem::transmute(ipv4) };\n            ipv4 as u64\n        });\n        __bindgen_bitfield_unit.set(1usize, 1u8, {\n            let local: u16 = unsafe { ::std::mem::transmute(local) };\n            local as u64\n        });\n        __bindgen_bitfield_unit.set(2usize, 1u8, {\n            let connreset: u16 = unsafe { ::std::mem::transmute(connreset) };\n            connreset as u64\n        });\n        __bindgen_bitfield_unit.set(3usize, 1u8, {\n            let conntimeout: u16 = unsafe { ::std::mem::transmute(conntimeout) };\n            conntimeout as u64\n        });\n        __bindgen_bitfield_unit.set(4usize, 1u8, {\n            let rxmit_drop: u16 = unsafe { ::std::mem::transmute(rxmit_drop) };\n            rxmit_drop as u64\n        });\n        __bindgen_bitfield_unit.set(5usize, 1u8, {\n            let ecn_fallback_synloss: u16 = unsafe { ::std::mem::transmute(ecn_fallback_synloss) };\n            ecn_fallback_synloss as u64\n        });\n        __bindgen_bitfield_unit.set(6usize, 1u8, {\n            let ecn_fallback_droprst: u16 = unsafe { ::std::mem::transmute(ecn_fallback_droprst) };\n            ecn_fallback_droprst as u64\n        });\n        __bindgen_bitfield_unit.set(7usize, 1u8, {\n            let ecn_fallback_droprxmt: u16 = unsafe { ::std::mem::transmute(ecn_fallback_droprxmt) };\n            ecn_fallback_droprxmt as u64\n        });\n        __bindgen_bitfield_unit.set(8usize, 1u8, {\n            let ecn_fallback_ce: u16 = unsafe { ::std::mem::transmute(ecn_fallback_ce) };\n            ecn_fallback_ce as u64\n        });\n        __bindgen_bitfield_unit.set(9usize, 1u8, {\n            let ecn_fallback_reorder: u16 = unsafe { ::std::mem::transmute(ecn_fallback_reorder) };\n            ecn_fallback_reorder as u64\n        });\n        __bindgen_bitfield_unit\n    }\n}\n#[repr(C, packed)]\n#[derive(Debug, Copy, Clone)]\npub struct if_cellular_status_v1 {\n    pub valid_bitmask: u_int32_t,\n    pub link_quality_metric: u_int32_t,\n    pub ul_effective_bandwidth: u_int32_t,\n    pub ul_max_bandwidth: u_int32_t,\n    pub ul_min_latency: u_int32_t,\n    pub ul_effective_latency: u_int32_t,\n    pub ul_max_latency: u_int32_t,\n    pub ul_retxt_level: u_int32_t,\n    pub ul_bytes_lost: u_int32_t,\n    pub ul_min_queue_size: u_int32_t,\n    pub ul_avg_queue_size: u_int32_t,\n    pub ul_max_queue_size: u_int32_t,\n    pub dl_effective_bandwidth: u_int32_t,\n    pub dl_max_bandwidth: u_int32_t,\n    pub config_inactivity_time: u_int32_t,\n    pub config_backoff_time: u_int32_t,\n    pub mss_recommended: u_int16_t,\n    pub reserved_1: u_int16_t,\n    pub reserved_2: u_int32_t,\n    pub reserved_3: u_int64_t,\n    pub reserved_4: u_int64_t,\n    pub reserved_5: u_int64_t,\n    pub reserved_6: u_int64_t,\n}\n#[test]\nfn bindgen_test_layout_if_cellular_status_v1() {\n    const UNINIT: ::std::mem::MaybeUninit<if_cellular_status_v1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_cellular_status_v1>(),\n        104usize,\n        concat!(\"Size of: \", stringify!(if_cellular_status_v1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_cellular_status_v1>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(if_cellular_status_v1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).valid_bitmask) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_cellular_status_v1),\n            \"::\",\n            stringify!(valid_bitmask)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).link_quality_metric) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_cellular_status_v1),\n            \"::\",\n            stringify!(link_quality_metric)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ul_effective_bandwidth) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_cellular_status_v1),\n            \"::\",\n            stringify!(ul_effective_bandwidth)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ul_max_bandwidth) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_cellular_status_v1),\n            \"::\",\n            stringify!(ul_max_bandwidth)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ul_min_latency) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_cellular_status_v1),\n            \"::\",\n            stringify!(ul_min_latency)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ul_effective_latency) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_cellular_status_v1),\n            \"::\",\n            stringify!(ul_effective_latency)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ul_max_latency) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_cellular_status_v1),\n            \"::\",\n            stringify!(ul_max_latency)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ul_retxt_level) as usize - ptr as usize },\n        28usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_cellular_status_v1),\n            \"::\",\n            stringify!(ul_retxt_level)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ul_bytes_lost) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_cellular_status_v1),\n            \"::\",\n            stringify!(ul_bytes_lost)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ul_min_queue_size) as usize - ptr as usize },\n        36usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_cellular_status_v1),\n            \"::\",\n            stringify!(ul_min_queue_size)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ul_avg_queue_size) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_cellular_status_v1),\n            \"::\",\n            stringify!(ul_avg_queue_size)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ul_max_queue_size) as usize - ptr as usize },\n        44usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_cellular_status_v1),\n            \"::\",\n            stringify!(ul_max_queue_size)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dl_effective_bandwidth) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_cellular_status_v1),\n            \"::\",\n            stringify!(dl_effective_bandwidth)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dl_max_bandwidth) as usize - ptr as usize },\n        52usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_cellular_status_v1),\n            \"::\",\n            stringify!(dl_max_bandwidth)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).config_inactivity_time) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_cellular_status_v1),\n            \"::\",\n            stringify!(config_inactivity_time)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).config_backoff_time) as usize - ptr as usize },\n        60usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_cellular_status_v1),\n            \"::\",\n            stringify!(config_backoff_time)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mss_recommended) as usize - ptr as usize },\n        64usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_cellular_status_v1),\n            \"::\",\n            stringify!(mss_recommended)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).reserved_1) as usize - ptr as usize },\n        66usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_cellular_status_v1),\n            \"::\",\n            stringify!(reserved_1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).reserved_2) as usize - ptr as usize },\n        68usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_cellular_status_v1),\n            \"::\",\n            stringify!(reserved_2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).reserved_3) as usize - ptr as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_cellular_status_v1),\n            \"::\",\n            stringify!(reserved_3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).reserved_4) as usize - ptr as usize },\n        80usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_cellular_status_v1),\n            \"::\",\n            stringify!(reserved_4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).reserved_5) as usize - ptr as usize },\n        88usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_cellular_status_v1),\n            \"::\",\n            stringify!(reserved_5)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).reserved_6) as usize - ptr as usize },\n        96usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_cellular_status_v1),\n            \"::\",\n            stringify!(reserved_6)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct if_cellular_status {\n    pub if_cell_u: if_cellular_status__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union if_cellular_status__bindgen_ty_1 {\n    pub if_status_v1: if_cellular_status_v1,\n}\n#[test]\nfn bindgen_test_layout_if_cellular_status__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<if_cellular_status__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_cellular_status__bindgen_ty_1>(),\n        104usize,\n        concat!(\"Size of: \", stringify!(if_cellular_status__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_cellular_status__bindgen_ty_1>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(if_cellular_status__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).if_status_v1) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_cellular_status__bindgen_ty_1),\n            \"::\",\n            stringify!(if_status_v1)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_if_cellular_status() {\n    const UNINIT: ::std::mem::MaybeUninit<if_cellular_status> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_cellular_status>(),\n        104usize,\n        concat!(\"Size of: \", stringify!(if_cellular_status))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_cellular_status>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(if_cellular_status))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).if_cell_u) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_cellular_status),\n            \"::\",\n            stringify!(if_cell_u)\n        )\n    );\n}\n#[repr(C, packed)]\n#[derive(Debug, Copy, Clone)]\npub struct if_wifi_status_v1 {\n    pub valid_bitmask: u_int32_t,\n    pub link_quality_metric: u_int32_t,\n    pub ul_effective_bandwidth: u_int32_t,\n    pub ul_max_bandwidth: u_int32_t,\n    pub ul_min_latency: u_int32_t,\n    pub ul_effective_latency: u_int32_t,\n    pub ul_max_latency: u_int32_t,\n    pub ul_retxt_level: u_int32_t,\n    pub ul_bytes_lost: u_int32_t,\n    pub ul_error_rate: u_int32_t,\n    pub dl_effective_bandwidth: u_int32_t,\n    pub dl_max_bandwidth: u_int32_t,\n    pub dl_min_latency: u_int32_t,\n    pub dl_effective_latency: u_int32_t,\n    pub dl_max_latency: u_int32_t,\n    pub dl_error_rate: u_int32_t,\n    pub config_frequency: u_int32_t,\n    pub config_multicast_rate: u_int32_t,\n    pub scan_count: u_int32_t,\n    pub scan_duration: u_int32_t,\n    pub reserved_1: u_int64_t,\n    pub reserved_2: u_int64_t,\n    pub reserved_3: u_int64_t,\n    pub reserved_4: u_int64_t,\n}\n#[test]\nfn bindgen_test_layout_if_wifi_status_v1() {\n    const UNINIT: ::std::mem::MaybeUninit<if_wifi_status_v1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_wifi_status_v1>(),\n        112usize,\n        concat!(\"Size of: \", stringify!(if_wifi_status_v1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_wifi_status_v1>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(if_wifi_status_v1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).valid_bitmask) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_wifi_status_v1),\n            \"::\",\n            stringify!(valid_bitmask)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).link_quality_metric) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_wifi_status_v1),\n            \"::\",\n            stringify!(link_quality_metric)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ul_effective_bandwidth) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_wifi_status_v1),\n            \"::\",\n            stringify!(ul_effective_bandwidth)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ul_max_bandwidth) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_wifi_status_v1),\n            \"::\",\n            stringify!(ul_max_bandwidth)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ul_min_latency) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_wifi_status_v1),\n            \"::\",\n            stringify!(ul_min_latency)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ul_effective_latency) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_wifi_status_v1),\n            \"::\",\n            stringify!(ul_effective_latency)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ul_max_latency) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_wifi_status_v1),\n            \"::\",\n            stringify!(ul_max_latency)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ul_retxt_level) as usize - ptr as usize },\n        28usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_wifi_status_v1),\n            \"::\",\n            stringify!(ul_retxt_level)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ul_bytes_lost) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_wifi_status_v1),\n            \"::\",\n            stringify!(ul_bytes_lost)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ul_error_rate) as usize - ptr as usize },\n        36usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_wifi_status_v1),\n            \"::\",\n            stringify!(ul_error_rate)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dl_effective_bandwidth) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_wifi_status_v1),\n            \"::\",\n            stringify!(dl_effective_bandwidth)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dl_max_bandwidth) as usize - ptr as usize },\n        44usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_wifi_status_v1),\n            \"::\",\n            stringify!(dl_max_bandwidth)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dl_min_latency) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_wifi_status_v1),\n            \"::\",\n            stringify!(dl_min_latency)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dl_effective_latency) as usize - ptr as usize },\n        52usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_wifi_status_v1),\n            \"::\",\n            stringify!(dl_effective_latency)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dl_max_latency) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_wifi_status_v1),\n            \"::\",\n            stringify!(dl_max_latency)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dl_error_rate) as usize - ptr as usize },\n        60usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_wifi_status_v1),\n            \"::\",\n            stringify!(dl_error_rate)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).config_frequency) as usize - ptr as usize },\n        64usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_wifi_status_v1),\n            \"::\",\n            stringify!(config_frequency)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).config_multicast_rate) as usize - ptr as usize },\n        68usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_wifi_status_v1),\n            \"::\",\n            stringify!(config_multicast_rate)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scan_count) as usize - ptr as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_wifi_status_v1),\n            \"::\",\n            stringify!(scan_count)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scan_duration) as usize - ptr as usize },\n        76usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_wifi_status_v1),\n            \"::\",\n            stringify!(scan_duration)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).reserved_1) as usize - ptr as usize },\n        80usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_wifi_status_v1),\n            \"::\",\n            stringify!(reserved_1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).reserved_2) as usize - ptr as usize },\n        88usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_wifi_status_v1),\n            \"::\",\n            stringify!(reserved_2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).reserved_3) as usize - ptr as usize },\n        96usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_wifi_status_v1),\n            \"::\",\n            stringify!(reserved_3)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).reserved_4) as usize - ptr as usize },\n        104usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_wifi_status_v1),\n            \"::\",\n            stringify!(reserved_4)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct if_wifi_status {\n    pub if_wifi_u: if_wifi_status__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union if_wifi_status__bindgen_ty_1 {\n    pub if_status_v1: if_wifi_status_v1,\n}\n#[test]\nfn bindgen_test_layout_if_wifi_status__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<if_wifi_status__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_wifi_status__bindgen_ty_1>(),\n        112usize,\n        concat!(\"Size of: \", stringify!(if_wifi_status__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_wifi_status__bindgen_ty_1>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(if_wifi_status__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).if_status_v1) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_wifi_status__bindgen_ty_1),\n            \"::\",\n            stringify!(if_status_v1)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_if_wifi_status() {\n    const UNINIT: ::std::mem::MaybeUninit<if_wifi_status> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_wifi_status>(),\n        112usize,\n        concat!(\"Size of: \", stringify!(if_wifi_status))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_wifi_status>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(if_wifi_status))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).if_wifi_u) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_wifi_status),\n            \"::\",\n            stringify!(if_wifi_u)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct if_link_status {\n    pub ifsr_version: u_int32_t,\n    pub ifsr_len: u_int32_t,\n    pub ifsr_u: if_link_status__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union if_link_status__bindgen_ty_1 {\n    pub ifsr_cell: if_cellular_status,\n    pub ifsr_wifi: if_wifi_status,\n}\n#[test]\nfn bindgen_test_layout_if_link_status__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<if_link_status__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_link_status__bindgen_ty_1>(),\n        112usize,\n        concat!(\"Size of: \", stringify!(if_link_status__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_link_status__bindgen_ty_1>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(if_link_status__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifsr_cell) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_link_status__bindgen_ty_1),\n            \"::\",\n            stringify!(ifsr_cell)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifsr_wifi) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_link_status__bindgen_ty_1),\n            \"::\",\n            stringify!(ifsr_wifi)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_if_link_status() {\n    const UNINIT: ::std::mem::MaybeUninit<if_link_status> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_link_status>(),\n        120usize,\n        concat!(\"Size of: \", stringify!(if_link_status))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_link_status>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(if_link_status))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifsr_version) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_link_status),\n            \"::\",\n            stringify!(ifsr_version)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifsr_len) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_link_status),\n            \"::\",\n            stringify!(ifsr_len)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifsr_u) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_link_status),\n            \"::\",\n            stringify!(ifsr_u)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct if_interface_state {\n    pub valid_bitmask: u_int8_t,\n    pub rrc_state: u_int8_t,\n    pub lqm_state: i8,\n    pub interface_availability: u_int8_t,\n}\n#[test]\nfn bindgen_test_layout_if_interface_state() {\n    const UNINIT: ::std::mem::MaybeUninit<if_interface_state> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_interface_state>(),\n        4usize,\n        concat!(\"Size of: \", stringify!(if_interface_state))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_interface_state>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(if_interface_state))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).valid_bitmask) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_interface_state),\n            \"::\",\n            stringify!(valid_bitmask)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rrc_state) as usize - ptr as usize },\n        1usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_interface_state),\n            \"::\",\n            stringify!(rrc_state)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lqm_state) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_interface_state),\n            \"::\",\n            stringify!(lqm_state)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).interface_availability) as usize - ptr as usize },\n        3usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_interface_state),\n            \"::\",\n            stringify!(interface_availability)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct chain_len_stats {\n    pub cls_one: u64,\n    pub cls_two: u64,\n    pub cls_three: u64,\n    pub cls_four: u64,\n    pub cls_five_or_more: u64,\n}\n#[test]\nfn bindgen_test_layout_chain_len_stats() {\n    const UNINIT: ::std::mem::MaybeUninit<chain_len_stats> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<chain_len_stats>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(chain_len_stats))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<chain_len_stats>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(chain_len_stats))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cls_one) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(chain_len_stats),\n            \"::\",\n            stringify!(cls_one)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cls_two) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(chain_len_stats),\n            \"::\",\n            stringify!(cls_two)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cls_three) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(chain_len_stats),\n            \"::\",\n            stringify!(cls_three)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cls_four) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(chain_len_stats),\n            \"::\",\n            stringify!(cls_four)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cls_five_or_more) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(chain_len_stats),\n            \"::\",\n            stringify!(cls_five_or_more)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ifnet_interface_advisory {\n    pub version: u8,\n    pub direction: u8,\n    pub _reserved: u16,\n    pub rate_trend_suggestion: i32,\n    pub timestamp: u64,\n    pub max_bandwidth: u64,\n    pub total_byte_count: u64,\n    pub average_throughput: u64,\n    pub flushable_queue_size: u32,\n    pub non_flushable_queue_size: u32,\n    pub average_delay: u32,\n}\n#[test]\nfn bindgen_test_layout_ifnet_interface_advisory() {\n    const UNINIT: ::std::mem::MaybeUninit<ifnet_interface_advisory> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifnet_interface_advisory>(),\n        56usize,\n        concat!(\"Size of: \", stringify!(ifnet_interface_advisory))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifnet_interface_advisory>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(ifnet_interface_advisory))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).version) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_interface_advisory),\n            \"::\",\n            stringify!(version)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).direction) as usize - ptr as usize },\n        1usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_interface_advisory),\n            \"::\",\n            stringify!(direction)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._reserved) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_interface_advisory),\n            \"::\",\n            stringify!(_reserved)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rate_trend_suggestion) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_interface_advisory),\n            \"::\",\n            stringify!(rate_trend_suggestion)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).timestamp) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_interface_advisory),\n            \"::\",\n            stringify!(timestamp)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_bandwidth) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_interface_advisory),\n            \"::\",\n            stringify!(max_bandwidth)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).total_byte_count) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_interface_advisory),\n            \"::\",\n            stringify!(total_byte_count)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).average_throughput) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_interface_advisory),\n            \"::\",\n            stringify!(average_throughput)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flushable_queue_size) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_interface_advisory),\n            \"::\",\n            stringify!(flushable_queue_size)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).non_flushable_queue_size) as usize - ptr as usize },\n        44usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_interface_advisory),\n            \"::\",\n            stringify!(non_flushable_queue_size)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).average_delay) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifnet_interface_advisory),\n            \"::\",\n            stringify!(average_delay)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ifqueue {\n    pub ifq_head: *mut ::std::os::raw::c_void,\n    pub ifq_tail: *mut ::std::os::raw::c_void,\n    pub ifq_len: ::std::os::raw::c_int,\n    pub ifq_maxlen: ::std::os::raw::c_int,\n    pub ifq_drops: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_ifqueue() {\n    const UNINIT: ::std::mem::MaybeUninit<ifqueue> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifqueue>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(ifqueue))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifqueue>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(ifqueue))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifq_head) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(ifqueue), \"::\", stringify!(ifq_head))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifq_tail) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(ifqueue), \"::\", stringify!(ifq_tail))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifq_len) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(ifqueue), \"::\", stringify!(ifq_len))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifq_maxlen) as usize - ptr as usize },\n        20usize,\n        concat!(\"Offset of field: \", stringify!(ifqueue), \"::\", stringify!(ifq_maxlen))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifq_drops) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(ifqueue), \"::\", stringify!(ifq_drops))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union sockaddr_union {\n    pub sa: sockaddr,\n    pub sin: sockaddr_in,\n    pub sin6: sockaddr_in6,\n}\n#[test]\nfn bindgen_test_layout_sockaddr_union() {\n    const UNINIT: ::std::mem::MaybeUninit<sockaddr_union> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sockaddr_union>(),\n        28usize,\n        concat!(\"Size of: \", stringify!(sockaddr_union))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sockaddr_union>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(sockaddr_union))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sa) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr_union), \"::\", stringify!(sa))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr_union), \"::\", stringify!(sin))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin6) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr_union), \"::\", stringify!(sin6))\n    );\n}\npub const PF_INOUT: _bindgen_ty_1 = 0;\npub const PF_IN: _bindgen_ty_1 = 1;\npub const PF_OUT: _bindgen_ty_1 = 2;\npub type _bindgen_ty_1 = ::std::os::raw::c_uint;\npub const PF_PASS: _bindgen_ty_2 = 0;\npub const PF_DROP: _bindgen_ty_2 = 1;\npub const PF_SCRUB: _bindgen_ty_2 = 2;\npub const PF_NOSCRUB: _bindgen_ty_2 = 3;\npub const PF_NAT: _bindgen_ty_2 = 4;\npub const PF_NONAT: _bindgen_ty_2 = 5;\npub const PF_BINAT: _bindgen_ty_2 = 6;\npub const PF_NOBINAT: _bindgen_ty_2 = 7;\npub const PF_RDR: _bindgen_ty_2 = 8;\npub const PF_NORDR: _bindgen_ty_2 = 9;\npub const PF_SYNPROXY_DROP: _bindgen_ty_2 = 10;\npub const PF_DUMMYNET: _bindgen_ty_2 = 11;\npub const PF_NODUMMYNET: _bindgen_ty_2 = 12;\npub const PF_NAT64: _bindgen_ty_2 = 13;\npub const PF_NONAT64: _bindgen_ty_2 = 14;\npub type _bindgen_ty_2 = ::std::os::raw::c_uint;\npub const PF_RULESET_SCRUB: _bindgen_ty_3 = 0;\npub const PF_RULESET_FILTER: _bindgen_ty_3 = 1;\npub const PF_RULESET_NAT: _bindgen_ty_3 = 2;\npub const PF_RULESET_BINAT: _bindgen_ty_3 = 3;\npub const PF_RULESET_RDR: _bindgen_ty_3 = 4;\npub const PF_RULESET_DUMMYNET: _bindgen_ty_3 = 5;\npub const PF_RULESET_MAX: _bindgen_ty_3 = 6;\npub type _bindgen_ty_3 = ::std::os::raw::c_uint;\npub const PF_OP_NONE: _bindgen_ty_4 = 0;\npub const PF_OP_IRG: _bindgen_ty_4 = 1;\npub const PF_OP_EQ: _bindgen_ty_4 = 2;\npub const PF_OP_NE: _bindgen_ty_4 = 3;\npub const PF_OP_LT: _bindgen_ty_4 = 4;\npub const PF_OP_LE: _bindgen_ty_4 = 5;\npub const PF_OP_GT: _bindgen_ty_4 = 6;\npub const PF_OP_GE: _bindgen_ty_4 = 7;\npub const PF_OP_XRG: _bindgen_ty_4 = 8;\npub const PF_OP_RRG: _bindgen_ty_4 = 9;\npub type _bindgen_ty_4 = ::std::os::raw::c_uint;\npub const PF_DEBUG_NONE: _bindgen_ty_5 = 0;\npub const PF_DEBUG_URGENT: _bindgen_ty_5 = 1;\npub const PF_DEBUG_MISC: _bindgen_ty_5 = 2;\npub const PF_DEBUG_NOISY: _bindgen_ty_5 = 3;\npub type _bindgen_ty_5 = ::std::os::raw::c_uint;\npub const PF_CHANGE_NONE: _bindgen_ty_6 = 0;\npub const PF_CHANGE_ADD_HEAD: _bindgen_ty_6 = 1;\npub const PF_CHANGE_ADD_TAIL: _bindgen_ty_6 = 2;\npub const PF_CHANGE_ADD_BEFORE: _bindgen_ty_6 = 3;\npub const PF_CHANGE_ADD_AFTER: _bindgen_ty_6 = 4;\npub const PF_CHANGE_REMOVE: _bindgen_ty_6 = 5;\npub const PF_CHANGE_GET_TICKET: _bindgen_ty_6 = 6;\npub type _bindgen_ty_6 = ::std::os::raw::c_uint;\npub const PF_GET_NONE: _bindgen_ty_7 = 0;\npub const PF_GET_CLR_CNTR: _bindgen_ty_7 = 1;\npub type _bindgen_ty_7 = ::std::os::raw::c_uint;\npub const PFTM_TCP_FIRST_PACKET: _bindgen_ty_8 = 0;\npub const PFTM_TCP_OPENING: _bindgen_ty_8 = 1;\npub const PFTM_TCP_ESTABLISHED: _bindgen_ty_8 = 2;\npub const PFTM_TCP_CLOSING: _bindgen_ty_8 = 3;\npub const PFTM_TCP_FIN_WAIT: _bindgen_ty_8 = 4;\npub const PFTM_TCP_CLOSED: _bindgen_ty_8 = 5;\npub const PFTM_UDP_FIRST_PACKET: _bindgen_ty_8 = 6;\npub const PFTM_UDP_SINGLE: _bindgen_ty_8 = 7;\npub const PFTM_UDP_MULTIPLE: _bindgen_ty_8 = 8;\npub const PFTM_ICMP_FIRST_PACKET: _bindgen_ty_8 = 9;\npub const PFTM_ICMP_ERROR_REPLY: _bindgen_ty_8 = 10;\npub const PFTM_GREv1_FIRST_PACKET: _bindgen_ty_8 = 11;\npub const PFTM_GREv1_INITIATING: _bindgen_ty_8 = 12;\npub const PFTM_GREv1_ESTABLISHED: _bindgen_ty_8 = 13;\npub const PFTM_ESP_FIRST_PACKET: _bindgen_ty_8 = 14;\npub const PFTM_ESP_INITIATING: _bindgen_ty_8 = 15;\npub const PFTM_ESP_ESTABLISHED: _bindgen_ty_8 = 16;\npub const PFTM_OTHER_FIRST_PACKET: _bindgen_ty_8 = 17;\npub const PFTM_OTHER_SINGLE: _bindgen_ty_8 = 18;\npub const PFTM_OTHER_MULTIPLE: _bindgen_ty_8 = 19;\npub const PFTM_FRAG: _bindgen_ty_8 = 20;\npub const PFTM_INTERVAL: _bindgen_ty_8 = 21;\npub const PFTM_ADAPTIVE_START: _bindgen_ty_8 = 22;\npub const PFTM_ADAPTIVE_END: _bindgen_ty_8 = 23;\npub const PFTM_SRC_NODE: _bindgen_ty_8 = 24;\npub const PFTM_TS_DIFF: _bindgen_ty_8 = 25;\npub const PFTM_MAX: _bindgen_ty_8 = 26;\npub const PFTM_PURGE: _bindgen_ty_8 = 27;\npub const PFTM_UNLINKED: _bindgen_ty_8 = 28;\npub type _bindgen_ty_8 = ::std::os::raw::c_uint;\npub const PF_NOPFROUTE: _bindgen_ty_9 = 0;\npub const PF_FASTROUTE: _bindgen_ty_9 = 1;\npub const PF_ROUTETO: _bindgen_ty_9 = 2;\npub const PF_DUPTO: _bindgen_ty_9 = 3;\npub const PF_REPLYTO: _bindgen_ty_9 = 4;\npub type _bindgen_ty_9 = ::std::os::raw::c_uint;\npub const PF_LIMIT_STATES: _bindgen_ty_10 = 0;\npub const PF_LIMIT_APP_STATES: _bindgen_ty_10 = 1;\npub const PF_LIMIT_SRC_NODES: _bindgen_ty_10 = 2;\npub const PF_LIMIT_FRAGS: _bindgen_ty_10 = 3;\npub const PF_LIMIT_TABLES: _bindgen_ty_10 = 4;\npub const PF_LIMIT_TABLE_ENTRIES: _bindgen_ty_10 = 5;\npub const PF_LIMIT_MAX: _bindgen_ty_10 = 6;\npub type _bindgen_ty_10 = ::std::os::raw::c_uint;\npub const PF_POOL_NONE: _bindgen_ty_11 = 0;\npub const PF_POOL_BITMASK: _bindgen_ty_11 = 1;\npub const PF_POOL_RANDOM: _bindgen_ty_11 = 2;\npub const PF_POOL_SRCHASH: _bindgen_ty_11 = 3;\npub const PF_POOL_ROUNDROBIN: _bindgen_ty_11 = 4;\npub type _bindgen_ty_11 = ::std::os::raw::c_uint;\npub const PF_ADDR_ADDRMASK: _bindgen_ty_12 = 0;\npub const PF_ADDR_NOROUTE: _bindgen_ty_12 = 1;\npub const PF_ADDR_DYNIFTL: _bindgen_ty_12 = 2;\npub const PF_ADDR_TABLE: _bindgen_ty_12 = 3;\npub const PF_ADDR_RTLABEL: _bindgen_ty_12 = 4;\npub const PF_ADDR_URPFFAILED: _bindgen_ty_12 = 5;\npub const PF_ADDR_RANGE: _bindgen_ty_12 = 6;\npub type _bindgen_ty_12 = ::std::os::raw::c_uint;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_addr {\n    pub pfa: pf_addr__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pf_addr__bindgen_ty_1 {\n    pub _v4addr: in_addr,\n    pub _v6addr: in6_addr,\n    pub _addr8: [u_int8_t; 16usize],\n    pub _addr16: [u_int16_t; 8usize],\n    pub _addr32: [u_int32_t; 4usize],\n}\n#[test]\nfn bindgen_test_layout_pf_addr__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_addr__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_addr__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_addr__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_addr__bindgen_ty_1>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_addr__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._v4addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(_v4addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._v6addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(_v6addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._addr8) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(_addr8)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._addr16) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(_addr16)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._addr32) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(_addr32)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_addr() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_addr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_addr>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_addr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_addr>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfa) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_addr), \"::\", stringify!(pfa))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_addr_wrap {\n    pub v: pf_addr_wrap__bindgen_ty_1,\n    pub p: pf_addr_wrap__bindgen_ty_2,\n    pub type_: u_int8_t,\n    pub iflags: u_int8_t,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pf_addr_wrap__bindgen_ty_1 {\n    pub a: pf_addr_wrap__bindgen_ty_1__bindgen_ty_1,\n    pub ifname: [::std::os::raw::c_char; 16usize],\n    pub tblname: [::std::os::raw::c_char; 32usize],\n    pub rtlabelname: [::std::os::raw::c_char; 32usize],\n    pub rtlabel: u_int32_t,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_addr_wrap__bindgen_ty_1__bindgen_ty_1 {\n    pub addr: pf_addr,\n    pub mask: pf_addr,\n}\n#[test]\nfn bindgen_test_layout_pf_addr_wrap__bindgen_ty_1__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_addr_wrap__bindgen_ty_1__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_addr_wrap__bindgen_ty_1__bindgen_ty_1>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(pf_addr_wrap__bindgen_ty_1__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_addr_wrap__bindgen_ty_1__bindgen_ty_1>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_addr_wrap__bindgen_ty_1__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mask) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(mask)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_addr_wrap__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_addr_wrap__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_addr_wrap__bindgen_ty_1>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(pf_addr_wrap__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_addr_wrap__bindgen_ty_1>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_addr_wrap__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_1),\n            \"::\",\n            stringify!(a)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifname) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_1),\n            \"::\",\n            stringify!(ifname)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tblname) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_1),\n            \"::\",\n            stringify!(tblname)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtlabelname) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_1),\n            \"::\",\n            stringify!(rtlabelname)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtlabel) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_1),\n            \"::\",\n            stringify!(rtlabel)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pf_addr_wrap__bindgen_ty_2 {\n    pub dyn_: *mut ::std::os::raw::c_void,\n    pub tbl: *mut ::std::os::raw::c_void,\n    pub dyncnt: ::std::os::raw::c_int,\n    pub tblcnt: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_pf_addr_wrap__bindgen_ty_2() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_addr_wrap__bindgen_ty_2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_addr_wrap__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_addr_wrap__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_addr_wrap__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_addr_wrap__bindgen_ty_2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dyn_) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_2),\n            \"::\",\n            stringify!(dyn_)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tbl) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_2),\n            \"::\",\n            stringify!(tbl)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dyncnt) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_2),\n            \"::\",\n            stringify!(dyncnt)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tblcnt) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_2),\n            \"::\",\n            stringify!(tblcnt)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_addr_wrap() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_addr_wrap> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_addr_wrap>(),\n        48usize,\n        concat!(\"Size of: \", stringify!(pf_addr_wrap))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_addr_wrap>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_addr_wrap))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).v) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_addr_wrap), \"::\", stringify!(v))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).p) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(pf_addr_wrap), \"::\", stringify!(p))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).type_) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(pf_addr_wrap), \"::\", stringify!(type_))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).iflags) as usize - ptr as usize },\n        41usize,\n        concat!(\"Offset of field: \", stringify!(pf_addr_wrap), \"::\", stringify!(iflags))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_port_range {\n    pub port: [u_int16_t; 2usize],\n    pub op: u_int8_t,\n}\n#[test]\nfn bindgen_test_layout_pf_port_range() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_port_range> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_port_range>(),\n        6usize,\n        concat!(\"Size of: \", stringify!(pf_port_range))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_port_range>(),\n        2usize,\n        concat!(\"Alignment of \", stringify!(pf_port_range))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).port) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_port_range), \"::\", stringify!(port))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).op) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(pf_port_range), \"::\", stringify!(op))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pf_rule_xport {\n    pub range: pf_port_range,\n    pub call_id: u_int16_t,\n    pub spi: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_pf_rule_xport() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rule_xport> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rule_xport>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_rule_xport))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rule_xport>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_rule_xport))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).range) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_xport), \"::\", stringify!(range))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).call_id) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule_xport),\n            \"::\",\n            stringify!(call_id)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).spi) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_xport), \"::\", stringify!(spi))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_rule_uid {\n    pub uid: [uid_t; 2usize],\n    pub op: u_int8_t,\n    pub _pad: [u_int8_t; 3usize],\n}\n#[test]\nfn bindgen_test_layout_pf_rule_uid() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rule_uid> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rule_uid>(),\n        12usize,\n        concat!(\"Size of: \", stringify!(pf_rule_uid))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rule_uid>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_rule_uid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uid) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_uid), \"::\", stringify!(uid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).op) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_uid), \"::\", stringify!(op))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._pad) as usize - ptr as usize },\n        9usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_uid), \"::\", stringify!(_pad))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_rule_gid {\n    pub gid: [uid_t; 2usize],\n    pub op: u_int8_t,\n    pub _pad: [u_int8_t; 3usize],\n}\n#[test]\nfn bindgen_test_layout_pf_rule_gid() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rule_gid> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rule_gid>(),\n        12usize,\n        concat!(\"Size of: \", stringify!(pf_rule_gid))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rule_gid>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_rule_gid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).gid) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_gid), \"::\", stringify!(gid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).op) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_gid), \"::\", stringify!(op))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._pad) as usize - ptr as usize },\n        9usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_gid), \"::\", stringify!(_pad))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_rule_addr {\n    pub addr: pf_addr_wrap,\n    pub xport: pf_rule_xport,\n    pub neg: u_int8_t,\n}\n#[test]\nfn bindgen_test_layout_pf_rule_addr() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rule_addr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rule_addr>(),\n        64usize,\n        concat!(\"Size of: \", stringify!(pf_rule_addr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rule_addr>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_rule_addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_addr), \"::\", stringify!(addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).xport) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_addr), \"::\", stringify!(xport))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).neg) as usize - ptr as usize },\n        56usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_addr), \"::\", stringify!(neg))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_pooladdr {\n    pub addr: pf_addr_wrap,\n    pub entries: pf_pooladdr__bindgen_ty_1,\n    pub ifname: [::std::os::raw::c_char; 16usize],\n    pub kif: *mut ::std::os::raw::c_void,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_pooladdr__bindgen_ty_1 {\n    pub tqe_next: *mut pf_pooladdr,\n    pub tqe_prev: *mut *mut pf_pooladdr,\n}\n#[test]\nfn bindgen_test_layout_pf_pooladdr__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_pooladdr__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_pooladdr__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_pooladdr__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_pooladdr__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_pooladdr__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqe_next) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_pooladdr__bindgen_ty_1),\n            \"::\",\n            stringify!(tqe_next)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqe_prev) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_pooladdr__bindgen_ty_1),\n            \"::\",\n            stringify!(tqe_prev)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_pooladdr() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_pooladdr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_pooladdr>(),\n        88usize,\n        concat!(\"Size of: \", stringify!(pf_pooladdr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_pooladdr>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_pooladdr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_pooladdr), \"::\", stringify!(addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).entries) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(pf_pooladdr), \"::\", stringify!(entries))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifname) as usize - ptr as usize },\n        64usize,\n        concat!(\"Offset of field: \", stringify!(pf_pooladdr), \"::\", stringify!(ifname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).kif) as usize - ptr as usize },\n        80usize,\n        concat!(\"Offset of field: \", stringify!(pf_pooladdr), \"::\", stringify!(kif))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_palist {\n    pub tqh_first: *mut pf_pooladdr,\n    pub tqh_last: *mut *mut pf_pooladdr,\n}\n#[test]\nfn bindgen_test_layout_pf_palist() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_palist> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_palist>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_palist))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_palist>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_palist))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqh_first) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_palist), \"::\", stringify!(tqh_first))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqh_last) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pf_palist), \"::\", stringify!(tqh_last))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_poolhashkey {\n    pub pfk: pf_poolhashkey__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pf_poolhashkey__bindgen_ty_1 {\n    pub key8: [u_int8_t; 16usize],\n    pub key16: [u_int16_t; 8usize],\n    pub key32: [u_int32_t; 4usize],\n}\n#[test]\nfn bindgen_test_layout_pf_poolhashkey__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_poolhashkey__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_poolhashkey__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_poolhashkey__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_poolhashkey__bindgen_ty_1>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_poolhashkey__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).key8) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_poolhashkey__bindgen_ty_1),\n            \"::\",\n            stringify!(key8)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).key16) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_poolhashkey__bindgen_ty_1),\n            \"::\",\n            stringify!(key16)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).key32) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_poolhashkey__bindgen_ty_1),\n            \"::\",\n            stringify!(key32)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_poolhashkey() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_poolhashkey> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_poolhashkey>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_poolhashkey))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_poolhashkey>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_poolhashkey))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfk) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_poolhashkey), \"::\", stringify!(pfk))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_pool {\n    pub list: pf_palist,\n    pub cur: *mut ::std::os::raw::c_void,\n    pub key: pf_poolhashkey,\n    pub counter: pf_addr,\n    pub tblidx: ::std::os::raw::c_int,\n    pub proxy_port: [u_int16_t; 2usize],\n    pub port_op: u_int8_t,\n    pub opts: u_int8_t,\n    pub af: sa_family_t,\n}\n#[test]\nfn bindgen_test_layout_pf_pool() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_pool> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_pool>(),\n        72usize,\n        concat!(\"Size of: \", stringify!(pf_pool))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_pool>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_pool))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).list) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_pool), \"::\", stringify!(list))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cur) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pf_pool), \"::\", stringify!(cur))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).key) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(pf_pool), \"::\", stringify!(key))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).counter) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(pf_pool), \"::\", stringify!(counter))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tblidx) as usize - ptr as usize },\n        56usize,\n        concat!(\"Offset of field: \", stringify!(pf_pool), \"::\", stringify!(tblidx))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).proxy_port) as usize - ptr as usize },\n        60usize,\n        concat!(\"Offset of field: \", stringify!(pf_pool), \"::\", stringify!(proxy_port))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).port_op) as usize - ptr as usize },\n        64usize,\n        concat!(\"Offset of field: \", stringify!(pf_pool), \"::\", stringify!(port_op))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).opts) as usize - ptr as usize },\n        65usize,\n        concat!(\"Offset of field: \", stringify!(pf_pool), \"::\", stringify!(opts))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).af) as usize - ptr as usize },\n        66usize,\n        concat!(\"Offset of field: \", stringify!(pf_pool), \"::\", stringify!(af))\n    );\n}\npub type pf_osfp_t = u_int32_t;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_osfp_entry {\n    pub fp_entry: pf_osfp_entry__bindgen_ty_1,\n    pub fp_os: pf_osfp_t,\n    pub fp_enflags: ::std::os::raw::c_int,\n    pub fp_class_nm: [::std::os::raw::c_char; 32usize],\n    pub fp_version_nm: [::std::os::raw::c_char; 32usize],\n    pub fp_subtype_nm: [::std::os::raw::c_char; 32usize],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_osfp_entry__bindgen_ty_1 {\n    pub sle_next: *mut pf_osfp_entry,\n}\n#[test]\nfn bindgen_test_layout_pf_osfp_entry__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_osfp_entry__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_osfp_entry__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_osfp_entry__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_osfp_entry__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_osfp_entry__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sle_next) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_entry__bindgen_ty_1),\n            \"::\",\n            stringify!(sle_next)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_osfp_entry() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_osfp_entry> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_osfp_entry>(),\n        112usize,\n        concat!(\"Size of: \", stringify!(pf_osfp_entry))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_osfp_entry>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_osfp_entry))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_entry) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_entry),\n            \"::\",\n            stringify!(fp_entry)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_os) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pf_osfp_entry), \"::\", stringify!(fp_os))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_enflags) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_entry),\n            \"::\",\n            stringify!(fp_enflags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_class_nm) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_entry),\n            \"::\",\n            stringify!(fp_class_nm)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_version_nm) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_entry),\n            \"::\",\n            stringify!(fp_version_nm)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_subtype_nm) as usize - ptr as usize },\n        80usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_entry),\n            \"::\",\n            stringify!(fp_subtype_nm)\n        )\n    );\n}\npub type pf_tcpopts_t = u_int64_t;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_os_fingerprint {\n    pub fp_oses: pf_os_fingerprint_pf_osfp_enlist,\n    pub fp_tcpopts: pf_tcpopts_t,\n    pub fp_wsize: u_int16_t,\n    pub fp_psize: u_int16_t,\n    pub fp_mss: u_int16_t,\n    pub fp_flags: u_int16_t,\n    pub fp_optcnt: u_int8_t,\n    pub fp_wscale: u_int8_t,\n    pub fp_ttl: u_int8_t,\n    pub fp_next: pf_os_fingerprint__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_os_fingerprint_pf_osfp_enlist {\n    pub slh_first: *mut pf_osfp_entry,\n}\n#[test]\nfn bindgen_test_layout_pf_os_fingerprint_pf_osfp_enlist() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_os_fingerprint_pf_osfp_enlist> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_os_fingerprint_pf_osfp_enlist>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_os_fingerprint_pf_osfp_enlist))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_os_fingerprint_pf_osfp_enlist>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_os_fingerprint_pf_osfp_enlist))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).slh_first) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint_pf_osfp_enlist),\n            \"::\",\n            stringify!(slh_first)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_os_fingerprint__bindgen_ty_1 {\n    pub sle_next: *mut pf_os_fingerprint,\n}\n#[test]\nfn bindgen_test_layout_pf_os_fingerprint__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_os_fingerprint__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_os_fingerprint__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_os_fingerprint__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_os_fingerprint__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_os_fingerprint__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sle_next) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint__bindgen_ty_1),\n            \"::\",\n            stringify!(sle_next)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_os_fingerprint() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_os_fingerprint> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_os_fingerprint>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(pf_os_fingerprint))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_os_fingerprint>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_os_fingerprint))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_oses) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_oses)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_tcpopts) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_tcpopts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_wsize) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_wsize)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_psize) as usize - ptr as usize },\n        18usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_psize)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_mss) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_mss)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_flags) as usize - ptr as usize },\n        22usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_optcnt) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_optcnt)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_wscale) as usize - ptr as usize },\n        25usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_wscale)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_ttl) as usize - ptr as usize },\n        26usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_ttl)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_next) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_next)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_osfp_ioctl {\n    pub fp_os: pf_osfp_entry,\n    pub fp_tcpopts: pf_tcpopts_t,\n    pub fp_wsize: u_int16_t,\n    pub fp_psize: u_int16_t,\n    pub fp_mss: u_int16_t,\n    pub fp_flags: u_int16_t,\n    pub fp_optcnt: u_int8_t,\n    pub fp_wscale: u_int8_t,\n    pub fp_ttl: u_int8_t,\n    pub fp_getnum: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_pf_osfp_ioctl() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_osfp_ioctl> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_osfp_ioctl>(),\n        136usize,\n        concat!(\"Size of: \", stringify!(pf_osfp_ioctl))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_osfp_ioctl>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_osfp_ioctl))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_os) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_osfp_ioctl), \"::\", stringify!(fp_os))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_tcpopts) as usize - ptr as usize },\n        112usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_ioctl),\n            \"::\",\n            stringify!(fp_tcpopts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_wsize) as usize - ptr as usize },\n        120usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_ioctl),\n            \"::\",\n            stringify!(fp_wsize)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_psize) as usize - ptr as usize },\n        122usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_ioctl),\n            \"::\",\n            stringify!(fp_psize)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_mss) as usize - ptr as usize },\n        124usize,\n        concat!(\"Offset of field: \", stringify!(pf_osfp_ioctl), \"::\", stringify!(fp_mss))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_flags) as usize - ptr as usize },\n        126usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_ioctl),\n            \"::\",\n            stringify!(fp_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_optcnt) as usize - ptr as usize },\n        128usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_ioctl),\n            \"::\",\n            stringify!(fp_optcnt)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_wscale) as usize - ptr as usize },\n        129usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_ioctl),\n            \"::\",\n            stringify!(fp_wscale)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_ttl) as usize - ptr as usize },\n        130usize,\n        concat!(\"Offset of field: \", stringify!(pf_osfp_ioctl), \"::\", stringify!(fp_ttl))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_getnum) as usize - ptr as usize },\n        132usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_ioctl),\n            \"::\",\n            stringify!(fp_getnum)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pf_rule_ptr {\n    pub ptr: *mut pf_rule,\n    pub nr: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_pf_rule_ptr() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rule_ptr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rule_ptr>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_rule_ptr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rule_ptr>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_rule_ptr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ptr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_ptr), \"::\", stringify!(ptr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_ptr), \"::\", stringify!(nr))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_rule {\n    pub src: pf_rule_addr,\n    pub dst: pf_rule_addr,\n    pub skip: [pf_rule_ptr; 8usize],\n    pub label: [::std::os::raw::c_char; 64usize],\n    pub ifname: [::std::os::raw::c_char; 16usize],\n    pub qname: [::std::os::raw::c_char; 64usize],\n    pub pqname: [::std::os::raw::c_char; 64usize],\n    pub tagname: [::std::os::raw::c_char; 64usize],\n    pub match_tagname: [::std::os::raw::c_char; 64usize],\n    pub overload_tblname: [::std::os::raw::c_char; 32usize],\n    pub entries: pf_rule__bindgen_ty_1,\n    pub rpool: pf_pool,\n    pub evaluations: u_int64_t,\n    pub packets: [u_int64_t; 2usize],\n    pub bytes: [u_int64_t; 2usize],\n    pub ticket: u_int64_t,\n    pub owner: [::std::os::raw::c_char; 64usize],\n    pub priority: u_int32_t,\n    pub kif: *mut ::std::os::raw::c_void,\n    pub anchor: *mut pf_anchor,\n    pub overload_tbl: *mut ::std::os::raw::c_void,\n    pub os_fingerprint: pf_osfp_t,\n    pub rtableid: ::std::os::raw::c_uint,\n    pub timeout: [u_int32_t; 26usize],\n    pub states: u_int32_t,\n    pub max_states: u_int32_t,\n    pub src_nodes: u_int32_t,\n    pub max_src_nodes: u_int32_t,\n    pub max_src_states: u_int32_t,\n    pub max_src_conn: u_int32_t,\n    pub max_src_conn_rate: pf_rule__bindgen_ty_2,\n    pub qid: u_int32_t,\n    pub pqid: u_int32_t,\n    pub rt_listid: u_int32_t,\n    pub nr: u_int32_t,\n    pub prob: u_int32_t,\n    pub cuid: uid_t,\n    pub cpid: pid_t,\n    pub return_icmp: u_int16_t,\n    pub return_icmp6: u_int16_t,\n    pub max_mss: u_int16_t,\n    pub tag: u_int16_t,\n    pub match_tag: u_int16_t,\n    pub uid: pf_rule_uid,\n    pub gid: pf_rule_gid,\n    pub rule_flag: u_int32_t,\n    pub action: u_int8_t,\n    pub direction: u_int8_t,\n    pub log: u_int8_t,\n    pub logif: u_int8_t,\n    pub quick: u_int8_t,\n    pub ifnot: u_int8_t,\n    pub match_tag_not: u_int8_t,\n    pub natpass: u_int8_t,\n    pub keep_state: u_int8_t,\n    pub af: sa_family_t,\n    pub proto: u_int8_t,\n    pub type_: u_int8_t,\n    pub code: u_int8_t,\n    pub flags: u_int8_t,\n    pub flagset: u_int8_t,\n    pub min_ttl: u_int8_t,\n    pub allow_opts: u_int8_t,\n    pub rt: u_int8_t,\n    pub return_ttl: u_int8_t,\n    pub tos: u_int8_t,\n    pub anchor_relative: u_int8_t,\n    pub anchor_wildcard: u_int8_t,\n    pub flush: u_int8_t,\n    pub proto_variant: u_int8_t,\n    pub extfilter: u_int8_t,\n    pub extmap: u_int8_t,\n    pub dnpipe: u_int32_t,\n    pub dntype: u_int32_t,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_rule__bindgen_ty_1 {\n    pub tqe_next: *mut pf_rule,\n    pub tqe_prev: *mut *mut pf_rule,\n}\n#[test]\nfn bindgen_test_layout_pf_rule__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rule__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rule__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_rule__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rule__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_rule__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqe_next) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule__bindgen_ty_1),\n            \"::\",\n            stringify!(tqe_next)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqe_prev) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule__bindgen_ty_1),\n            \"::\",\n            stringify!(tqe_prev)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_rule__bindgen_ty_2 {\n    pub limit: u_int32_t,\n    pub seconds: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_pf_rule__bindgen_ty_2() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rule__bindgen_ty_2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rule__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_rule__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rule__bindgen_ty_2>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_rule__bindgen_ty_2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).limit) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule__bindgen_ty_2),\n            \"::\",\n            stringify!(limit)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).seconds) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule__bindgen_ty_2),\n            \"::\",\n            stringify!(seconds)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_rule() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rule> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rule>(),\n        1040usize,\n        concat!(\"Size of: \", stringify!(pf_rule))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rule>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_rule))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).src) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(src))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dst) as usize - ptr as usize },\n        64usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(dst))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).skip) as usize - ptr as usize },\n        128usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(skip))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).label) as usize - ptr as usize },\n        192usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(label))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifname) as usize - ptr as usize },\n        256usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(ifname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).qname) as usize - ptr as usize },\n        272usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(qname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pqname) as usize - ptr as usize },\n        336usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(pqname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tagname) as usize - ptr as usize },\n        400usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(tagname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).match_tagname) as usize - ptr as usize },\n        464usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule),\n            \"::\",\n            stringify!(match_tagname)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).overload_tblname) as usize - ptr as usize },\n        528usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule),\n            \"::\",\n            stringify!(overload_tblname)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).entries) as usize - ptr as usize },\n        560usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(entries))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rpool) as usize - ptr as usize },\n        576usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(rpool))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).evaluations) as usize - ptr as usize },\n        648usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(evaluations))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).packets) as usize - ptr as usize },\n        656usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(packets))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).bytes) as usize - ptr as usize },\n        672usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(bytes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ticket) as usize - ptr as usize },\n        688usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(ticket))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).owner) as usize - ptr as usize },\n        696usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(owner))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).priority) as usize - ptr as usize },\n        760usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(priority))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).kif) as usize - ptr as usize },\n        768usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(kif))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor) as usize - ptr as usize },\n        776usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(anchor))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).overload_tbl) as usize - ptr as usize },\n        784usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(overload_tbl))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).os_fingerprint) as usize - ptr as usize },\n        792usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule),\n            \"::\",\n            stringify!(os_fingerprint)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtableid) as usize - ptr as usize },\n        796usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(rtableid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).timeout) as usize - ptr as usize },\n        800usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(timeout))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).states) as usize - ptr as usize },\n        904usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(states))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_states) as usize - ptr as usize },\n        908usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(max_states))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).src_nodes) as usize - ptr as usize },\n        912usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(src_nodes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_src_nodes) as usize - ptr as usize },\n        916usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule),\n            \"::\",\n            stringify!(max_src_nodes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_src_states) as usize - ptr as usize },\n        920usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule),\n            \"::\",\n            stringify!(max_src_states)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_src_conn) as usize - ptr as usize },\n        924usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(max_src_conn))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_src_conn_rate) as usize - ptr as usize },\n        928usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule),\n            \"::\",\n            stringify!(max_src_conn_rate)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).qid) as usize - ptr as usize },\n        936usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(qid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pqid) as usize - ptr as usize },\n        940usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(pqid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rt_listid) as usize - ptr as usize },\n        944usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(rt_listid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nr) as usize - ptr as usize },\n        948usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(nr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).prob) as usize - ptr as usize },\n        952usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(prob))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cuid) as usize - ptr as usize },\n        956usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(cuid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cpid) as usize - ptr as usize },\n        960usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(cpid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).return_icmp) as usize - ptr as usize },\n        964usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(return_icmp))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).return_icmp6) as usize - ptr as usize },\n        966usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(return_icmp6))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_mss) as usize - ptr as usize },\n        968usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(max_mss))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tag) as usize - ptr as usize },\n        970usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(tag))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).match_tag) as usize - ptr as usize },\n        972usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(match_tag))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uid) as usize - ptr as usize },\n        976usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(uid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).gid) as usize - ptr as usize },\n        988usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(gid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rule_flag) as usize - ptr as usize },\n        1000usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(rule_flag))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).action) as usize - ptr as usize },\n        1004usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(action))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).direction) as usize - ptr as usize },\n        1005usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(direction))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).log) as usize - ptr as usize },\n        1006usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(log))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).logif) as usize - ptr as usize },\n        1007usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(logif))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).quick) as usize - ptr as usize },\n        1008usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(quick))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifnot) as usize - ptr as usize },\n        1009usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(ifnot))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).match_tag_not) as usize - ptr as usize },\n        1010usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule),\n            \"::\",\n            stringify!(match_tag_not)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).natpass) as usize - ptr as usize },\n        1011usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(natpass))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).keep_state) as usize - ptr as usize },\n        1012usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(keep_state))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).af) as usize - ptr as usize },\n        1013usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(af))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).proto) as usize - ptr as usize },\n        1014usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(proto))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).type_) as usize - ptr as usize },\n        1015usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(type_))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).code) as usize - ptr as usize },\n        1016usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(code))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flags) as usize - ptr as usize },\n        1017usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flagset) as usize - ptr as usize },\n        1018usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(flagset))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).min_ttl) as usize - ptr as usize },\n        1019usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(min_ttl))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).allow_opts) as usize - ptr as usize },\n        1020usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(allow_opts))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rt) as usize - ptr as usize },\n        1021usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(rt))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).return_ttl) as usize - ptr as usize },\n        1022usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(return_ttl))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tos) as usize - ptr as usize },\n        1023usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(tos))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor_relative) as usize - ptr as usize },\n        1024usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule),\n            \"::\",\n            stringify!(anchor_relative)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor_wildcard) as usize - ptr as usize },\n        1025usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule),\n            \"::\",\n            stringify!(anchor_wildcard)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flush) as usize - ptr as usize },\n        1026usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(flush))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).proto_variant) as usize - ptr as usize },\n        1027usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule),\n            \"::\",\n            stringify!(proto_variant)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).extfilter) as usize - ptr as usize },\n        1028usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(extfilter))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).extmap) as usize - ptr as usize },\n        1029usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(extmap))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dnpipe) as usize - ptr as usize },\n        1032usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(dnpipe))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dntype) as usize - ptr as usize },\n        1036usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(dntype))\n    );\n}\npub const pf_extmap_PF_EXTMAP_APD: pf_extmap = 1;\npub const pf_extmap_PF_EXTMAP_AD: pf_extmap = 2;\npub const pf_extmap_PF_EXTMAP_EI: pf_extmap = 3;\npub type pf_extmap = ::std::os::raw::c_uint;\npub const pf_extfilter_PF_EXTFILTER_APD: pf_extfilter = 1;\npub const pf_extfilter_PF_EXTFILTER_AD: pf_extfilter = 2;\npub const pf_extfilter_PF_EXTFILTER_EI: pf_extfilter = 3;\npub type pf_extfilter = ::std::os::raw::c_uint;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_threshold {\n    pub limit: u_int32_t,\n    pub seconds: u_int32_t,\n    pub count: u_int32_t,\n    pub last: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_pf_threshold() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_threshold> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_threshold>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_threshold))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_threshold>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_threshold))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).limit) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_threshold), \"::\", stringify!(limit))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).seconds) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(pf_threshold), \"::\", stringify!(seconds))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).count) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pf_threshold), \"::\", stringify!(count))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).last) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(pf_threshold), \"::\", stringify!(last))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_src_node {\n    pub entry: pf_src_node__bindgen_ty_1,\n    pub addr: pf_addr,\n    pub raddr: pf_addr,\n    pub rule: pf_rule_ptr,\n    pub kif: *mut ::std::os::raw::c_void,\n    pub bytes: [u_int64_t; 2usize],\n    pub packets: [u_int64_t; 2usize],\n    pub states: u_int32_t,\n    pub conn: u_int32_t,\n    pub conn_rate: pf_threshold,\n    pub creation: u_int64_t,\n    pub expire: u_int64_t,\n    pub af: sa_family_t,\n    pub ruletype: u_int8_t,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_src_node__bindgen_ty_1 {\n    pub rbe_left: *mut pf_src_node,\n    pub rbe_right: *mut pf_src_node,\n    pub rbe_parent: *mut pf_src_node,\n}\n#[test]\nfn bindgen_test_layout_pf_src_node__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_src_node__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_src_node__bindgen_ty_1>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(pf_src_node__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_src_node__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_src_node__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_left) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_src_node__bindgen_ty_1),\n            \"::\",\n            stringify!(rbe_left)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_right) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_src_node__bindgen_ty_1),\n            \"::\",\n            stringify!(rbe_right)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_parent) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_src_node__bindgen_ty_1),\n            \"::\",\n            stringify!(rbe_parent)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_src_node() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_src_node> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_src_node>(),\n        152usize,\n        concat!(\"Size of: \", stringify!(pf_src_node))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_src_node>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_src_node))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).entry) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(entry))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).raddr) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(raddr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rule) as usize - ptr as usize },\n        56usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(rule))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).kif) as usize - ptr as usize },\n        64usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(kif))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).bytes) as usize - ptr as usize },\n        72usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(bytes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).packets) as usize - ptr as usize },\n        88usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(packets))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).states) as usize - ptr as usize },\n        104usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(states))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).conn) as usize - ptr as usize },\n        108usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(conn))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).conn_rate) as usize - ptr as usize },\n        112usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_src_node),\n            \"::\",\n            stringify!(conn_rate)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).creation) as usize - ptr as usize },\n        128usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(creation))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).expire) as usize - ptr as usize },\n        136usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(expire))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).af) as usize - ptr as usize },\n        144usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(af))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ruletype) as usize - ptr as usize },\n        145usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(ruletype))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pf_state_xport {\n    pub port: u_int16_t,\n    pub call_id: u_int16_t,\n    pub spi: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_pf_state_xport() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_state_xport> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_state_xport>(),\n        4usize,\n        concat!(\"Size of: \", stringify!(pf_state_xport))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_state_xport>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_state_xport))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).port) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_xport), \"::\", stringify!(port))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).call_id) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_xport),\n            \"::\",\n            stringify!(call_id)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).spi) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_xport), \"::\", stringify!(spi))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_state_host {\n    pub addr: pf_addr,\n    pub xport: pf_state_xport,\n}\n#[test]\nfn bindgen_test_layout_pf_state_host() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_state_host> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_state_host>(),\n        20usize,\n        concat!(\"Size of: \", stringify!(pf_state_host))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_state_host>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_state_host))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_host), \"::\", stringify!(addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).xport) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_host), \"::\", stringify!(xport))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct hook_desc {\n    _unused: [u8; 0],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct hook_desc_head {\n    pub tqh_first: *mut hook_desc,\n    pub tqh_last: *mut *mut hook_desc,\n}\n#[test]\nfn bindgen_test_layout_hook_desc_head() {\n    const UNINIT: ::std::mem::MaybeUninit<hook_desc_head> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<hook_desc_head>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(hook_desc_head))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<hook_desc_head>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(hook_desc_head))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqh_first) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(hook_desc_head),\n            \"::\",\n            stringify!(tqh_first)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqh_last) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(hook_desc_head),\n            \"::\",\n            stringify!(tqh_last)\n        )\n    );\n}\n#[repr(C, packed)]\n#[derive(Debug, Copy, Clone)]\npub struct pfsync_state_scrub {\n    pub pfss_flags: u_int16_t,\n    pub pfss_ttl: u_int8_t,\n    pub scrub_flag: u_int8_t,\n    pub pfss_ts_mod: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_pfsync_state_scrub() {\n    const UNINIT: ::std::mem::MaybeUninit<pfsync_state_scrub> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfsync_state_scrub>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pfsync_state_scrub))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfsync_state_scrub>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(pfsync_state_scrub))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfss_flags) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_scrub),\n            \"::\",\n            stringify!(pfss_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfss_ttl) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_scrub),\n            \"::\",\n            stringify!(pfss_ttl)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scrub_flag) as usize - ptr as usize },\n        3usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_scrub),\n            \"::\",\n            stringify!(scrub_flag)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfss_ts_mod) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_scrub),\n            \"::\",\n            stringify!(pfss_ts_mod)\n        )\n    );\n}\n#[repr(C, packed)]\n#[derive(Copy, Clone)]\npub struct pfsync_state_host {\n    pub addr: pf_addr,\n    pub xport: pf_state_xport,\n    pub pad: [u_int16_t; 2usize],\n}\n#[test]\nfn bindgen_test_layout_pfsync_state_host() {\n    const UNINIT: ::std::mem::MaybeUninit<pfsync_state_host> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfsync_state_host>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(pfsync_state_host))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfsync_state_host>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(pfsync_state_host))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_host),\n            \"::\",\n            stringify!(addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).xport) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_host),\n            \"::\",\n            stringify!(xport)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pad) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_host),\n            \"::\",\n            stringify!(pad)\n        )\n    );\n}\n#[repr(C, packed)]\n#[derive(Debug, Copy, Clone)]\npub struct pfsync_state_peer {\n    pub scrub: pfsync_state_scrub,\n    pub seqlo: u_int32_t,\n    pub seqhi: u_int32_t,\n    pub seqdiff: u_int32_t,\n    pub max_win: u_int16_t,\n    pub mss: u_int16_t,\n    pub state: u_int8_t,\n    pub wscale: u_int8_t,\n    pub pad: [u_int8_t; 6usize],\n}\n#[test]\nfn bindgen_test_layout_pfsync_state_peer() {\n    const UNINIT: ::std::mem::MaybeUninit<pfsync_state_peer> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfsync_state_peer>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(pfsync_state_peer))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfsync_state_peer>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(pfsync_state_peer))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scrub) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_peer),\n            \"::\",\n            stringify!(scrub)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).seqlo) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_peer),\n            \"::\",\n            stringify!(seqlo)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).seqhi) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_peer),\n            \"::\",\n            stringify!(seqhi)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).seqdiff) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_peer),\n            \"::\",\n            stringify!(seqdiff)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_win) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_peer),\n            \"::\",\n            stringify!(max_win)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mss) as usize - ptr as usize },\n        22usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_peer),\n            \"::\",\n            stringify!(mss)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).state) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_peer),\n            \"::\",\n            stringify!(state)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).wscale) as usize - ptr as usize },\n        25usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_peer),\n            \"::\",\n            stringify!(wscale)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pad) as usize - ptr as usize },\n        26usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_peer),\n            \"::\",\n            stringify!(pad)\n        )\n    );\n}\n#[repr(C, packed)]\n#[derive(Copy, Clone)]\npub struct pfsync_state {\n    pub id: [u_int32_t; 2usize],\n    pub ifname: [::std::os::raw::c_char; 16usize],\n    pub lan: pfsync_state_host,\n    pub gwy: pfsync_state_host,\n    pub ext_lan: pfsync_state_host,\n    pub ext_gwy: pfsync_state_host,\n    pub src: pfsync_state_peer,\n    pub dst: pfsync_state_peer,\n    pub rt_addr: pf_addr,\n    pub unlink_hooks: hook_desc_head,\n    pub rule: u_int32_t,\n    pub anchor: u_int32_t,\n    pub nat_rule: u_int32_t,\n    pub creation: u_int64_t,\n    pub expire: u_int64_t,\n    pub packets: [[u_int32_t; 2usize]; 2usize],\n    pub bytes: [[u_int32_t; 2usize]; 2usize],\n    pub creatorid: u_int32_t,\n    pub tag: u_int16_t,\n    pub af_lan: sa_family_t,\n    pub af_gwy: sa_family_t,\n    pub proto: u_int8_t,\n    pub direction: u_int8_t,\n    pub log: u_int8_t,\n    pub allow_opts: u_int8_t,\n    pub timeout: u_int8_t,\n    pub sync_flags: u_int8_t,\n    pub updates: u_int8_t,\n    pub proto_variant: u_int8_t,\n    pub __pad: u_int8_t,\n    pub flowhash: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_pfsync_state() {\n    const UNINIT: ::std::mem::MaybeUninit<pfsync_state> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfsync_state>(),\n        297usize,\n        concat!(\"Size of: \", stringify!(pfsync_state))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfsync_state>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(pfsync_state))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).id) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(id))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifname) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(ifname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lan) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(lan))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).gwy) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(gwy))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ext_lan) as usize - ptr as usize },\n        72usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(ext_lan))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ext_gwy) as usize - ptr as usize },\n        96usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(ext_gwy))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).src) as usize - ptr as usize },\n        120usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(src))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dst) as usize - ptr as usize },\n        152usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(dst))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rt_addr) as usize - ptr as usize },\n        184usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(rt_addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).unlink_hooks) as usize - ptr as usize },\n        200usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state),\n            \"::\",\n            stringify!(unlink_hooks)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rule) as usize - ptr as usize },\n        216usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(rule))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor) as usize - ptr as usize },\n        220usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(anchor))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nat_rule) as usize - ptr as usize },\n        224usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state),\n            \"::\",\n            stringify!(nat_rule)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).creation) as usize - ptr as usize },\n        228usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state),\n            \"::\",\n            stringify!(creation)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).expire) as usize - ptr as usize },\n        236usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(expire))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).packets) as usize - ptr as usize },\n        244usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(packets))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).bytes) as usize - ptr as usize },\n        260usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(bytes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).creatorid) as usize - ptr as usize },\n        276usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state),\n            \"::\",\n            stringify!(creatorid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tag) as usize - ptr as usize },\n        280usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(tag))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).af_lan) as usize - ptr as usize },\n        282usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(af_lan))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).af_gwy) as usize - ptr as usize },\n        283usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(af_gwy))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).proto) as usize - ptr as usize },\n        284usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(proto))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).direction) as usize - ptr as usize },\n        285usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state),\n            \"::\",\n            stringify!(direction)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).log) as usize - ptr as usize },\n        286usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(log))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).allow_opts) as usize - ptr as usize },\n        287usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state),\n            \"::\",\n            stringify!(allow_opts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).timeout) as usize - ptr as usize },\n        288usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(timeout))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sync_flags) as usize - ptr as usize },\n        289usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state),\n            \"::\",\n            stringify!(sync_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).updates) as usize - ptr as usize },\n        290usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(updates))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).proto_variant) as usize - ptr as usize },\n        291usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state),\n            \"::\",\n            stringify!(proto_variant)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__pad) as usize - ptr as usize },\n        292usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(__pad))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flowhash) as usize - ptr as usize },\n        293usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state),\n            \"::\",\n            stringify!(flowhash)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_rulequeue {\n    pub tqh_first: *mut pf_rule,\n    pub tqh_last: *mut *mut pf_rule,\n}\n#[test]\nfn bindgen_test_layout_pf_rulequeue() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rulequeue> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rulequeue>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_rulequeue))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rulequeue>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_rulequeue))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqh_first) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rulequeue),\n            \"::\",\n            stringify!(tqh_first)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqh_last) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rulequeue),\n            \"::\",\n            stringify!(tqh_last)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_ruleset {\n    pub rules: [pf_ruleset__bindgen_ty_1; 6usize],\n    pub anchor: *mut pf_anchor,\n    pub tticket: u_int32_t,\n    pub tables: ::std::os::raw::c_int,\n    pub topen: ::std::os::raw::c_int,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_ruleset__bindgen_ty_1 {\n    pub queues: [pf_rulequeue; 2usize],\n    pub active: pf_ruleset__bindgen_ty_1__bindgen_ty_1,\n    pub inactive: pf_ruleset__bindgen_ty_1__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_ruleset__bindgen_ty_1__bindgen_ty_1 {\n    pub ptr: *mut pf_rulequeue,\n    pub ptr_array: *mut *mut pf_rule,\n    pub rcount: u_int32_t,\n    pub ticket: u_int32_t,\n    pub open: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_pf_ruleset__bindgen_ty_1__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_ruleset__bindgen_ty_1__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_ruleset__bindgen_ty_1__bindgen_ty_1>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(pf_ruleset__bindgen_ty_1__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_ruleset__bindgen_ty_1__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_ruleset__bindgen_ty_1__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ptr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_ruleset__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(ptr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ptr_array) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_ruleset__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(ptr_array)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rcount) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_ruleset__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(rcount)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ticket) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_ruleset__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(ticket)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).open) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_ruleset__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(open)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_ruleset__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_ruleset__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_ruleset__bindgen_ty_1>(),\n        96usize,\n        concat!(\"Size of: \", stringify!(pf_ruleset__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_ruleset__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_ruleset__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).queues) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_ruleset__bindgen_ty_1),\n            \"::\",\n            stringify!(queues)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).active) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_ruleset__bindgen_ty_1),\n            \"::\",\n            stringify!(active)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).inactive) as usize - ptr as usize },\n        64usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_ruleset__bindgen_ty_1),\n            \"::\",\n            stringify!(inactive)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_ruleset() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_ruleset> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_ruleset>(),\n        600usize,\n        concat!(\"Size of: \", stringify!(pf_ruleset))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_ruleset>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_ruleset))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rules) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_ruleset), \"::\", stringify!(rules))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor) as usize - ptr as usize },\n        576usize,\n        concat!(\"Offset of field: \", stringify!(pf_ruleset), \"::\", stringify!(anchor))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tticket) as usize - ptr as usize },\n        584usize,\n        concat!(\"Offset of field: \", stringify!(pf_ruleset), \"::\", stringify!(tticket))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tables) as usize - ptr as usize },\n        588usize,\n        concat!(\"Offset of field: \", stringify!(pf_ruleset), \"::\", stringify!(tables))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).topen) as usize - ptr as usize },\n        592usize,\n        concat!(\"Offset of field: \", stringify!(pf_ruleset), \"::\", stringify!(topen))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_anchor_global {\n    pub rbh_root: *mut pf_anchor,\n}\n#[test]\nfn bindgen_test_layout_pf_anchor_global() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_anchor_global> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_anchor_global>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_anchor_global))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_anchor_global>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_anchor_global))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbh_root) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_anchor_global),\n            \"::\",\n            stringify!(rbh_root)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_anchor_node {\n    pub rbh_root: *mut pf_anchor,\n}\n#[test]\nfn bindgen_test_layout_pf_anchor_node() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_anchor_node> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_anchor_node>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_anchor_node))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_anchor_node>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_anchor_node))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbh_root) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_anchor_node),\n            \"::\",\n            stringify!(rbh_root)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_anchor {\n    pub entry_global: pf_anchor__bindgen_ty_1,\n    pub entry_node: pf_anchor__bindgen_ty_2,\n    pub parent: *mut pf_anchor,\n    pub children: pf_anchor_node,\n    pub name: [::std::os::raw::c_char; 64usize],\n    pub path: [::std::os::raw::c_char; 1024usize],\n    pub ruleset: pf_ruleset,\n    pub refcnt: ::std::os::raw::c_int,\n    pub match_: ::std::os::raw::c_int,\n    pub owner: [::std::os::raw::c_char; 64usize],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_anchor__bindgen_ty_1 {\n    pub rbe_left: *mut pf_anchor,\n    pub rbe_right: *mut pf_anchor,\n    pub rbe_parent: *mut pf_anchor,\n}\n#[test]\nfn bindgen_test_layout_pf_anchor__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_anchor__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_anchor__bindgen_ty_1>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(pf_anchor__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_anchor__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_anchor__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_left) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_anchor__bindgen_ty_1),\n            \"::\",\n            stringify!(rbe_left)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_right) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_anchor__bindgen_ty_1),\n            \"::\",\n            stringify!(rbe_right)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_parent) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_anchor__bindgen_ty_1),\n            \"::\",\n            stringify!(rbe_parent)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_anchor__bindgen_ty_2 {\n    pub rbe_left: *mut pf_anchor,\n    pub rbe_right: *mut pf_anchor,\n    pub rbe_parent: *mut pf_anchor,\n}\n#[test]\nfn bindgen_test_layout_pf_anchor__bindgen_ty_2() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_anchor__bindgen_ty_2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_anchor__bindgen_ty_2>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(pf_anchor__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_anchor__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_anchor__bindgen_ty_2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_left) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_anchor__bindgen_ty_2),\n            \"::\",\n            stringify!(rbe_left)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_right) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_anchor__bindgen_ty_2),\n            \"::\",\n            stringify!(rbe_right)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_parent) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_anchor__bindgen_ty_2),\n            \"::\",\n            stringify!(rbe_parent)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_anchor() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_anchor> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_anchor>(),\n        1824usize,\n        concat!(\"Size of: \", stringify!(pf_anchor))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_anchor>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_anchor))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).entry_global) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_anchor),\n            \"::\",\n            stringify!(entry_global)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).entry_node) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(pf_anchor), \"::\", stringify!(entry_node))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).parent) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(pf_anchor), \"::\", stringify!(parent))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).children) as usize - ptr as usize },\n        56usize,\n        concat!(\"Offset of field: \", stringify!(pf_anchor), \"::\", stringify!(children))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).name) as usize - ptr as usize },\n        64usize,\n        concat!(\"Offset of field: \", stringify!(pf_anchor), \"::\", stringify!(name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).path) as usize - ptr as usize },\n        128usize,\n        concat!(\"Offset of field: \", stringify!(pf_anchor), \"::\", stringify!(path))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ruleset) as usize - ptr as usize },\n        1152usize,\n        concat!(\"Offset of field: \", stringify!(pf_anchor), \"::\", stringify!(ruleset))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).refcnt) as usize - ptr as usize },\n        1752usize,\n        concat!(\"Offset of field: \", stringify!(pf_anchor), \"::\", stringify!(refcnt))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).match_) as usize - ptr as usize },\n        1756usize,\n        concat!(\"Offset of field: \", stringify!(pf_anchor), \"::\", stringify!(match_))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).owner) as usize - ptr as usize },\n        1760usize,\n        concat!(\"Offset of field: \", stringify!(pf_anchor), \"::\", stringify!(owner))\n    );\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_INSERT_COLOR(arg1: *mut pf_anchor_global, arg2: *mut pf_anchor);\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_REMOVE_COLOR(arg1: *mut pf_anchor_global, arg2: *mut pf_anchor, arg3: *mut pf_anchor);\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_REMOVE(arg1: *mut pf_anchor_global, arg2: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_INSERT(arg1: *mut pf_anchor_global, arg2: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_FIND(arg1: *mut pf_anchor_global, arg2: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_NFIND(arg1: *mut pf_anchor_global, arg2: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_NEXT(arg1: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_MINMAX(arg1: *mut pf_anchor_global, arg2: ::std::os::raw::c_int) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_GETPARENT(arg1: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_SETPARENT(arg1: *mut pf_anchor, arg2: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_GETCOLOR(arg1: *mut pf_anchor) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_SETCOLOR(arg1: *mut pf_anchor, arg2: ::std::os::raw::c_int);\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_INSERT_COLOR(arg1: *mut pf_anchor_node, arg2: *mut pf_anchor);\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_REMOVE_COLOR(arg1: *mut pf_anchor_node, arg2: *mut pf_anchor, arg3: *mut pf_anchor);\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_REMOVE(arg1: *mut pf_anchor_node, arg2: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_INSERT(arg1: *mut pf_anchor_node, arg2: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_FIND(arg1: *mut pf_anchor_node, arg2: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_NFIND(arg1: *mut pf_anchor_node, arg2: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_NEXT(arg1: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_MINMAX(arg1: *mut pf_anchor_node, arg2: ::std::os::raw::c_int) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_GETPARENT(arg1: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_SETPARENT(arg1: *mut pf_anchor, arg2: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_GETCOLOR(arg1: *mut pf_anchor) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_SETCOLOR(arg1: *mut pf_anchor, arg2: ::std::os::raw::c_int);\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfr_table {\n    pub pfrt_anchor: [::std::os::raw::c_char; 1024usize],\n    pub pfrt_name: [::std::os::raw::c_char; 32usize],\n    pub pfrt_flags: u32,\n    pub pfrt_fback: u8,\n}\n#[test]\nfn bindgen_test_layout_pfr_table() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_table> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_table>(),\n        1064usize,\n        concat!(\"Size of: \", stringify!(pfr_table))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_table>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pfr_table))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrt_anchor) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_table),\n            \"::\",\n            stringify!(pfrt_anchor)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrt_name) as usize - ptr as usize },\n        1024usize,\n        concat!(\"Offset of field: \", stringify!(pfr_table), \"::\", stringify!(pfrt_name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrt_flags) as usize - ptr as usize },\n        1056usize,\n        concat!(\"Offset of field: \", stringify!(pfr_table), \"::\", stringify!(pfrt_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrt_fback) as usize - ptr as usize },\n        1060usize,\n        concat!(\"Offset of field: \", stringify!(pfr_table), \"::\", stringify!(pfrt_fback))\n    );\n}\npub const PFR_FB_NONE: _bindgen_ty_13 = 0;\npub const PFR_FB_MATCH: _bindgen_ty_13 = 1;\npub const PFR_FB_ADDED: _bindgen_ty_13 = 2;\npub const PFR_FB_DELETED: _bindgen_ty_13 = 3;\npub const PFR_FB_CHANGED: _bindgen_ty_13 = 4;\npub const PFR_FB_CLEARED: _bindgen_ty_13 = 5;\npub const PFR_FB_DUPLICATE: _bindgen_ty_13 = 6;\npub const PFR_FB_NOTMATCH: _bindgen_ty_13 = 7;\npub const PFR_FB_CONFLICT: _bindgen_ty_13 = 8;\npub const PFR_FB_MAX: _bindgen_ty_13 = 9;\npub type _bindgen_ty_13 = ::std::os::raw::c_uint;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfr_addr {\n    pub pfra_u: pfr_addr__bindgen_ty_1,\n    pub pfra_af: u8,\n    pub pfra_net: u8,\n    pub pfra_not: u8,\n    pub pfra_fback: u8,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pfr_addr__bindgen_ty_1 {\n    pub _pfra_ip4addr: in_addr,\n    pub _pfra_ip6addr: in6_addr,\n}\n#[test]\nfn bindgen_test_layout_pfr_addr__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_addr__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_addr__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pfr_addr__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_addr__bindgen_ty_1>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pfr_addr__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._pfra_ip4addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(_pfra_ip4addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._pfra_ip6addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(_pfra_ip6addr)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pfr_addr() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_addr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_addr>(),\n        20usize,\n        concat!(\"Size of: \", stringify!(pfr_addr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_addr>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pfr_addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfra_u) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfr_addr), \"::\", stringify!(pfra_u))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfra_af) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pfr_addr), \"::\", stringify!(pfra_af))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfra_net) as usize - ptr as usize },\n        17usize,\n        concat!(\"Offset of field: \", stringify!(pfr_addr), \"::\", stringify!(pfra_net))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfra_not) as usize - ptr as usize },\n        18usize,\n        concat!(\"Offset of field: \", stringify!(pfr_addr), \"::\", stringify!(pfra_not))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfra_fback) as usize - ptr as usize },\n        19usize,\n        concat!(\"Offset of field: \", stringify!(pfr_addr), \"::\", stringify!(pfra_fback))\n    );\n}\npub const PFR_DIR_IN: _bindgen_ty_14 = 0;\npub const PFR_DIR_OUT: _bindgen_ty_14 = 1;\npub const PFR_DIR_MAX: _bindgen_ty_14 = 2;\npub type _bindgen_ty_14 = ::std::os::raw::c_uint;\npub const PFR_OP_BLOCK: _bindgen_ty_15 = 0;\npub const PFR_OP_PASS: _bindgen_ty_15 = 1;\npub const PFR_OP_ADDR_MAX: _bindgen_ty_15 = 2;\npub const PFR_OP_TABLE_MAX: _bindgen_ty_15 = 3;\npub type _bindgen_ty_15 = ::std::os::raw::c_uint;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfr_astats {\n    pub pfras_a: pfr_addr,\n    pub pfras_packets: [[u64; 2usize]; 2usize],\n    pub pfras_bytes: [[u64; 2usize]; 2usize],\n    pub pfras_tzero: u64,\n}\n#[test]\nfn bindgen_test_layout_pfr_astats() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_astats> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_astats>(),\n        96usize,\n        concat!(\"Size of: \", stringify!(pfr_astats))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_astats>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfr_astats))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfras_a) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfr_astats), \"::\", stringify!(pfras_a))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfras_packets) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_astats),\n            \"::\",\n            stringify!(pfras_packets)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfras_bytes) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_astats),\n            \"::\",\n            stringify!(pfras_bytes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfras_tzero) as usize - ptr as usize },\n        88usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_astats),\n            \"::\",\n            stringify!(pfras_tzero)\n        )\n    );\n}\npub const PFR_REFCNT_RULE: _bindgen_ty_16 = 0;\npub const PFR_REFCNT_ANCHOR: _bindgen_ty_16 = 1;\npub const PFR_REFCNT_MAX: _bindgen_ty_16 = 2;\npub type _bindgen_ty_16 = ::std::os::raw::c_uint;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfr_tstats {\n    pub pfrts_t: pfr_table,\n    pub pfrts_packets: [[u_int64_t; 3usize]; 2usize],\n    pub pfrts_bytes: [[u_int64_t; 3usize]; 2usize],\n    pub pfrts_match: u_int64_t,\n    pub pfrts_nomatch: u_int64_t,\n    pub pfrts_tzero: u_int64_t,\n    pub pfrts_cnt: ::std::os::raw::c_int,\n    pub pfrts_refcnt: [::std::os::raw::c_int; 2usize],\n}\n#[test]\nfn bindgen_test_layout_pfr_tstats() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_tstats> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_tstats>(),\n        1200usize,\n        concat!(\"Size of: \", stringify!(pfr_tstats))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_tstats>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfr_tstats))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrts_t) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfr_tstats), \"::\", stringify!(pfrts_t))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrts_packets) as usize - ptr as usize },\n        1064usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_tstats),\n            \"::\",\n            stringify!(pfrts_packets)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrts_bytes) as usize - ptr as usize },\n        1112usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_tstats),\n            \"::\",\n            stringify!(pfrts_bytes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrts_match) as usize - ptr as usize },\n        1160usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_tstats),\n            \"::\",\n            stringify!(pfrts_match)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrts_nomatch) as usize - ptr as usize },\n        1168usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_tstats),\n            \"::\",\n            stringify!(pfrts_nomatch)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrts_tzero) as usize - ptr as usize },\n        1176usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_tstats),\n            \"::\",\n            stringify!(pfrts_tzero)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrts_cnt) as usize - ptr as usize },\n        1184usize,\n        concat!(\"Offset of field: \", stringify!(pfr_tstats), \"::\", stringify!(pfrts_cnt))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrts_refcnt) as usize - ptr as usize },\n        1188usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_tstats),\n            \"::\",\n            stringify!(pfrts_refcnt)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfi_kif {\n    pub pfik_name: [::std::os::raw::c_char; 16usize],\n    pub pfik_packets: [[[u_int64_t; 2usize]; 2usize]; 2usize],\n    pub pfik_bytes: [[[u_int64_t; 2usize]; 2usize]; 2usize],\n    pub pfik_tzero: u_int64_t,\n    pub pfik_flags: ::std::os::raw::c_int,\n    pub pfik_states: ::std::os::raw::c_int,\n    pub pfik_rules: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_pfi_kif() {\n    const UNINIT: ::std::mem::MaybeUninit<pfi_kif> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfi_kif>(),\n        168usize,\n        concat!(\"Size of: \", stringify!(pfi_kif))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfi_kif>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfi_kif))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_name) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfi_kif), \"::\", stringify!(pfik_name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_packets) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pfi_kif), \"::\", stringify!(pfik_packets))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_bytes) as usize - ptr as usize },\n        80usize,\n        concat!(\"Offset of field: \", stringify!(pfi_kif), \"::\", stringify!(pfik_bytes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_tzero) as usize - ptr as usize },\n        144usize,\n        concat!(\"Offset of field: \", stringify!(pfi_kif), \"::\", stringify!(pfik_tzero))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_flags) as usize - ptr as usize },\n        152usize,\n        concat!(\"Offset of field: \", stringify!(pfi_kif), \"::\", stringify!(pfik_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_states) as usize - ptr as usize },\n        156usize,\n        concat!(\"Offset of field: \", stringify!(pfi_kif), \"::\", stringify!(pfik_states))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_rules) as usize - ptr as usize },\n        160usize,\n        concat!(\"Offset of field: \", stringify!(pfi_kif), \"::\", stringify!(pfik_rules))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_status {\n    pub counters: [u_int64_t; 16usize],\n    pub lcounters: [u_int64_t; 7usize],\n    pub fcounters: [u_int64_t; 3usize],\n    pub scounters: [u_int64_t; 3usize],\n    pub pcounters: [[[u_int64_t; 3usize]; 2usize]; 2usize],\n    pub bcounters: [[u_int64_t; 2usize]; 2usize],\n    pub stateid: u_int64_t,\n    pub running: u_int32_t,\n    pub states: u_int32_t,\n    pub src_nodes: u_int32_t,\n    pub since: u_int64_t,\n    pub debug: u_int32_t,\n    pub hostid: u_int32_t,\n    pub ifname: [::std::os::raw::c_char; 16usize],\n    pub pf_chksum: [u_int8_t; 16usize],\n}\n#[test]\nfn bindgen_test_layout_pf_status() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_status> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_status>(),\n        432usize,\n        concat!(\"Size of: \", stringify!(pf_status))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_status>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_status))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).counters) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(counters))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lcounters) as usize - ptr as usize },\n        128usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(lcounters))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fcounters) as usize - ptr as usize },\n        184usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(fcounters))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scounters) as usize - ptr as usize },\n        208usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(scounters))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pcounters) as usize - ptr as usize },\n        232usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(pcounters))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).bcounters) as usize - ptr as usize },\n        328usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(bcounters))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).stateid) as usize - ptr as usize },\n        360usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(stateid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).running) as usize - ptr as usize },\n        368usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(running))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).states) as usize - ptr as usize },\n        372usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(states))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).src_nodes) as usize - ptr as usize },\n        376usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(src_nodes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).since) as usize - ptr as usize },\n        384usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(since))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).debug) as usize - ptr as usize },\n        392usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(debug))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).hostid) as usize - ptr as usize },\n        396usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(hostid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifname) as usize - ptr as usize },\n        400usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(ifname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pf_chksum) as usize - ptr as usize },\n        416usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(pf_chksum))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct cbq_opts {\n    pub minburst: u_int32_t,\n    pub maxburst: u_int32_t,\n    pub pktsize: u_int32_t,\n    pub maxpktsize: u_int32_t,\n    pub ns_per_byte: u_int32_t,\n    pub maxidle: u_int32_t,\n    pub minidle: i32,\n    pub offtime: u_int32_t,\n    pub flags: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_cbq_opts() {\n    const UNINIT: ::std::mem::MaybeUninit<cbq_opts> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<cbq_opts>(),\n        36usize,\n        concat!(\"Size of: \", stringify!(cbq_opts))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<cbq_opts>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(cbq_opts))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).minburst) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(cbq_opts), \"::\", stringify!(minburst))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).maxburst) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(cbq_opts), \"::\", stringify!(maxburst))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pktsize) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(cbq_opts), \"::\", stringify!(pktsize))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).maxpktsize) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(cbq_opts), \"::\", stringify!(maxpktsize))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ns_per_byte) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(cbq_opts), \"::\", stringify!(ns_per_byte))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).maxidle) as usize - ptr as usize },\n        20usize,\n        concat!(\"Offset of field: \", stringify!(cbq_opts), \"::\", stringify!(maxidle))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).minidle) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(cbq_opts), \"::\", stringify!(minidle))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).offtime) as usize - ptr as usize },\n        28usize,\n        concat!(\"Offset of field: \", stringify!(cbq_opts), \"::\", stringify!(offtime))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flags) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(cbq_opts), \"::\", stringify!(flags))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct priq_opts {\n    pub flags: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_priq_opts() {\n    const UNINIT: ::std::mem::MaybeUninit<priq_opts> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<priq_opts>(),\n        4usize,\n        concat!(\"Size of: \", stringify!(priq_opts))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<priq_opts>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(priq_opts))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flags) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(priq_opts), \"::\", stringify!(flags))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct hfsc_opts {\n    pub rtsc_m1: u_int64_t,\n    pub rtsc_d: u_int64_t,\n    pub rtsc_m2: u_int64_t,\n    pub rtsc_fl: u_int32_t,\n    pub lssc_m1: u_int64_t,\n    pub lssc_d: u_int64_t,\n    pub lssc_m2: u_int64_t,\n    pub lssc_fl: u_int32_t,\n    pub ulsc_m1: u_int64_t,\n    pub ulsc_d: u_int64_t,\n    pub ulsc_m2: u_int64_t,\n    pub ulsc_fl: u_int32_t,\n    pub flags: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_hfsc_opts() {\n    const UNINIT: ::std::mem::MaybeUninit<hfsc_opts> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<hfsc_opts>(),\n        96usize,\n        concat!(\"Size of: \", stringify!(hfsc_opts))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<hfsc_opts>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(hfsc_opts))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtsc_m1) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts), \"::\", stringify!(rtsc_m1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtsc_d) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts), \"::\", stringify!(rtsc_d))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtsc_m2) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts), \"::\", stringify!(rtsc_m2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtsc_fl) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts), \"::\", stringify!(rtsc_fl))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lssc_m1) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts), \"::\", stringify!(lssc_m1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lssc_d) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts), \"::\", stringify!(lssc_d))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lssc_m2) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts), \"::\", stringify!(lssc_m2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lssc_fl) as usize - ptr as usize },\n        56usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts), \"::\", stringify!(lssc_fl))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ulsc_m1) as usize - ptr as usize },\n        64usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts), \"::\", stringify!(ulsc_m1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ulsc_d) as usize - ptr as usize },\n        72usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts), \"::\", stringify!(ulsc_d))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ulsc_m2) as usize - ptr as usize },\n        80usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts), \"::\", stringify!(ulsc_m2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ulsc_fl) as usize - ptr as usize },\n        88usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts), \"::\", stringify!(ulsc_fl))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flags) as usize - ptr as usize },\n        92usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts), \"::\", stringify!(flags))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct fairq_opts {\n    pub nbuckets: u_int32_t,\n    pub flags: u_int32_t,\n    pub hogs_m1: u_int64_t,\n    pub lssc_m1: u_int64_t,\n    pub lssc_d: u_int64_t,\n    pub lssc_m2: u_int64_t,\n}\n#[test]\nfn bindgen_test_layout_fairq_opts() {\n    const UNINIT: ::std::mem::MaybeUninit<fairq_opts> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<fairq_opts>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(fairq_opts))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<fairq_opts>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(fairq_opts))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nbuckets) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(fairq_opts), \"::\", stringify!(nbuckets))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flags) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(fairq_opts), \"::\", stringify!(flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).hogs_m1) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(fairq_opts), \"::\", stringify!(hogs_m1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lssc_m1) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(fairq_opts), \"::\", stringify!(lssc_m1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lssc_d) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(fairq_opts), \"::\", stringify!(lssc_d))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lssc_m2) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(fairq_opts), \"::\", stringify!(lssc_m2))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_altq {\n    pub ifname: [::std::os::raw::c_char; 16usize],\n    pub altq_disc: *mut ::std::os::raw::c_void,\n    pub entries: pf_altq__bindgen_ty_1,\n    pub aflags: u_int32_t,\n    pub bwtype: u_int32_t,\n    pub scheduler: u_int32_t,\n    pub tbrsize: u_int32_t,\n    pub ifbandwidth: u_int64_t,\n    pub qname: [::std::os::raw::c_char; 64usize],\n    pub parent: [::std::os::raw::c_char; 64usize],\n    pub parent_qid: u_int32_t,\n    pub qrflags: u_int32_t,\n    pub __bindgen_anon_1: pf_altq__bindgen_ty_2,\n    pub qlimit: u_int32_t,\n    pub flags: u_int32_t,\n    pub bandwidth: u_int64_t,\n    pub pq_u: pf_altq__bindgen_ty_3,\n    pub qid: u_int32_t,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_altq__bindgen_ty_1 {\n    pub tqe_next: *mut pf_altq,\n    pub tqe_prev: *mut *mut pf_altq,\n}\n#[test]\nfn bindgen_test_layout_pf_altq__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_altq__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_altq__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_altq__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_altq__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_altq__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqe_next) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_altq__bindgen_ty_1),\n            \"::\",\n            stringify!(tqe_next)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqe_prev) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_altq__bindgen_ty_1),\n            \"::\",\n            stringify!(tqe_prev)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pf_altq__bindgen_ty_2 {\n    pub priority: u_int32_t,\n    pub weight: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_pf_altq__bindgen_ty_2() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_altq__bindgen_ty_2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_altq__bindgen_ty_2>(),\n        4usize,\n        concat!(\"Size of: \", stringify!(pf_altq__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_altq__bindgen_ty_2>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_altq__bindgen_ty_2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).priority) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_altq__bindgen_ty_2),\n            \"::\",\n            stringify!(priority)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).weight) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_altq__bindgen_ty_2),\n            \"::\",\n            stringify!(weight)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pf_altq__bindgen_ty_3 {\n    pub cbq_opts: cbq_opts,\n    pub priq_opts: priq_opts,\n    pub hfsc_opts: hfsc_opts,\n    pub fairq_opts: fairq_opts,\n}\n#[test]\nfn bindgen_test_layout_pf_altq__bindgen_ty_3() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_altq__bindgen_ty_3> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_altq__bindgen_ty_3>(),\n        96usize,\n        concat!(\"Size of: \", stringify!(pf_altq__bindgen_ty_3))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_altq__bindgen_ty_3>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_altq__bindgen_ty_3))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cbq_opts) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_altq__bindgen_ty_3),\n            \"::\",\n            stringify!(cbq_opts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).priq_opts) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_altq__bindgen_ty_3),\n            \"::\",\n            stringify!(priq_opts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).hfsc_opts) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_altq__bindgen_ty_3),\n            \"::\",\n            stringify!(hfsc_opts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fairq_opts) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_altq__bindgen_ty_3),\n            \"::\",\n            stringify!(fairq_opts)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_altq() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_altq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_altq>(),\n        328usize,\n        concat!(\"Size of: \", stringify!(pf_altq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_altq>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_altq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifname) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq), \"::\", stringify!(ifname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).altq_disc) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq), \"::\", stringify!(altq_disc))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).entries) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq), \"::\", stringify!(entries))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).aflags) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq), \"::\", stringify!(aflags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).bwtype) as usize - ptr as usize },\n        44usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq), \"::\", stringify!(bwtype))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scheduler) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq), \"::\", stringify!(scheduler))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tbrsize) as usize - ptr as usize },\n        52usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq), \"::\", stringify!(tbrsize))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifbandwidth) as usize - ptr as usize },\n        56usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq), \"::\", stringify!(ifbandwidth))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).qname) as usize - ptr as usize },\n        64usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq), \"::\", stringify!(qname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).parent) as usize - ptr as usize },\n        128usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq), \"::\", stringify!(parent))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).parent_qid) as usize - ptr as usize },\n        192usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq), \"::\", stringify!(parent_qid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).qrflags) as usize - ptr as usize },\n        196usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq), \"::\", stringify!(qrflags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).qlimit) as usize - ptr as usize },\n        204usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq), \"::\", stringify!(qlimit))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flags) as usize - ptr as usize },\n        208usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq), \"::\", stringify!(flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).bandwidth) as usize - ptr as usize },\n        216usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq), \"::\", stringify!(bandwidth))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pq_u) as usize - ptr as usize },\n        224usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq), \"::\", stringify!(pq_u))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).qid) as usize - ptr as usize },\n        320usize,\n        concat!(\"Offset of field: \", stringify!(pf_altq), \"::\", stringify!(qid))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_tagname {\n    pub entries: pf_tagname__bindgen_ty_1,\n    pub name: [::std::os::raw::c_char; 64usize],\n    pub tag: u_int16_t,\n    pub ref_: ::std::os::raw::c_int,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_tagname__bindgen_ty_1 {\n    pub tqe_next: *mut pf_tagname,\n    pub tqe_prev: *mut *mut pf_tagname,\n}\n#[test]\nfn bindgen_test_layout_pf_tagname__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_tagname__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_tagname__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_tagname__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_tagname__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_tagname__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqe_next) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_tagname__bindgen_ty_1),\n            \"::\",\n            stringify!(tqe_next)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqe_prev) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_tagname__bindgen_ty_1),\n            \"::\",\n            stringify!(tqe_prev)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_tagname() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_tagname> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_tagname>(),\n        88usize,\n        concat!(\"Size of: \", stringify!(pf_tagname))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_tagname>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_tagname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).entries) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_tagname), \"::\", stringify!(entries))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).name) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pf_tagname), \"::\", stringify!(name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tag) as usize - ptr as usize },\n        80usize,\n        concat!(\"Offset of field: \", stringify!(pf_tagname), \"::\", stringify!(tag))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ref_) as usize - ptr as usize },\n        84usize,\n        concat!(\"Offset of field: \", stringify!(pf_tagname), \"::\", stringify!(ref_))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_pooladdr {\n    pub action: u_int32_t,\n    pub ticket: u_int32_t,\n    pub nr: u_int32_t,\n    pub r_num: u_int32_t,\n    pub r_action: u_int8_t,\n    pub r_last: u_int8_t,\n    pub af: u_int8_t,\n    pub anchor: [::std::os::raw::c_char; 1024usize],\n    pub addr: pf_pooladdr,\n}\n#[test]\nfn bindgen_test_layout_pfioc_pooladdr() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_pooladdr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_pooladdr>(),\n        1136usize,\n        concat!(\"Size of: \", stringify!(pfioc_pooladdr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_pooladdr>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_pooladdr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).action) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_pooladdr),\n            \"::\",\n            stringify!(action)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ticket) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_pooladdr),\n            \"::\",\n            stringify!(ticket)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nr) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_pooladdr), \"::\", stringify!(nr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).r_num) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_pooladdr), \"::\", stringify!(r_num))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).r_action) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_pooladdr),\n            \"::\",\n            stringify!(r_action)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).r_last) as usize - ptr as usize },\n        17usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_pooladdr),\n            \"::\",\n            stringify!(r_last)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).af) as usize - ptr as usize },\n        18usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_pooladdr), \"::\", stringify!(af))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor) as usize - ptr as usize },\n        19usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_pooladdr),\n            \"::\",\n            stringify!(anchor)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        1048usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_pooladdr), \"::\", stringify!(addr))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_rule {\n    pub action: u_int32_t,\n    pub ticket: u_int32_t,\n    pub pool_ticket: u_int32_t,\n    pub nr: u_int32_t,\n    pub anchor: [::std::os::raw::c_char; 1024usize],\n    pub anchor_call: [::std::os::raw::c_char; 1024usize],\n    pub rule: pf_rule,\n}\n#[test]\nfn bindgen_test_layout_pfioc_rule() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_rule> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_rule>(),\n        3104usize,\n        concat!(\"Size of: \", stringify!(pfioc_rule))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_rule>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_rule))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).action) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_rule), \"::\", stringify!(action))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ticket) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_rule), \"::\", stringify!(ticket))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pool_ticket) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_rule),\n            \"::\",\n            stringify!(pool_ticket)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nr) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_rule), \"::\", stringify!(nr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_rule), \"::\", stringify!(anchor))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor_call) as usize - ptr as usize },\n        1040usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_rule),\n            \"::\",\n            stringify!(anchor_call)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rule) as usize - ptr as usize },\n        2064usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_rule), \"::\", stringify!(rule))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_natlook {\n    pub saddr: pf_addr,\n    pub daddr: pf_addr,\n    pub rsaddr: pf_addr,\n    pub rdaddr: pf_addr,\n    pub sxport: pf_state_xport,\n    pub dxport: pf_state_xport,\n    pub rsxport: pf_state_xport,\n    pub rdxport: pf_state_xport,\n    pub af: sa_family_t,\n    pub proto: u_int8_t,\n    pub proto_variant: u_int8_t,\n    pub direction: u_int8_t,\n}\n#[test]\nfn bindgen_test_layout_pfioc_natlook() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_natlook> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_natlook>(),\n        84usize,\n        concat!(\"Size of: \", stringify!(pfioc_natlook))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_natlook>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pfioc_natlook))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).saddr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_natlook), \"::\", stringify!(saddr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).daddr) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_natlook), \"::\", stringify!(daddr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rsaddr) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_natlook), \"::\", stringify!(rsaddr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rdaddr) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_natlook), \"::\", stringify!(rdaddr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sxport) as usize - ptr as usize },\n        64usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_natlook), \"::\", stringify!(sxport))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dxport) as usize - ptr as usize },\n        68usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_natlook), \"::\", stringify!(dxport))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rsxport) as usize - ptr as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_natlook),\n            \"::\",\n            stringify!(rsxport)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rdxport) as usize - ptr as usize },\n        76usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_natlook),\n            \"::\",\n            stringify!(rdxport)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).af) as usize - ptr as usize },\n        80usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_natlook), \"::\", stringify!(af))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).proto) as usize - ptr as usize },\n        81usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_natlook), \"::\", stringify!(proto))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).proto_variant) as usize - ptr as usize },\n        82usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_natlook),\n            \"::\",\n            stringify!(proto_variant)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).direction) as usize - ptr as usize },\n        83usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_natlook),\n            \"::\",\n            stringify!(direction)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_state {\n    pub state: pfsync_state,\n}\n#[test]\nfn bindgen_test_layout_pfioc_state() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_state> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_state>(),\n        297usize,\n        concat!(\"Size of: \", stringify!(pfioc_state))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_state>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(pfioc_state))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).state) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_state), \"::\", stringify!(state))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_src_node_kill {\n    pub psnk_af: sa_family_t,\n    pub psnk_src: pf_rule_addr,\n    pub psnk_dst: pf_rule_addr,\n}\n#[test]\nfn bindgen_test_layout_pfioc_src_node_kill() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_src_node_kill> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_src_node_kill>(),\n        136usize,\n        concat!(\"Size of: \", stringify!(pfioc_src_node_kill))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_src_node_kill>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_src_node_kill))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psnk_af) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_src_node_kill),\n            \"::\",\n            stringify!(psnk_af)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psnk_src) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_src_node_kill),\n            \"::\",\n            stringify!(psnk_src)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psnk_dst) as usize - ptr as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_src_node_kill),\n            \"::\",\n            stringify!(psnk_dst)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_state_addr_kill {\n    pub addr: pf_addr_wrap,\n    pub reserved_: [u_int8_t; 3usize],\n    pub neg: u_int8_t,\n    pub xport: pf_rule_xport,\n}\n#[test]\nfn bindgen_test_layout_pfioc_state_addr_kill() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_state_addr_kill> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_state_addr_kill>(),\n        64usize,\n        concat!(\"Size of: \", stringify!(pfioc_state_addr_kill))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_state_addr_kill>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_state_addr_kill))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_addr_kill),\n            \"::\",\n            stringify!(addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).reserved_) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_addr_kill),\n            \"::\",\n            stringify!(reserved_)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).neg) as usize - ptr as usize },\n        51usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_addr_kill),\n            \"::\",\n            stringify!(neg)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).xport) as usize - ptr as usize },\n        52usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_addr_kill),\n            \"::\",\n            stringify!(xport)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_state_kill {\n    pub psk_af: sa_family_t,\n    pub psk_proto: u_int8_t,\n    pub psk_proto_variant: u_int8_t,\n    pub _pad: u_int8_t,\n    pub psk_src: pfioc_state_addr_kill,\n    pub psk_dst: pfioc_state_addr_kill,\n    pub psk_ifname: [::std::os::raw::c_char; 16usize],\n    pub psk_ownername: [::std::os::raw::c_char; 64usize],\n}\n#[test]\nfn bindgen_test_layout_pfioc_state_kill() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_state_kill> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_state_kill>(),\n        216usize,\n        concat!(\"Size of: \", stringify!(pfioc_state_kill))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_state_kill>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_state_kill))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psk_af) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_kill),\n            \"::\",\n            stringify!(psk_af)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psk_proto) as usize - ptr as usize },\n        1usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_kill),\n            \"::\",\n            stringify!(psk_proto)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psk_proto_variant) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_kill),\n            \"::\",\n            stringify!(psk_proto_variant)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._pad) as usize - ptr as usize },\n        3usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_kill),\n            \"::\",\n            stringify!(_pad)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psk_src) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_kill),\n            \"::\",\n            stringify!(psk_src)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psk_dst) as usize - ptr as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_kill),\n            \"::\",\n            stringify!(psk_dst)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psk_ifname) as usize - ptr as usize },\n        136usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_kill),\n            \"::\",\n            stringify!(psk_ifname)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psk_ownername) as usize - ptr as usize },\n        152usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_kill),\n            \"::\",\n            stringify!(psk_ownername)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_states {\n    pub ps_len: ::std::os::raw::c_int,\n    pub ps_u: pfioc_states__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pfioc_states__bindgen_ty_1 {\n    pub psu_buf: caddr_t,\n    pub psu_states: *mut pfsync_state,\n}\n#[test]\nfn bindgen_test_layout_pfioc_states__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_states__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_states__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pfioc_states__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_states__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_states__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psu_buf) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_states__bindgen_ty_1),\n            \"::\",\n            stringify!(psu_buf)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psu_states) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_states__bindgen_ty_1),\n            \"::\",\n            stringify!(psu_states)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pfioc_states() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_states> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_states>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pfioc_states))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_states>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_states))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ps_len) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_states), \"::\", stringify!(ps_len))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ps_u) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_states), \"::\", stringify!(ps_u))\n    );\n}\n#[repr(C, packed)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_token {\n    pub token_value: u_int64_t,\n    pub timestamp: u_int64_t,\n    pub pid: pid_t,\n    pub proc_name: [::std::os::raw::c_char; 64usize],\n}\n#[test]\nfn bindgen_test_layout_pfioc_token() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_token> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_token>(),\n        84usize,\n        concat!(\"Size of: \", stringify!(pfioc_token))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_token>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(pfioc_token))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).token_value) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_token),\n            \"::\",\n            stringify!(token_value)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).timestamp) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_token),\n            \"::\",\n            stringify!(timestamp)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pid) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_token), \"::\", stringify!(pid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).proc_name) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_token),\n            \"::\",\n            stringify!(proc_name)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_kernel_token {\n    pub next: pfioc_kernel_token__bindgen_ty_1,\n    pub token: pfioc_token,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_kernel_token__bindgen_ty_1 {\n    pub sle_next: *mut pfioc_kernel_token,\n}\n#[test]\nfn bindgen_test_layout_pfioc_kernel_token__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_kernel_token__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_kernel_token__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pfioc_kernel_token__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_kernel_token__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_kernel_token__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sle_next) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_kernel_token__bindgen_ty_1),\n            \"::\",\n            stringify!(sle_next)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pfioc_kernel_token() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_kernel_token> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_kernel_token>(),\n        96usize,\n        concat!(\"Size of: \", stringify!(pfioc_kernel_token))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_kernel_token>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_kernel_token))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).next) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_kernel_token),\n            \"::\",\n            stringify!(next)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).token) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_kernel_token),\n            \"::\",\n            stringify!(token)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_remove_token {\n    pub token_value: u_int64_t,\n    pub refcount: u_int64_t,\n}\n#[test]\nfn bindgen_test_layout_pfioc_remove_token() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_remove_token> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_remove_token>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pfioc_remove_token))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_remove_token>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_remove_token))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).token_value) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_remove_token),\n            \"::\",\n            stringify!(token_value)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).refcount) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_remove_token),\n            \"::\",\n            stringify!(refcount)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_tokens {\n    pub size: ::std::os::raw::c_int,\n    pub pgt_u: pfioc_tokens__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pfioc_tokens__bindgen_ty_1 {\n    pub pgtu_buf: caddr_t,\n    pub pgtu_tokens: *mut pfioc_token,\n}\n#[test]\nfn bindgen_test_layout_pfioc_tokens__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_tokens__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_tokens__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pfioc_tokens__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_tokens__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_tokens__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pgtu_buf) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_tokens__bindgen_ty_1),\n            \"::\",\n            stringify!(pgtu_buf)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pgtu_tokens) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_tokens__bindgen_ty_1),\n            \"::\",\n            stringify!(pgtu_tokens)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pfioc_tokens() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_tokens> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_tokens>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pfioc_tokens))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_tokens>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_tokens))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).size) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_tokens), \"::\", stringify!(size))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pgt_u) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_tokens), \"::\", stringify!(pgt_u))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_src_nodes {\n    pub psn_len: ::std::os::raw::c_int,\n    pub psn_u: pfioc_src_nodes__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pfioc_src_nodes__bindgen_ty_1 {\n    pub psu_buf: caddr_t,\n    pub psu_src_nodes: *mut pf_src_node,\n}\n#[test]\nfn bindgen_test_layout_pfioc_src_nodes__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_src_nodes__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_src_nodes__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pfioc_src_nodes__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_src_nodes__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_src_nodes__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psu_buf) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_src_nodes__bindgen_ty_1),\n            \"::\",\n            stringify!(psu_buf)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psu_src_nodes) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_src_nodes__bindgen_ty_1),\n            \"::\",\n            stringify!(psu_src_nodes)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pfioc_src_nodes() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_src_nodes> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_src_nodes>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pfioc_src_nodes))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_src_nodes>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_src_nodes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psn_len) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_src_nodes),\n            \"::\",\n            stringify!(psn_len)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psn_u) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_src_nodes),\n            \"::\",\n            stringify!(psn_u)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_if {\n    pub ifname: [::std::os::raw::c_char; 16usize],\n}\n#[test]\nfn bindgen_test_layout_pfioc_if() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_if> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_if>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pfioc_if))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_if>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(pfioc_if))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifname) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_if), \"::\", stringify!(ifname))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_tm {\n    pub timeout: ::std::os::raw::c_int,\n    pub seconds: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_pfioc_tm() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_tm> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_tm>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pfioc_tm))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_tm>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pfioc_tm))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).timeout) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_tm), \"::\", stringify!(timeout))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).seconds) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_tm), \"::\", stringify!(seconds))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_limit {\n    pub index: ::std::os::raw::c_int,\n    pub limit: ::std::os::raw::c_uint,\n}\n#[test]\nfn bindgen_test_layout_pfioc_limit() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_limit> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_limit>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pfioc_limit))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_limit>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pfioc_limit))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).index) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_limit), \"::\", stringify!(index))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).limit) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_limit), \"::\", stringify!(limit))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_altq {\n    pub action: u_int32_t,\n    pub ticket: u_int32_t,\n    pub nr: u_int32_t,\n    pub altq: pf_altq,\n}\n#[test]\nfn bindgen_test_layout_pfioc_altq() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_altq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_altq>(),\n        344usize,\n        concat!(\"Size of: \", stringify!(pfioc_altq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_altq>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_altq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).action) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_altq), \"::\", stringify!(action))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ticket) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_altq), \"::\", stringify!(ticket))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nr) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_altq), \"::\", stringify!(nr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).altq) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_altq), \"::\", stringify!(altq))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_qstats {\n    pub ticket: u_int32_t,\n    pub nr: u_int32_t,\n    pub buf: *mut ::std::os::raw::c_void,\n    pub nbytes: ::std::os::raw::c_int,\n    pub scheduler: u_int8_t,\n}\n#[test]\nfn bindgen_test_layout_pfioc_qstats() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_qstats> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_qstats>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(pfioc_qstats))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_qstats>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_qstats))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ticket) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_qstats), \"::\", stringify!(ticket))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nr) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_qstats), \"::\", stringify!(nr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).buf) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_qstats), \"::\", stringify!(buf))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nbytes) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_qstats), \"::\", stringify!(nbytes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scheduler) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_qstats),\n            \"::\",\n            stringify!(scheduler)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_ruleset {\n    pub nr: u_int32_t,\n    pub path: [::std::os::raw::c_char; 1024usize],\n    pub name: [::std::os::raw::c_char; 64usize],\n}\n#[test]\nfn bindgen_test_layout_pfioc_ruleset() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_ruleset> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_ruleset>(),\n        1092usize,\n        concat!(\"Size of: \", stringify!(pfioc_ruleset))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_ruleset>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pfioc_ruleset))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_ruleset), \"::\", stringify!(nr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).path) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_ruleset), \"::\", stringify!(path))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).name) as usize - ptr as usize },\n        1028usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_ruleset), \"::\", stringify!(name))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_trans {\n    pub size: ::std::os::raw::c_int,\n    pub esize: ::std::os::raw::c_int,\n    pub array: *mut pfioc_trans_pfioc_trans_e,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_trans_pfioc_trans_e {\n    pub rs_num: ::std::os::raw::c_int,\n    pub anchor: [::std::os::raw::c_char; 1024usize],\n    pub ticket: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_pfioc_trans_pfioc_trans_e() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_trans_pfioc_trans_e> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_trans_pfioc_trans_e>(),\n        1032usize,\n        concat!(\"Size of: \", stringify!(pfioc_trans_pfioc_trans_e))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_trans_pfioc_trans_e>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pfioc_trans_pfioc_trans_e))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rs_num) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_trans_pfioc_trans_e),\n            \"::\",\n            stringify!(rs_num)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_trans_pfioc_trans_e),\n            \"::\",\n            stringify!(anchor)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ticket) as usize - ptr as usize },\n        1028usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_trans_pfioc_trans_e),\n            \"::\",\n            stringify!(ticket)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pfioc_trans() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_trans> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_trans>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pfioc_trans))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_trans>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_trans))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).size) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_trans), \"::\", stringify!(size))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).esize) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_trans), \"::\", stringify!(esize))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).array) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_trans), \"::\", stringify!(array))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_table {\n    pub pfrio_table: pfr_table,\n    pub pfrio_buffer: *mut ::std::os::raw::c_void,\n    pub pfrio_esize: ::std::os::raw::c_int,\n    pub pfrio_size: ::std::os::raw::c_int,\n    pub pfrio_size2: ::std::os::raw::c_int,\n    pub pfrio_nadd: ::std::os::raw::c_int,\n    pub pfrio_ndel: ::std::os::raw::c_int,\n    pub pfrio_nchange: ::std::os::raw::c_int,\n    pub pfrio_flags: ::std::os::raw::c_int,\n    pub pfrio_ticket: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_pfioc_table() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_table> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_table>(),\n        1104usize,\n        concat!(\"Size of: \", stringify!(pfioc_table))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_table>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_table))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_table) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_table)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_buffer) as usize - ptr as usize },\n        1064usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_buffer)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_esize) as usize - ptr as usize },\n        1072usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_esize)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_size) as usize - ptr as usize },\n        1076usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_size)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_size2) as usize - ptr as usize },\n        1080usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_size2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_nadd) as usize - ptr as usize },\n        1084usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_nadd)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_ndel) as usize - ptr as usize },\n        1088usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_ndel)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_nchange) as usize - ptr as usize },\n        1092usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_nchange)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_flags) as usize - ptr as usize },\n        1096usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_ticket) as usize - ptr as usize },\n        1100usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_ticket)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_iface {\n    pub pfiio_name: [::std::os::raw::c_char; 16usize],\n    pub pfiio_buffer: *mut ::std::os::raw::c_void,\n    pub pfiio_esize: ::std::os::raw::c_int,\n    pub pfiio_size: ::std::os::raw::c_int,\n    pub pfiio_nzero: ::std::os::raw::c_int,\n    pub pfiio_flags: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_pfioc_iface() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_iface> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_iface>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(pfioc_iface))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_iface>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_iface))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfiio_name) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_iface),\n            \"::\",\n            stringify!(pfiio_name)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfiio_buffer) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_iface),\n            \"::\",\n            stringify!(pfiio_buffer)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfiio_esize) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_iface),\n            \"::\",\n            stringify!(pfiio_esize)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfiio_size) as usize - ptr as usize },\n        28usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_iface),\n            \"::\",\n            stringify!(pfiio_size)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfiio_nzero) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_iface),\n            \"::\",\n            stringify!(pfiio_nzero)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfiio_flags) as usize - ptr as usize },\n        36usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_iface),\n            \"::\",\n            stringify!(pfiio_flags)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_ifspeed {\n    pub ifname: [::std::os::raw::c_char; 16usize],\n    pub baudrate: u_int64_t,\n}\n#[test]\nfn bindgen_test_layout_pf_ifspeed() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_ifspeed> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_ifspeed>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(pf_ifspeed))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_ifspeed>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_ifspeed))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifname) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_ifspeed), \"::\", stringify!(ifname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).baudrate) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pf_ifspeed), \"::\", stringify!(baudrate))\n    );\n}\nunsafe extern \"C\" {\n    pub static mut pf_anchors: pf_anchor_global;\n}\nunsafe extern \"C\" {\n    pub static mut pf_main_anchor: pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_get_ruleset_number(arg1: u_int8_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn pf_init_ruleset(arg1: *mut pf_ruleset);\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_setup(\n        arg1: *mut pf_rule,\n        arg2: *const pf_ruleset,\n        arg3: *const ::std::os::raw::c_char,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_copyout(\n        arg1: *const pf_ruleset,\n        arg2: *const pf_rule,\n        arg3: *mut pfioc_rule,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_remove(arg1: *mut pf_rule);\n}\nunsafe extern \"C\" {\n    pub fn pf_remove_if_empty_ruleset(arg1: *mut pf_ruleset);\n}\nunsafe extern \"C\" {\n    pub fn pf_find_anchor(arg1: *const ::std::os::raw::c_char) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_find_ruleset(arg1: *const ::std::os::raw::c_char) -> *mut pf_ruleset;\n}\nunsafe extern \"C\" {\n    pub fn pf_find_ruleset_with_owner(\n        arg1: *const ::std::os::raw::c_char,\n        arg2: *const ::std::os::raw::c_char,\n        arg3: ::std::os::raw::c_int,\n        arg4: *mut ::std::os::raw::c_int,\n    ) -> *mut pf_ruleset;\n}\nunsafe extern \"C\" {\n    pub fn pf_find_or_create_ruleset(arg1: *const ::std::os::raw::c_char) -> *mut pf_ruleset;\n}\nunsafe extern \"C\" {\n    pub fn pf_rs_initialize();\n}\npub type __builtin_va_list = [__va_list_tag; 1usize];\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __va_list_tag {\n    pub gp_offset: ::std::os::raw::c_uint,\n    pub fp_offset: ::std::os::raw::c_uint,\n    pub overflow_arg_area: *mut ::std::os::raw::c_void,\n    pub reg_save_area: *mut ::std::os::raw::c_void,\n}\n#[test]\nfn bindgen_test_layout___va_list_tag() {\n    const UNINIT: ::std::mem::MaybeUninit<__va_list_tag> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__va_list_tag>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(__va_list_tag))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__va_list_tag>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__va_list_tag))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).gp_offset) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__va_list_tag),\n            \"::\",\n            stringify!(gp_offset)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_offset) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__va_list_tag),\n            \"::\",\n            stringify!(fp_offset)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).overflow_arg_area) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__va_list_tag),\n            \"::\",\n            stringify!(overflow_arg_area)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).reg_save_area) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__va_list_tag),\n            \"::\",\n            stringify!(reg_save_area)\n        )\n    );\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/redir/sys/unix/pfvar_bindgen_openbsd.rs",
    "content": "// automatically generated by rust-bindgen 0.69.4\n\npub const __ISO_C_VISIBLE: u32 = 2011;\npub const __XPG_VISIBLE: u32 = 700;\npub const __POSIX_VISIBLE: u32 = 200809;\npub const __BSD_VISIBLE: u32 = 1;\npub const _STACKALIGNBYTES: u32 = 15;\npub const _MAX_PAGE_SHIFT: u32 = 12;\npub const INT8_MIN: i32 = -128;\npub const INT16_MIN: i32 = -32768;\npub const INT32_MIN: i32 = -2147483648;\npub const INT64_MIN: i64 = -9223372036854775808;\npub const INT8_MAX: u32 = 127;\npub const INT16_MAX: u32 = 32767;\npub const INT32_MAX: u32 = 2147483647;\npub const INT64_MAX: u64 = 9223372036854775807;\npub const UINT8_MAX: u32 = 255;\npub const UINT16_MAX: u32 = 65535;\npub const UINT32_MAX: u32 = 4294967295;\npub const UINT64_MAX: i32 = -1;\npub const INT_LEAST8_MIN: i32 = -128;\npub const INT_LEAST16_MIN: i32 = -32768;\npub const INT_LEAST32_MIN: i32 = -2147483648;\npub const INT_LEAST64_MIN: i64 = -9223372036854775808;\npub const INT_LEAST8_MAX: u32 = 127;\npub const INT_LEAST16_MAX: u32 = 32767;\npub const INT_LEAST32_MAX: u32 = 2147483647;\npub const INT_LEAST64_MAX: u64 = 9223372036854775807;\npub const UINT_LEAST8_MAX: u32 = 255;\npub const UINT_LEAST16_MAX: u32 = 65535;\npub const UINT_LEAST32_MAX: u32 = 4294967295;\npub const UINT_LEAST64_MAX: i32 = -1;\npub const INTPTR_MIN: i64 = -9223372036854775808;\npub const INTPTR_MAX: u64 = 9223372036854775807;\npub const UINTPTR_MAX: i32 = -1;\npub const INTMAX_MIN: i64 = -9223372036854775808;\npub const INTMAX_MAX: u64 = 9223372036854775807;\npub const UINTMAX_MAX: i32 = -1;\npub const PTRDIFF_MIN: i64 = -9223372036854775808;\npub const PTRDIFF_MAX: u64 = 9223372036854775807;\npub const SIG_ATOMIC_MIN: i32 = -2147483648;\npub const SIG_ATOMIC_MAX: u32 = 2147483647;\npub const SIZE_MAX: i32 = -1;\npub const WCHAR_MIN: i32 = -2147483648;\npub const WCHAR_MAX: u32 = 2147483647;\npub const WINT_MIN: i32 = -2147483648;\npub const WINT_MAX: u32 = 2147483647;\npub const UIO_MAXIOV: u32 = 1024;\npub const _LITTLE_ENDIAN: u32 = 1234;\npub const _BIG_ENDIAN: u32 = 4321;\npub const _PDP_ENDIAN: u32 = 3412;\npub const _QUAD_HIGHWORD: u32 = 1;\npub const _QUAD_LOWWORD: u32 = 0;\npub const LITTLE_ENDIAN: u32 = 1234;\npub const BIG_ENDIAN: u32 = 4321;\npub const PDP_ENDIAN: u32 = 3412;\npub const SOCK_STREAM: u32 = 1;\npub const SOCK_DGRAM: u32 = 2;\npub const SOCK_RAW: u32 = 3;\npub const SOCK_RDM: u32 = 4;\npub const SOCK_SEQPACKET: u32 = 5;\npub const SOCK_CLOEXEC: u32 = 32768;\npub const SOCK_NONBLOCK: u32 = 16384;\npub const SOCK_DNS: u32 = 4096;\npub const SO_DEBUG: u32 = 1;\npub const SO_ACCEPTCONN: u32 = 2;\npub const SO_REUSEADDR: u32 = 4;\npub const SO_KEEPALIVE: u32 = 8;\npub const SO_DONTROUTE: u32 = 16;\npub const SO_BROADCAST: u32 = 32;\npub const SO_USELOOPBACK: u32 = 64;\npub const SO_LINGER: u32 = 128;\npub const SO_OOBINLINE: u32 = 256;\npub const SO_REUSEPORT: u32 = 512;\npub const SO_TIMESTAMP: u32 = 2048;\npub const SO_BINDANY: u32 = 4096;\npub const SO_ZEROIZE: u32 = 8192;\npub const SO_SNDBUF: u32 = 4097;\npub const SO_RCVBUF: u32 = 4098;\npub const SO_SNDLOWAT: u32 = 4099;\npub const SO_RCVLOWAT: u32 = 4100;\npub const SO_SNDTIMEO: u32 = 4101;\npub const SO_RCVTIMEO: u32 = 4102;\npub const SO_ERROR: u32 = 4103;\npub const SO_TYPE: u32 = 4104;\npub const SO_NETPROC: u32 = 4128;\npub const SO_RTABLE: u32 = 4129;\npub const SO_PEERCRED: u32 = 4130;\npub const SO_SPLICE: u32 = 4131;\npub const SO_DOMAIN: u32 = 4132;\npub const SO_PROTOCOL: u32 = 4133;\npub const RT_TABLEID_MAX: u32 = 255;\npub const RT_TABLEID_BITS: u32 = 8;\npub const RT_TABLEID_MASK: u32 = 255;\npub const SOL_SOCKET: u32 = 65535;\npub const AF_UNSPEC: u32 = 0;\npub const AF_UNIX: u32 = 1;\npub const AF_LOCAL: u32 = 1;\npub const AF_INET: u32 = 2;\npub const AF_IMPLINK: u32 = 3;\npub const AF_PUP: u32 = 4;\npub const AF_CHAOS: u32 = 5;\npub const AF_NS: u32 = 6;\npub const AF_ISO: u32 = 7;\npub const AF_OSI: u32 = 7;\npub const AF_ECMA: u32 = 8;\npub const AF_DATAKIT: u32 = 9;\npub const AF_CCITT: u32 = 10;\npub const AF_SNA: u32 = 11;\npub const AF_DECnet: u32 = 12;\npub const AF_DLI: u32 = 13;\npub const AF_LAT: u32 = 14;\npub const AF_HYLINK: u32 = 15;\npub const AF_APPLETALK: u32 = 16;\npub const AF_ROUTE: u32 = 17;\npub const AF_LINK: u32 = 18;\npub const pseudo_AF_XTP: u32 = 19;\npub const AF_COIP: u32 = 20;\npub const AF_CNT: u32 = 21;\npub const pseudo_AF_RTIP: u32 = 22;\npub const AF_IPX: u32 = 23;\npub const AF_INET6: u32 = 24;\npub const pseudo_AF_PIP: u32 = 25;\npub const AF_ISDN: u32 = 26;\npub const AF_E164: u32 = 26;\npub const AF_NATM: u32 = 27;\npub const AF_ENCAP: u32 = 28;\npub const AF_SIP: u32 = 29;\npub const AF_KEY: u32 = 30;\npub const pseudo_AF_HDRCMPLT: u32 = 31;\npub const AF_BLUETOOTH: u32 = 32;\npub const AF_MPLS: u32 = 33;\npub const pseudo_AF_PFLOW: u32 = 34;\npub const pseudo_AF_PIPEX: u32 = 35;\npub const AF_MAX: u32 = 36;\npub const PF_UNSPEC: u32 = 0;\npub const PF_LOCAL: u32 = 1;\npub const PF_UNIX: u32 = 1;\npub const PF_INET: u32 = 2;\npub const PF_IMPLINK: u32 = 3;\npub const PF_PUP: u32 = 4;\npub const PF_CHAOS: u32 = 5;\npub const PF_NS: u32 = 6;\npub const PF_ISO: u32 = 7;\npub const PF_OSI: u32 = 7;\npub const PF_ECMA: u32 = 8;\npub const PF_DATAKIT: u32 = 9;\npub const PF_CCITT: u32 = 10;\npub const PF_SNA: u32 = 11;\npub const PF_DECnet: u32 = 12;\npub const PF_DLI: u32 = 13;\npub const PF_LAT: u32 = 14;\npub const PF_HYLINK: u32 = 15;\npub const PF_APPLETALK: u32 = 16;\npub const PF_ROUTE: u32 = 17;\npub const PF_LINK: u32 = 18;\npub const PF_XTP: u32 = 19;\npub const PF_COIP: u32 = 20;\npub const PF_CNT: u32 = 21;\npub const PF_IPX: u32 = 23;\npub const PF_INET6: u32 = 24;\npub const PF_RTIP: u32 = 22;\npub const PF_PIP: u32 = 25;\npub const PF_ISDN: u32 = 26;\npub const PF_NATM: u32 = 27;\npub const PF_ENCAP: u32 = 28;\npub const PF_SIP: u32 = 29;\npub const PF_KEY: u32 = 30;\npub const PF_BPF: u32 = 31;\npub const PF_BLUETOOTH: u32 = 32;\npub const PF_MPLS: u32 = 33;\npub const PF_PFLOW: u32 = 34;\npub const PF_PIPEX: u32 = 35;\npub const PF_MAX: u32 = 36;\npub const SHUT_RD: u32 = 0;\npub const SHUT_WR: u32 = 1;\npub const SHUT_RDWR: u32 = 2;\npub const NET_MAXID: u32 = 36;\npub const NET_RT_DUMP: u32 = 1;\npub const NET_RT_FLAGS: u32 = 2;\npub const NET_RT_IFLIST: u32 = 3;\npub const NET_RT_STATS: u32 = 4;\npub const NET_RT_TABLE: u32 = 5;\npub const NET_RT_IFNAMES: u32 = 6;\npub const NET_RT_SOURCE: u32 = 7;\npub const NET_RT_MAXID: u32 = 8;\npub const NET_UNIX_INFLIGHT: u32 = 6;\npub const NET_UNIX_DEFERRED: u32 = 7;\npub const NET_UNIX_MAXID: u32 = 8;\npub const UNPCTL_RECVSPACE: u32 = 1;\npub const UNPCTL_SENDSPACE: u32 = 2;\npub const NET_UNIX_PROTO_MAXID: u32 = 3;\npub const NET_LINK_IFRXQ: u32 = 1;\npub const NET_LINK_MAXID: u32 = 2;\npub const NET_LINK_IFRXQ_PRESSURE_RETURN: u32 = 1;\npub const NET_LINK_IFRXQ_PRESSURE_DROP: u32 = 2;\npub const NET_LINK_IFRXQ_MAXID: u32 = 3;\npub const NET_KEY_SADB_DUMP: u32 = 1;\npub const NET_KEY_SPD_DUMP: u32 = 2;\npub const NET_KEY_MAXID: u32 = 3;\npub const NET_BPF_BUFSIZE: u32 = 1;\npub const NET_BPF_MAXBUFSIZE: u32 = 2;\npub const NET_BPF_MAXID: u32 = 3;\npub const NET_PFLOW_STATS: u32 = 1;\npub const NET_PFLOW_MAXID: u32 = 2;\npub const SOMAXCONN: u32 = 128;\npub const MSG_OOB: u32 = 1;\npub const MSG_PEEK: u32 = 2;\npub const MSG_DONTROUTE: u32 = 4;\npub const MSG_EOR: u32 = 8;\npub const MSG_TRUNC: u32 = 16;\npub const MSG_CTRUNC: u32 = 32;\npub const MSG_WAITALL: u32 = 64;\npub const MSG_DONTWAIT: u32 = 128;\npub const MSG_BCAST: u32 = 256;\npub const MSG_MCAST: u32 = 512;\npub const MSG_NOSIGNAL: u32 = 1024;\npub const MSG_CMSG_CLOEXEC: u32 = 2048;\npub const MSG_WAITFORONE: u32 = 4096;\npub const SCM_RIGHTS: u32 = 1;\npub const SCM_TIMESTAMP: u32 = 4;\npub const IF_NAMESIZE: u32 = 16;\npub const FD_SETSIZE: u32 = 1024;\npub const __NBBY: u32 = 8;\npub const NBBY: u32 = 8;\npub const DST_NONE: u32 = 0;\npub const DST_USA: u32 = 1;\npub const DST_AUST: u32 = 2;\npub const DST_WET: u32 = 3;\npub const DST_MET: u32 = 4;\npub const DST_EET: u32 = 5;\npub const DST_CAN: u32 = 6;\npub const ITIMER_REAL: u32 = 0;\npub const ITIMER_VIRTUAL: u32 = 1;\npub const ITIMER_PROF: u32 = 2;\npub const CLOCKS_PER_SEC: u32 = 100;\npub const CLOCK_REALTIME: u32 = 0;\npub const CLOCK_PROCESS_CPUTIME_ID: u32 = 2;\npub const CLOCK_MONOTONIC: u32 = 3;\npub const CLOCK_THREAD_CPUTIME_ID: u32 = 4;\npub const CLOCK_UPTIME: u32 = 5;\npub const CLOCK_BOOTTIME: u32 = 6;\npub const TIMER_RELTIME: u32 = 0;\npub const TIMER_ABSTIME: u32 = 1;\npub const CLK_TCK: u32 = 100;\npub const TIME_UTC: u32 = 1;\npub const MCLPOOLS: u32 = 8;\npub const IFQ_NQUEUES: u32 = 8;\npub const IFQ_MINPRIO: u32 = 0;\npub const IFQ_MAXPRIO: u32 = 7;\npub const IFQ_DEFPRIO: u32 = 3;\npub const LINK_STATE_UNKNOWN: u32 = 0;\npub const LINK_STATE_INVALID: u32 = 1;\npub const LINK_STATE_DOWN: u32 = 2;\npub const LINK_STATE_KALIVE_DOWN: u32 = 3;\npub const LINK_STATE_UP: u32 = 4;\npub const LINK_STATE_HALF_DUPLEX: u32 = 5;\npub const LINK_STATE_FULL_DUPLEX: u32 = 6;\npub const IFNAMSIZ: u32 = 16;\npub const IFDESCRSIZE: u32 = 64;\npub const IFF_UP: u32 = 1;\npub const IFF_BROADCAST: u32 = 2;\npub const IFF_DEBUG: u32 = 4;\npub const IFF_LOOPBACK: u32 = 8;\npub const IFF_POINTOPOINT: u32 = 16;\npub const IFF_STATICARP: u32 = 32;\npub const IFF_RUNNING: u32 = 64;\npub const IFF_NOARP: u32 = 128;\npub const IFF_PROMISC: u32 = 256;\npub const IFF_ALLMULTI: u32 = 512;\npub const IFF_OACTIVE: u32 = 1024;\npub const IFF_SIMPLEX: u32 = 2048;\npub const IFF_LINK0: u32 = 4096;\npub const IFF_LINK1: u32 = 8192;\npub const IFF_LINK2: u32 = 16384;\npub const IFF_MULTICAST: u32 = 32768;\npub const IFF_CANTCHANGE: u32 = 36434;\npub const IFXF_MPSAFE: u32 = 1;\npub const IFXF_CLONED: u32 = 2;\npub const IFXF_AUTOCONF6TEMP: u32 = 4;\npub const IFXF_MPLS: u32 = 8;\npub const IFXF_WOL: u32 = 16;\npub const IFXF_AUTOCONF6: u32 = 32;\npub const IFXF_INET6_NOSOII: u32 = 64;\npub const IFXF_AUTOCONF4: u32 = 128;\npub const IFXF_MONITOR: u32 = 256;\npub const IFXF_LRO: u32 = 512;\npub const IFXF_CANTCHANGE: u32 = 3;\npub const IFCAP_CSUM_IPv4: u32 = 1;\npub const IFCAP_CSUM_TCPv4: u32 = 2;\npub const IFCAP_CSUM_UDPv4: u32 = 4;\npub const IFCAP_VLAN_MTU: u32 = 16;\npub const IFCAP_VLAN_HWTAGGING: u32 = 32;\npub const IFCAP_CSUM_TCPv6: u32 = 128;\npub const IFCAP_CSUM_UDPv6: u32 = 256;\npub const IFCAP_TSOv4: u32 = 4096;\npub const IFCAP_TSOv6: u32 = 8192;\npub const IFCAP_LRO: u32 = 16384;\npub const IFCAP_WOL: u32 = 32768;\npub const IFCAP_CSUM_MASK: u32 = 391;\npub const IFQCTL_LEN: u32 = 1;\npub const IFQCTL_MAXLEN: u32 = 2;\npub const IFQCTL_DROPS: u32 = 3;\npub const IFQCTL_CONGESTION: u32 = 4;\npub const IFQCTL_MAXID: u32 = 5;\npub const IFAN_ARRIVAL: u32 = 0;\npub const IFAN_DEPARTURE: u32 = 1;\npub const IFG_ALL: &[u8; 4] = b\"all\\0\";\npub const IFG_EGRESS: &[u8; 7] = b\"egress\\0\";\npub const IF_HDRPRIO_MIN: u32 = 0;\npub const IF_HDRPRIO_MAX: u32 = 7;\npub const IF_HDRPRIO_PACKET: i32 = -1;\npub const IF_HDRPRIO_PAYLOAD: i32 = -2;\npub const IF_HDRPRIO_OUTER: i32 = -3;\npub const IF_PWE3_ETHERNET: u32 = 1;\npub const IF_PWE3_IP: u32 = 2;\npub const IFLR_PREFIX: u32 = 32768;\npub const IFSFF_ADDR_EEPROM: u32 = 160;\npub const IFSFF_ADDR_DDM: u32 = 162;\npub const IFSFF_DATA_LEN: u32 = 256;\npub const ARPHRD_ETHER: u32 = 1;\npub const ARPHRD_IEEE802: u32 = 6;\npub const ARPHRD_FRELAY: u32 = 15;\npub const ARPHRD_IEEE1394: u32 = 24;\npub const ARPOP_REQUEST: u32 = 1;\npub const ARPOP_REPLY: u32 = 2;\npub const ARPOP_REVREQUEST: u32 = 3;\npub const ARPOP_REVREPLY: u32 = 4;\npub const ARPOP_INVREQUEST: u32 = 8;\npub const ARPOP_INVREPLY: u32 = 9;\npub const ATF_INUSE: u32 = 1;\npub const ATF_COM: u32 = 2;\npub const ATF_PERM: u32 = 4;\npub const ATF_PUBL: u32 = 8;\npub const ATF_USETRAILERS: u32 = 16;\npub const SPLAY_NEGINF: i32 = -1;\npub const SPLAY_INF: u32 = 1;\npub const RB_BLACK: u32 = 0;\npub const RB_RED: u32 = 1;\npub const RB_NEGINF: i32 = -1;\npub const RB_INF: u32 = 1;\npub const LO_CLASSFLAGS: u32 = 65535;\npub const LO_INITIALIZED: u32 = 65536;\npub const LO_WITNESS: u32 = 131072;\npub const LO_QUIET: u32 = 262144;\npub const LO_RECURSABLE: u32 = 524288;\npub const LO_SLEEPABLE: u32 = 1048576;\npub const LO_UPGRADABLE: u32 = 2097152;\npub const LO_DUPOK: u32 = 4194304;\npub const LO_IS_VNODE: u32 = 8388608;\npub const LO_CLASSMASK: u32 = 251658240;\npub const LO_NOPROFILE: u32 = 268435456;\npub const LO_NEW: u32 = 536870912;\npub const LO_CLASSSHIFT: u32 = 24;\npub const RWL_DUPOK: u32 = 1;\npub const RWL_NOWITNESS: u32 = 2;\npub const RWL_IS_VNODE: u32 = 4;\npub const RWLOCK_WAIT: u32 = 1;\npub const RWLOCK_WRWANT: u32 = 2;\npub const RWLOCK_WRLOCK: u32 = 4;\npub const RWLOCK_MASK: u32 = 7;\npub const RWLOCK_READER_SHIFT: u32 = 3;\npub const RWLOCK_READ_INCR: u32 = 8;\npub const RW_WRITE: u32 = 1;\npub const RW_READ: u32 = 2;\npub const RW_DOWNGRADE: u32 = 4;\npub const RW_OPMASK: u32 = 7;\npub const RW_INTR: u32 = 16;\npub const RW_SLEEPFAIL: u32 = 32;\npub const RW_NOSLEEP: u32 = 64;\npub const RW_RECURSEFAIL: u32 = 128;\npub const RW_DUPOK: u32 = 256;\npub const RW_WRITE_OTHER: u32 = 256;\npub const ARG_MAX: u32 = 524288;\npub const CHILD_MAX: u32 = 80;\npub const LINK_MAX: u32 = 32767;\npub const MAX_CANON: u32 = 255;\npub const MAX_INPUT: u32 = 255;\npub const NAME_MAX: u32 = 255;\npub const NGROUPS_MAX: u32 = 16;\npub const OPEN_MAX: u32 = 64;\npub const PATH_MAX: u32 = 1024;\npub const PIPE_BUF: u32 = 512;\npub const SYMLINK_MAX: u32 = 1024;\npub const SYMLOOP_MAX: u32 = 32;\npub const BC_DIM_MAX: u32 = 65535;\npub const COLL_WEIGHTS_MAX: u32 = 2;\npub const EXPR_NEST_MAX: u32 = 32;\npub const LINE_MAX: u32 = 2048;\npub const RE_DUP_MAX: u32 = 255;\npub const IOV_MAX: u32 = 1024;\npub const NZERO: u32 = 20;\npub const TTY_NAME_MAX: u32 = 260;\npub const LOGIN_NAME_MAX: u32 = 32;\npub const HOST_NAME_MAX: u32 = 255;\npub const _MAXCOMLEN: u32 = 24;\npub const TIMEOUT_PROC: u32 = 1;\npub const TIMEOUT_ONQUEUE: u32 = 2;\npub const TIMEOUT_INITIALIZED: u32 = 4;\npub const TIMEOUT_TRIGGERED: u32 = 8;\npub const TIMEOUT_MPSAFE: u32 = 16;\npub const IPPROTO_IP: u32 = 0;\npub const IPPROTO_HOPOPTS: u32 = 0;\npub const IPPROTO_ICMP: u32 = 1;\npub const IPPROTO_IGMP: u32 = 2;\npub const IPPROTO_GGP: u32 = 3;\npub const IPPROTO_IPIP: u32 = 4;\npub const IPPROTO_IPV4: u32 = 4;\npub const IPPROTO_TCP: u32 = 6;\npub const IPPROTO_EGP: u32 = 8;\npub const IPPROTO_PUP: u32 = 12;\npub const IPPROTO_UDP: u32 = 17;\npub const IPPROTO_IDP: u32 = 22;\npub const IPPROTO_TP: u32 = 29;\npub const IPPROTO_IPV6: u32 = 41;\npub const IPPROTO_ROUTING: u32 = 43;\npub const IPPROTO_FRAGMENT: u32 = 44;\npub const IPPROTO_RSVP: u32 = 46;\npub const IPPROTO_GRE: u32 = 47;\npub const IPPROTO_ESP: u32 = 50;\npub const IPPROTO_AH: u32 = 51;\npub const IPPROTO_MOBILE: u32 = 55;\npub const IPPROTO_ICMPV6: u32 = 58;\npub const IPPROTO_NONE: u32 = 59;\npub const IPPROTO_DSTOPTS: u32 = 60;\npub const IPPROTO_EON: u32 = 80;\npub const IPPROTO_ETHERIP: u32 = 97;\npub const IPPROTO_ENCAP: u32 = 98;\npub const IPPROTO_PIM: u32 = 103;\npub const IPPROTO_IPCOMP: u32 = 108;\npub const IPPROTO_CARP: u32 = 112;\npub const IPPROTO_SCTP: u32 = 132;\npub const IPPROTO_UDPLITE: u32 = 136;\npub const IPPROTO_MPLS: u32 = 137;\npub const IPPROTO_PFSYNC: u32 = 240;\npub const IPPROTO_RAW: u32 = 255;\npub const IPPROTO_MAX: u32 = 256;\npub const IPPROTO_DIVERT: u32 = 258;\npub const IPPORT_RESERVED: u32 = 1024;\npub const IPPORT_USERRESERVED: u32 = 49151;\npub const IPPORT_HIFIRSTAUTO: u32 = 49152;\npub const IPPORT_HILASTAUTO: u32 = 65535;\npub const IPPROTO_DONE: u32 = 257;\npub const IN_CLASSA_NSHIFT: u32 = 24;\npub const IN_CLASSA_MAX: u32 = 128;\npub const IN_CLASSB_NSHIFT: u32 = 16;\npub const IN_CLASSB_MAX: u32 = 65536;\npub const IN_CLASSC_NSHIFT: u32 = 8;\npub const IN_CLASSD_NSHIFT: u32 = 28;\npub const IN_RFC3021_NSHIFT: u32 = 31;\npub const IN_LOOPBACKNET: u32 = 127;\npub const IP_OPTIONS: u32 = 1;\npub const IP_HDRINCL: u32 = 2;\npub const IP_TOS: u32 = 3;\npub const IP_TTL: u32 = 4;\npub const IP_RECVOPTS: u32 = 5;\npub const IP_RECVRETOPTS: u32 = 6;\npub const IP_RECVDSTADDR: u32 = 7;\npub const IP_RETOPTS: u32 = 8;\npub const IP_MULTICAST_IF: u32 = 9;\npub const IP_MULTICAST_TTL: u32 = 10;\npub const IP_MULTICAST_LOOP: u32 = 11;\npub const IP_ADD_MEMBERSHIP: u32 = 12;\npub const IP_DROP_MEMBERSHIP: u32 = 13;\npub const IP_PORTRANGE: u32 = 19;\npub const IP_AUTH_LEVEL: u32 = 20;\npub const IP_ESP_TRANS_LEVEL: u32 = 21;\npub const IP_ESP_NETWORK_LEVEL: u32 = 22;\npub const IP_IPSEC_LOCAL_ID: u32 = 23;\npub const IP_IPSEC_REMOTE_ID: u32 = 24;\npub const IP_IPSEC_LOCAL_CRED: u32 = 25;\npub const IP_IPSEC_REMOTE_CRED: u32 = 26;\npub const IP_IPSEC_LOCAL_AUTH: u32 = 27;\npub const IP_IPSEC_REMOTE_AUTH: u32 = 28;\npub const IP_IPCOMP_LEVEL: u32 = 29;\npub const IP_RECVIF: u32 = 30;\npub const IP_RECVTTL: u32 = 31;\npub const IP_MINTTL: u32 = 32;\npub const IP_RECVDSTPORT: u32 = 33;\npub const IP_PIPEX: u32 = 34;\npub const IP_RECVRTABLE: u32 = 35;\npub const IP_IPSECFLOWINFO: u32 = 36;\npub const IP_IPDEFTTL: u32 = 37;\npub const IP_SENDSRCADDR: u32 = 7;\npub const IP_RTABLE: u32 = 4129;\npub const IPSEC_LEVEL_BYPASS: u32 = 0;\npub const IPSEC_LEVEL_NONE: u32 = 0;\npub const IPSEC_LEVEL_AVAIL: u32 = 1;\npub const IPSEC_LEVEL_USE: u32 = 2;\npub const IPSEC_LEVEL_REQUIRE: u32 = 3;\npub const IPSEC_LEVEL_UNIQUE: u32 = 4;\npub const IPSEC_LEVEL_DEFAULT: u32 = 1;\npub const IPSEC_AUTH_LEVEL_DEFAULT: u32 = 1;\npub const IPSEC_ESP_TRANS_LEVEL_DEFAULT: u32 = 1;\npub const IPSEC_ESP_NETWORK_LEVEL_DEFAULT: u32 = 1;\npub const IPSEC_IPCOMP_LEVEL_DEFAULT: u32 = 1;\npub const IP_DEFAULT_MULTICAST_TTL: u32 = 1;\npub const IP_DEFAULT_MULTICAST_LOOP: u32 = 1;\npub const IP_MIN_MEMBERSHIPS: u32 = 15;\npub const IP_MAX_MEMBERSHIPS: u32 = 4095;\npub const IP_PORTRANGE_DEFAULT: u32 = 0;\npub const IP_PORTRANGE_HIGH: u32 = 1;\npub const IP_PORTRANGE_LOW: u32 = 2;\npub const INET_ADDRSTRLEN: u32 = 16;\npub const IPPROTO_MAXID: u32 = 259;\npub const IPCTL_FORWARDING: u32 = 1;\npub const IPCTL_SENDREDIRECTS: u32 = 2;\npub const IPCTL_DEFTTL: u32 = 3;\npub const IPCTL_SOURCEROUTE: u32 = 5;\npub const IPCTL_DIRECTEDBCAST: u32 = 6;\npub const IPCTL_IPPORT_FIRSTAUTO: u32 = 7;\npub const IPCTL_IPPORT_LASTAUTO: u32 = 8;\npub const IPCTL_IPPORT_HIFIRSTAUTO: u32 = 9;\npub const IPCTL_IPPORT_HILASTAUTO: u32 = 10;\npub const IPCTL_IPPORT_MAXQUEUE: u32 = 11;\npub const IPCTL_ENCDEBUG: u32 = 12;\npub const IPCTL_IPSEC_STATS: u32 = 13;\npub const IPCTL_IPSEC_EXPIRE_ACQUIRE: u32 = 14;\npub const IPCTL_IPSEC_EMBRYONIC_SA_TIMEOUT: u32 = 15;\npub const IPCTL_IPSEC_REQUIRE_PFS: u32 = 16;\npub const IPCTL_IPSEC_SOFT_ALLOCATIONS: u32 = 17;\npub const IPCTL_IPSEC_ALLOCATIONS: u32 = 18;\npub const IPCTL_IPSEC_SOFT_BYTES: u32 = 19;\npub const IPCTL_IPSEC_BYTES: u32 = 20;\npub const IPCTL_IPSEC_TIMEOUT: u32 = 21;\npub const IPCTL_IPSEC_SOFT_TIMEOUT: u32 = 22;\npub const IPCTL_IPSEC_SOFT_FIRSTUSE: u32 = 23;\npub const IPCTL_IPSEC_FIRSTUSE: u32 = 24;\npub const IPCTL_IPSEC_ENC_ALGORITHM: u32 = 25;\npub const IPCTL_IPSEC_AUTH_ALGORITHM: u32 = 26;\npub const IPCTL_MTUDISC: u32 = 27;\npub const IPCTL_MTUDISCTIMEOUT: u32 = 28;\npub const IPCTL_IPSEC_IPCOMP_ALGORITHM: u32 = 29;\npub const IPCTL_IFQUEUE: u32 = 30;\npub const IPCTL_MFORWARDING: u32 = 31;\npub const IPCTL_MULTIPATH: u32 = 32;\npub const IPCTL_STATS: u32 = 33;\npub const IPCTL_MRTPROTO: u32 = 34;\npub const IPCTL_MRTSTATS: u32 = 35;\npub const IPCTL_ARPQUEUED: u32 = 36;\npub const IPCTL_MRTMFC: u32 = 37;\npub const IPCTL_MRTVIF: u32 = 38;\npub const IPCTL_ARPTIMEOUT: u32 = 39;\npub const IPCTL_ARPDOWN: u32 = 40;\npub const IPCTL_ARPQUEUE: u32 = 41;\npub const IPCTL_MAXID: u32 = 42;\npub const INET6_ADDRSTRLEN: u32 = 46;\npub const __IPV6_ADDR_SCOPE_NODELOCAL: u32 = 1;\npub const __IPV6_ADDR_SCOPE_INTFACELOCAL: u32 = 1;\npub const __IPV6_ADDR_SCOPE_LINKLOCAL: u32 = 2;\npub const __IPV6_ADDR_SCOPE_SITELOCAL: u32 = 5;\npub const __IPV6_ADDR_SCOPE_ORGLOCAL: u32 = 8;\npub const __IPV6_ADDR_SCOPE_GLOBAL: u32 = 14;\npub const IPV6_UNICAST_HOPS: u32 = 4;\npub const IPV6_MULTICAST_IF: u32 = 9;\npub const IPV6_MULTICAST_HOPS: u32 = 10;\npub const IPV6_MULTICAST_LOOP: u32 = 11;\npub const IPV6_JOIN_GROUP: u32 = 12;\npub const IPV6_LEAVE_GROUP: u32 = 13;\npub const IPV6_PORTRANGE: u32 = 14;\npub const ICMP6_FILTER: u32 = 18;\npub const IPV6_CHECKSUM: u32 = 26;\npub const IPV6_V6ONLY: u32 = 27;\npub const IPV6_RTHDRDSTOPTS: u32 = 35;\npub const IPV6_RECVPKTINFO: u32 = 36;\npub const IPV6_RECVHOPLIMIT: u32 = 37;\npub const IPV6_RECVRTHDR: u32 = 38;\npub const IPV6_RECVHOPOPTS: u32 = 39;\npub const IPV6_RECVDSTOPTS: u32 = 40;\npub const IPV6_USE_MIN_MTU: u32 = 42;\npub const IPV6_RECVPATHMTU: u32 = 43;\npub const IPV6_PATHMTU: u32 = 44;\npub const IPV6_PKTINFO: u32 = 46;\npub const IPV6_HOPLIMIT: u32 = 47;\npub const IPV6_NEXTHOP: u32 = 48;\npub const IPV6_HOPOPTS: u32 = 49;\npub const IPV6_DSTOPTS: u32 = 50;\npub const IPV6_RTHDR: u32 = 51;\npub const IPV6_AUTH_LEVEL: u32 = 53;\npub const IPV6_ESP_TRANS_LEVEL: u32 = 54;\npub const IPV6_ESP_NETWORK_LEVEL: u32 = 55;\npub const IPSEC6_OUTSA: u32 = 56;\npub const IPV6_RECVTCLASS: u32 = 57;\npub const IPV6_AUTOFLOWLABEL: u32 = 59;\npub const IPV6_IPCOMP_LEVEL: u32 = 60;\npub const IPV6_TCLASS: u32 = 61;\npub const IPV6_DONTFRAG: u32 = 62;\npub const IPV6_PIPEX: u32 = 63;\npub const IPV6_RECVDSTPORT: u32 = 64;\npub const IPV6_MINHOPCOUNT: u32 = 65;\npub const IPV6_RTABLE: u32 = 4129;\npub const IPV6_RTHDR_LOOSE: u32 = 0;\npub const IPV6_RTHDR_TYPE_0: u32 = 0;\npub const IPV6_DEFAULT_MULTICAST_HOPS: u32 = 1;\npub const IPV6_DEFAULT_MULTICAST_LOOP: u32 = 1;\npub const IPV6_PORTRANGE_DEFAULT: u32 = 0;\npub const IPV6_PORTRANGE_HIGH: u32 = 1;\npub const IPV6_PORTRANGE_LOW: u32 = 2;\npub const IPV6PROTO_MAXID: u32 = 259;\npub const IPV6CTL_FORWARDING: u32 = 1;\npub const IPV6CTL_SENDREDIRECTS: u32 = 2;\npub const IPV6CTL_DEFHLIM: u32 = 3;\npub const IPV6CTL_FORWSRCRT: u32 = 5;\npub const IPV6CTL_STATS: u32 = 6;\npub const IPV6CTL_MRTSTATS: u32 = 7;\npub const IPV6CTL_MRTPROTO: u32 = 8;\npub const IPV6CTL_MAXFRAGPACKETS: u32 = 9;\npub const IPV6CTL_SOURCECHECK: u32 = 10;\npub const IPV6CTL_SOURCECHECK_LOGINT: u32 = 11;\npub const IPV6CTL_ACCEPT_RTADV: u32 = 12;\npub const IPV6CTL_LOG_INTERVAL: u32 = 14;\npub const IPV6CTL_HDRNESTLIMIT: u32 = 15;\npub const IPV6CTL_DAD_COUNT: u32 = 16;\npub const IPV6CTL_AUTO_FLOWLABEL: u32 = 17;\npub const IPV6CTL_DEFMCASTHLIM: u32 = 18;\npub const IPV6CTL_USE_DEPRECATED: u32 = 21;\npub const IPV6CTL_MAXFRAGS: u32 = 41;\npub const IPV6CTL_MFORWARDING: u32 = 42;\npub const IPV6CTL_MULTIPATH: u32 = 43;\npub const IPV6CTL_MCAST_PMTU: u32 = 44;\npub const IPV6CTL_NEIGHBORGCTHRESH: u32 = 45;\npub const IPV6CTL_MAXDYNROUTES: u32 = 48;\npub const IPV6CTL_DAD_PENDING: u32 = 49;\npub const IPV6CTL_MTUDISCTIMEOUT: u32 = 50;\npub const IPV6CTL_IFQUEUE: u32 = 51;\npub const IPV6CTL_MRTMIF: u32 = 52;\npub const IPV6CTL_MRTMFC: u32 = 53;\npub const IPV6CTL_SOIIKEY: u32 = 54;\npub const IPV6CTL_MAXID: u32 = 55;\npub const RNF_NORMAL: u32 = 1;\npub const RNF_ROOT: u32 = 2;\npub const RNF_ACTIVE: u32 = 4;\npub const RTF_UP: u32 = 1;\npub const RTF_GATEWAY: u32 = 2;\npub const RTF_HOST: u32 = 4;\npub const RTF_REJECT: u32 = 8;\npub const RTF_DYNAMIC: u32 = 16;\npub const RTF_MODIFIED: u32 = 32;\npub const RTF_DONE: u32 = 64;\npub const RTF_CLONING: u32 = 256;\npub const RTF_MULTICAST: u32 = 512;\npub const RTF_LLINFO: u32 = 1024;\npub const RTF_STATIC: u32 = 2048;\npub const RTF_BLACKHOLE: u32 = 4096;\npub const RTF_PROTO3: u32 = 8192;\npub const RTF_PROTO2: u32 = 16384;\npub const RTF_ANNOUNCE: u32 = 16384;\npub const RTF_PROTO1: u32 = 32768;\npub const RTF_CLONED: u32 = 65536;\npub const RTF_CACHED: u32 = 131072;\npub const RTF_MPATH: u32 = 262144;\npub const RTF_MPLS: u32 = 1048576;\npub const RTF_LOCAL: u32 = 2097152;\npub const RTF_BROADCAST: u32 = 4194304;\npub const RTF_CONNECTED: u32 = 8388608;\npub const RTF_BFD: u32 = 16777216;\npub const RTF_FMASK: u32 = 17890312;\npub const RTP_NONE: u32 = 0;\npub const RTP_LOCAL: u32 = 1;\npub const RTP_CONNECTED: u32 = 4;\npub const RTP_STATIC: u32 = 8;\npub const RTP_EIGRP: u32 = 28;\npub const RTP_OSPF: u32 = 32;\npub const RTP_ISIS: u32 = 36;\npub const RTP_RIP: u32 = 40;\npub const RTP_BGP: u32 = 48;\npub const RTP_DEFAULT: u32 = 56;\npub const RTP_PROPOSAL_STATIC: u32 = 57;\npub const RTP_PROPOSAL_DHCLIENT: u32 = 58;\npub const RTP_PROPOSAL_SLAAC: u32 = 59;\npub const RTP_PROPOSAL_UMB: u32 = 60;\npub const RTP_PROPOSAL_PPP: u32 = 61;\npub const RTP_PROPOSAL_SOLICIT: u32 = 62;\npub const RTP_MAX: u32 = 63;\npub const RTP_ANY: u32 = 64;\npub const RTP_MASK: u32 = 127;\npub const RTP_DOWN: u32 = 128;\npub const RTM_VERSION: u32 = 5;\npub const RTM_MAXSIZE: u32 = 2048;\npub const RTM_ADD: u32 = 1;\npub const RTM_DELETE: u32 = 2;\npub const RTM_CHANGE: u32 = 3;\npub const RTM_GET: u32 = 4;\npub const RTM_LOSING: u32 = 5;\npub const RTM_REDIRECT: u32 = 6;\npub const RTM_MISS: u32 = 7;\npub const RTM_RESOLVE: u32 = 11;\npub const RTM_NEWADDR: u32 = 12;\npub const RTM_DELADDR: u32 = 13;\npub const RTM_IFINFO: u32 = 14;\npub const RTM_IFANNOUNCE: u32 = 15;\npub const RTM_DESYNC: u32 = 16;\npub const RTM_INVALIDATE: u32 = 17;\npub const RTM_BFD: u32 = 18;\npub const RTM_PROPOSAL: u32 = 19;\npub const RTM_CHGADDRATTR: u32 = 20;\npub const RTM_80211INFO: u32 = 21;\npub const RTM_SOURCE: u32 = 22;\npub const RTV_MTU: u32 = 1;\npub const RTV_HOPCOUNT: u32 = 2;\npub const RTV_EXPIRE: u32 = 4;\npub const RTV_RPIPE: u32 = 8;\npub const RTV_SPIPE: u32 = 16;\npub const RTV_SSTHRESH: u32 = 32;\npub const RTV_RTT: u32 = 64;\npub const RTV_RTTVAR: u32 = 128;\npub const RTA_DST: u32 = 1;\npub const RTA_GATEWAY: u32 = 2;\npub const RTA_NETMASK: u32 = 4;\npub const RTA_GENMASK: u32 = 8;\npub const RTA_IFP: u32 = 16;\npub const RTA_IFA: u32 = 32;\npub const RTA_AUTHOR: u32 = 64;\npub const RTA_BRD: u32 = 128;\npub const RTA_SRC: u32 = 256;\npub const RTA_SRCMASK: u32 = 512;\npub const RTA_LABEL: u32 = 1024;\npub const RTA_BFD: u32 = 2048;\npub const RTA_DNS: u32 = 4096;\npub const RTA_STATIC: u32 = 8192;\npub const RTA_SEARCH: u32 = 16384;\npub const RTAX_DST: u32 = 0;\npub const RTAX_GATEWAY: u32 = 1;\npub const RTAX_NETMASK: u32 = 2;\npub const RTAX_GENMASK: u32 = 3;\npub const RTAX_IFP: u32 = 4;\npub const RTAX_IFA: u32 = 5;\npub const RTAX_AUTHOR: u32 = 6;\npub const RTAX_BRD: u32 = 7;\npub const RTAX_SRC: u32 = 8;\npub const RTAX_SRCMASK: u32 = 9;\npub const RTAX_LABEL: u32 = 10;\npub const RTAX_BFD: u32 = 11;\npub const RTAX_DNS: u32 = 12;\npub const RTAX_STATIC: u32 = 13;\npub const RTAX_SEARCH: u32 = 14;\npub const RTAX_MAX: u32 = 15;\npub const ROUTE_MSGFILTER: u32 = 1;\npub const ROUTE_TABLEFILTER: u32 = 2;\npub const ROUTE_PRIOFILTER: u32 = 3;\npub const ROUTE_FLAGFILTER: u32 = 4;\npub const RTABLE_ANY: u32 = 4294967295;\npub const RTLABEL_LEN: u32 = 32;\npub const RTDNS_LEN: u32 = 128;\npub const RTSTATIC_LEN: u32 = 128;\npub const RTSEARCH_LEN: u32 = 128;\npub const PF_MD5_DIGEST_LENGTH: u32 = 16;\npub const PFTM_TCP_FIRST_PACKET_VAL: u32 = 120;\npub const PFTM_TCP_OPENING_VAL: u32 = 30;\npub const PFTM_TCP_ESTABLISHED_VAL: u32 = 86400;\npub const PFTM_TCP_CLOSING_VAL: u32 = 900;\npub const PFTM_TCP_FIN_WAIT_VAL: u32 = 45;\npub const PFTM_TCP_CLOSED_VAL: u32 = 90;\npub const PFTM_UDP_FIRST_PACKET_VAL: u32 = 60;\npub const PFTM_UDP_SINGLE_VAL: u32 = 30;\npub const PFTM_UDP_MULTIPLE_VAL: u32 = 60;\npub const PFTM_ICMP_FIRST_PACKET_VAL: u32 = 20;\npub const PFTM_ICMP_ERROR_REPLY_VAL: u32 = 10;\npub const PFTM_OTHER_FIRST_PACKET_VAL: u32 = 60;\npub const PFTM_OTHER_SINGLE_VAL: u32 = 30;\npub const PFTM_OTHER_MULTIPLE_VAL: u32 = 60;\npub const PFTM_FRAG_VAL: u32 = 60;\npub const PFTM_INTERVAL_VAL: u32 = 10;\npub const PFTM_SRC_NODE_VAL: u32 = 0;\npub const PFTM_TS_DIFF_VAL: u32 = 30;\npub const PF_FRAG_STALE: u32 = 200;\npub const PF_FRAG_ENTRY_POINTS: u32 = 16;\npub const PF_FRAG_ENTRY_LIMIT: u32 = 64;\npub const PF_POOL_IDMASK: u32 = 15;\npub const PF_POOL_TYPEMASK: u32 = 15;\npub const PF_POOL_STICKYADDR: u32 = 32;\npub const PF_WSCALE_FLAG: u32 = 128;\npub const PF_WSCALE_MASK: u32 = 15;\npub const PF_LOG: u32 = 1;\npub const PF_LOG_ALL: u32 = 2;\npub const PF_LOG_USER: u32 = 4;\npub const PF_LOG_FORCE: u32 = 8;\npub const PF_LOG_MATCHES: u32 = 16;\npub const PF_TABLE_NAME_SIZE: u32 = 32;\npub const PFI_AFLAG_NETWORK: u32 = 1;\npub const PFI_AFLAG_BROADCAST: u32 = 2;\npub const PFI_AFLAG_PEER: u32 = 4;\npub const PFI_AFLAG_MODEMASK: u32 = 7;\npub const PFI_AFLAG_NOALIAS: u32 = 8;\npub const PF_DEBUGNAME: &[u8; 5] = b\"pf: \\0\";\npub const PF_THRESHOLD_MULT: u32 = 1000;\npub const PF_THRESHOLD_MAX: u32 = 4294967;\npub const PF_OSFP_EXPANDED: u32 = 1;\npub const PF_OSFP_GENERIC: u32 = 2;\npub const PF_OSFP_NODETAIL: u32 = 4;\npub const PF_OSFP_LEN: u32 = 32;\npub const _FP_RESERVED_BIT: u32 = 1;\npub const _FP_UNUSED_BITS: u32 = 1;\npub const _FP_CLASS_BITS: u32 = 10;\npub const _FP_VERSION_BITS: u32 = 10;\npub const _FP_SUBTYPE_BITS: u32 = 10;\npub const PF_OSFP_WSIZE_MOD: u32 = 1;\npub const PF_OSFP_WSIZE_DC: u32 = 2;\npub const PF_OSFP_WSIZE_MSS: u32 = 4;\npub const PF_OSFP_WSIZE_MTU: u32 = 8;\npub const PF_OSFP_PSIZE_MOD: u32 = 16;\npub const PF_OSFP_PSIZE_DC: u32 = 32;\npub const PF_OSFP_WSCALE: u32 = 64;\npub const PF_OSFP_WSCALE_MOD: u32 = 128;\npub const PF_OSFP_WSCALE_DC: u32 = 256;\npub const PF_OSFP_MSS: u32 = 512;\npub const PF_OSFP_MSS_MOD: u32 = 1024;\npub const PF_OSFP_MSS_DC: u32 = 2048;\npub const PF_OSFP_DF: u32 = 4096;\npub const PF_OSFP_TS0: u32 = 8192;\npub const PF_OSFP_INET6: u32 = 16384;\npub const PF_OSFP_MAXTTL_OFFSET: u32 = 40;\npub const PF_OSFP_TCPOPT_NOP: u32 = 0;\npub const PF_OSFP_TCPOPT_WSCALE: u32 = 1;\npub const PF_OSFP_TCPOPT_MSS: u32 = 2;\npub const PF_OSFP_TCPOPT_SACK: u32 = 3;\npub const PF_OSFP_TCPOPT_TS: u32 = 4;\npub const PF_OSFP_TCPOPT_BITS: u32 = 3;\npub const PF_ANCHOR_STACK_MAX: u32 = 64;\npub const PF_ANCHOR_NAME_SIZE: u32 = 64;\npub const PF_ANCHOR_MAXPATH: u32 = 959;\npub const PF_ANCHOR_HIWAT: u32 = 512;\npub const PF_OPTIMIZER_TABLE_PFX: &[u8; 13] = b\"__automatic_\\0\";\npub const PF_SKIP_IFP: u32 = 0;\npub const PF_SKIP_DIR: u32 = 1;\npub const PF_SKIP_RDOM: u32 = 2;\npub const PF_SKIP_AF: u32 = 3;\npub const PF_SKIP_PROTO: u32 = 4;\npub const PF_SKIP_SRC_ADDR: u32 = 5;\npub const PF_SKIP_DST_ADDR: u32 = 6;\npub const PF_SKIP_SRC_PORT: u32 = 7;\npub const PF_SKIP_DST_PORT: u32 = 8;\npub const PF_SKIP_COUNT: u32 = 9;\npub const PF_RULE_LABEL_SIZE: u32 = 64;\npub const PF_QNAME_SIZE: u32 = 64;\npub const PF_TAG_NAME_SIZE: u32 = 64;\npub const PF_STATE_NORMAL: u32 = 1;\npub const PF_STATE_MODULATE: u32 = 2;\npub const PF_STATE_SYNPROXY: u32 = 3;\npub const PF_FLUSH: u32 = 1;\npub const PF_FLUSH_GLOBAL: u32 = 2;\npub const PFRULE_DROP: u32 = 0;\npub const PFRULE_RETURNRST: u32 = 1;\npub const PFRULE_FRAGMENT: u32 = 2;\npub const PFRULE_RETURNICMP: u32 = 4;\npub const PFRULE_RETURN: u32 = 8;\npub const PFRULE_NOSYNC: u32 = 16;\npub const PFRULE_SRCTRACK: u32 = 32;\npub const PFRULE_RULESRCTRACK: u32 = 64;\npub const PFRULE_SETDELAY: u32 = 128;\npub const PFRULE_IFBOUND: u32 = 65536;\npub const PFRULE_STATESLOPPY: u32 = 131072;\npub const PFRULE_PFLOW: u32 = 262144;\npub const PFRULE_ONCE: u32 = 1048576;\npub const PFRULE_AFTO: u32 = 2097152;\npub const PFRULE_EXPIRED: u32 = 4194304;\npub const PFSTATE_HIWAT: u32 = 100000;\npub const PFSTATE_ADAPT_START: u32 = 60000;\npub const PFSTATE_ADAPT_END: u32 = 120000;\npub const PF_PKTDELAY_MAXPKTS: u32 = 10000;\npub const PFSNODE_HIWAT: u32 = 10000;\npub const PFSS_TIMESTAMP: u32 = 1;\npub const PFSS_PAWS: u32 = 16;\npub const PFSS_PAWS_IDLED: u32 = 32;\npub const PFSS_DATA_TS: u32 = 64;\npub const PFSS_DATA_NOTS: u32 = 128;\npub const PFSTATE_ALLOWOPTS: u32 = 1;\npub const PFSTATE_SLOPPY: u32 = 2;\npub const PFSTATE_PFLOW: u32 = 4;\npub const PFSTATE_NOSYNC: u32 = 8;\npub const PFSTATE_ACK: u32 = 16;\npub const PFSTATE_NODF: u32 = 32;\npub const PFSTATE_SETTOS: u32 = 64;\npub const PFSTATE_RANDOMID: u32 = 128;\npub const PFSTATE_SCRUB_TCP: u32 = 256;\npub const PFSTATE_SETPRIO: u32 = 512;\npub const PFSTATE_INP_UNLINKED: u32 = 1024;\npub const PFSTATE_SCRUBMASK: u32 = 416;\npub const PFSTATE_SETMASK: u32 = 576;\npub const PFSYNC_SCRUB_FLAG_VALID: u32 = 1;\npub const PFSYNC_FLAG_SRCNODE: u32 = 4;\npub const PFSYNC_FLAG_NATSRCNODE: u32 = 8;\npub const PF_RESERVED_ANCHOR: &[u8; 4] = b\"_pf\\0\";\npub const PFR_TFLAG_PERSIST: u32 = 1;\npub const PFR_TFLAG_CONST: u32 = 2;\npub const PFR_TFLAG_ACTIVE: u32 = 4;\npub const PFR_TFLAG_INACTIVE: u32 = 8;\npub const PFR_TFLAG_REFERENCED: u32 = 16;\npub const PFR_TFLAG_REFDANCHOR: u32 = 32;\npub const PFR_TFLAG_COUNTERS: u32 = 64;\npub const PFR_TFLAG_USRMASK: u32 = 67;\npub const PFR_TFLAG_SETMASK: u32 = 60;\npub const PFR_TFLAG_ALLMASK: u32 = 127;\npub const PFRKE_FLAG_NOT: u32 = 1;\npub const PFRKE_FLAG_MARK: u32 = 2;\npub const PFI_IFLAG_SKIP: u32 = 256;\npub const PFI_IFLAG_ANY: u32 = 512;\npub const PF_DPORT_RANGE: u32 = 1;\npub const PF_RPORT_RANGE: u32 = 2;\npub const PFRES_MATCH: u32 = 0;\npub const PFRES_BADOFF: u32 = 1;\npub const PFRES_FRAG: u32 = 2;\npub const PFRES_SHORT: u32 = 3;\npub const PFRES_NORM: u32 = 4;\npub const PFRES_MEMORY: u32 = 5;\npub const PFRES_TS: u32 = 6;\npub const PFRES_CONGEST: u32 = 7;\npub const PFRES_IPOPTIONS: u32 = 8;\npub const PFRES_PROTCKSUM: u32 = 9;\npub const PFRES_BADSTATE: u32 = 10;\npub const PFRES_STATEINS: u32 = 11;\npub const PFRES_MAXSTATES: u32 = 12;\npub const PFRES_SRCLIMIT: u32 = 13;\npub const PFRES_SYNPROXY: u32 = 14;\npub const PFRES_TRANSLATE: u32 = 15;\npub const PFRES_NOROUTE: u32 = 16;\npub const PFRES_MAX: u32 = 17;\npub const LCNT_STATES: u32 = 0;\npub const LCNT_SRCSTATES: u32 = 1;\npub const LCNT_SRCNODES: u32 = 2;\npub const LCNT_SRCCONN: u32 = 3;\npub const LCNT_SRCCONNRATE: u32 = 4;\npub const LCNT_OVERLOAD_TABLE: u32 = 5;\npub const LCNT_OVERLOAD_FLUSH: u32 = 6;\npub const LCNT_SYNFLOODS: u32 = 7;\npub const LCNT_SYNCOOKIES_SENT: u32 = 8;\npub const LCNT_SYNCOOKIES_VALID: u32 = 9;\npub const LCNT_MAX: u32 = 10;\npub const PFUDPS_NO_TRAFFIC: u32 = 0;\npub const PFUDPS_SINGLE: u32 = 1;\npub const PFUDPS_MULTIPLE: u32 = 2;\npub const PFUDPS_NSTATES: u32 = 3;\npub const PFOTHERS_NO_TRAFFIC: u32 = 0;\npub const PFOTHERS_SINGLE: u32 = 1;\npub const PFOTHERS_MULTIPLE: u32 = 2;\npub const PFOTHERS_NSTATES: u32 = 3;\npub const FCNT_STATE_SEARCH: u32 = 0;\npub const FCNT_STATE_INSERT: u32 = 1;\npub const FCNT_STATE_REMOVALS: u32 = 2;\npub const FCNT_MAX: u32 = 3;\npub const SCNT_SRC_NODE_SEARCH: u32 = 0;\npub const SCNT_SRC_NODE_INSERT: u32 = 1;\npub const SCNT_SRC_NODE_REMOVALS: u32 = 2;\npub const SCNT_MAX: u32 = 3;\npub const PF_REASS_ENABLED: u32 = 1;\npub const PF_REASS_NODF: u32 = 2;\npub const PF_SYNCOOKIES_NEVER: u32 = 0;\npub const PF_SYNCOOKIES_ALWAYS: u32 = 1;\npub const PF_SYNCOOKIES_ADAPTIVE: u32 = 2;\npub const PF_SYNCOOKIES_MODE_MAX: u32 = 2;\npub const PF_SYNCOOKIES_HIWATPCT: u32 = 25;\npub const PF_SYNCOOKIES_LOWATPCT: u32 = 12;\npub const PF_PRIO_ZERO: u32 = 255;\npub const PFQS_FLOWQUEUE: u32 = 1;\npub const PFQS_ROOTCLASS: u32 = 2;\npub const PFQS_DEFAULT: u32 = 4096;\npub const PFR_KTABLE_HIWAT: u32 = 1000;\npub const PFR_KENTRY_HIWAT: u32 = 200000;\npub const PFR_KENTRY_HIWAT_SMALL: u32 = 100000;\npub const PFR_FLAG_DUMMY: u32 = 2;\npub const PFR_FLAG_FEEDBACK: u32 = 4;\npub const PFR_FLAG_CLSTATS: u32 = 8;\npub const PFR_FLAG_ADDRSTOO: u32 = 16;\npub const PFR_FLAG_REPLACE: u32 = 32;\npub const PFR_FLAG_ALLRSETS: u32 = 64;\npub const PFR_FLAG_ALLMASK: u32 = 127;\npub type __int8_t = ::std::os::raw::c_schar;\npub type __uint8_t = ::std::os::raw::c_uchar;\npub type __int16_t = ::std::os::raw::c_short;\npub type __uint16_t = ::std::os::raw::c_ushort;\npub type __int32_t = ::std::os::raw::c_int;\npub type __uint32_t = ::std::os::raw::c_uint;\npub type __int64_t = ::std::os::raw::c_longlong;\npub type __uint64_t = ::std::os::raw::c_ulonglong;\npub type __int_least8_t = __int8_t;\npub type __uint_least8_t = __uint8_t;\npub type __int_least16_t = __int16_t;\npub type __uint_least16_t = __uint16_t;\npub type __int_least32_t = __int32_t;\npub type __uint_least32_t = __uint32_t;\npub type __int_least64_t = __int64_t;\npub type __uint_least64_t = __uint64_t;\npub type __int_fast8_t = __int32_t;\npub type __uint_fast8_t = __uint32_t;\npub type __int_fast16_t = __int32_t;\npub type __uint_fast16_t = __uint32_t;\npub type __int_fast32_t = __int32_t;\npub type __uint_fast32_t = __uint32_t;\npub type __int_fast64_t = __int64_t;\npub type __uint_fast64_t = __uint64_t;\npub type __intptr_t = ::std::os::raw::c_long;\npub type __uintptr_t = ::std::os::raw::c_ulong;\npub type __intmax_t = __int64_t;\npub type __uintmax_t = __uint64_t;\npub type __register_t = ::std::os::raw::c_long;\npub type __vaddr_t = ::std::os::raw::c_ulong;\npub type __paddr_t = ::std::os::raw::c_ulong;\npub type __vsize_t = ::std::os::raw::c_ulong;\npub type __psize_t = ::std::os::raw::c_ulong;\npub type __double_t = f64;\npub type __float_t = f32;\npub type __ptrdiff_t = ::std::os::raw::c_long;\npub type __size_t = ::std::os::raw::c_ulong;\npub type __ssize_t = ::std::os::raw::c_long;\npub type __va_list = __builtin_va_list;\npub type __wchar_t = ::std::os::raw::c_int;\npub type __wint_t = ::std::os::raw::c_int;\npub type __rune_t = ::std::os::raw::c_int;\npub type __wctrans_t = *mut ::std::os::raw::c_void;\npub type __wctype_t = *mut ::std::os::raw::c_void;\npub type int_least8_t = __int_least8_t;\npub type uint_least8_t = __uint_least8_t;\npub type int_least16_t = __int_least16_t;\npub type uint_least16_t = __uint_least16_t;\npub type int_least32_t = __int_least32_t;\npub type uint_least32_t = __uint_least32_t;\npub type int_least64_t = __int_least64_t;\npub type uint_least64_t = __uint_least64_t;\npub type int_fast8_t = __int_fast8_t;\npub type uint_fast8_t = __uint_fast8_t;\npub type int_fast16_t = __int_fast16_t;\npub type uint_fast16_t = __uint_fast16_t;\npub type int_fast32_t = __int_fast32_t;\npub type uint_fast32_t = __uint_fast32_t;\npub type int_fast64_t = __int_fast64_t;\npub type uint_fast64_t = __uint_fast64_t;\npub type intmax_t = __intmax_t;\npub type uintmax_t = __uintmax_t;\npub type __blkcnt_t = __int64_t;\npub type __blksize_t = __int32_t;\npub type __clock_t = __int64_t;\npub type __clockid_t = __int32_t;\npub type __cpuid_t = ::std::os::raw::c_ulong;\npub type __dev_t = __int32_t;\npub type __fixpt_t = __uint32_t;\npub type __fsblkcnt_t = __uint64_t;\npub type __fsfilcnt_t = __uint64_t;\npub type __gid_t = __uint32_t;\npub type __id_t = __uint32_t;\npub type __in_addr_t = __uint32_t;\npub type __in_port_t = __uint16_t;\npub type __ino_t = __uint64_t;\npub type __key_t = ::std::os::raw::c_long;\npub type __mode_t = __uint32_t;\npub type __nlink_t = __uint32_t;\npub type __off_t = __int64_t;\npub type __pid_t = __int32_t;\npub type __rlim_t = __uint64_t;\npub type __sa_family_t = __uint8_t;\npub type __segsz_t = __int32_t;\npub type __socklen_t = __uint32_t;\npub type __suseconds_t = ::std::os::raw::c_long;\npub type __time_t = __int64_t;\npub type __timer_t = __int32_t;\npub type __uid_t = __uint32_t;\npub type __useconds_t = __uint32_t;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union __mbstate_t {\n    pub __mbstate8: [::std::os::raw::c_char; 128usize],\n    pub __mbstateL: __int64_t,\n}\n#[test]\nfn bindgen_test_layout___mbstate_t() {\n    const UNINIT: ::std::mem::MaybeUninit<__mbstate_t> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__mbstate_t>(),\n        128usize,\n        concat!(\"Size of: \", stringify!(__mbstate_t))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__mbstate_t>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__mbstate_t))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__mbstate8) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__mbstate_t),\n            \"::\",\n            stringify!(__mbstate8)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__mbstateL) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__mbstate_t),\n            \"::\",\n            stringify!(__mbstateL)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct iovec {\n    pub iov_base: *mut ::std::os::raw::c_void,\n    pub iov_len: usize,\n}\n#[test]\nfn bindgen_test_layout_iovec() {\n    const UNINIT: ::std::mem::MaybeUninit<iovec> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<iovec>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(iovec))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<iovec>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(iovec))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).iov_base) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(iovec), \"::\", stringify!(iov_base))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).iov_len) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(iovec), \"::\", stringify!(iov_len))\n    );\n}\npub const uio_rw_UIO_READ: uio_rw = 0;\npub const uio_rw_UIO_WRITE: uio_rw = 1;\npub type uio_rw = ::std::os::raw::c_uint;\npub const uio_seg_UIO_USERSPACE: uio_seg = 0;\npub const uio_seg_UIO_SYSSPACE: uio_seg = 1;\npub type uio_seg = ::std::os::raw::c_uint;\nunsafe extern \"C\" {\n    pub fn preadv(arg1: ::std::os::raw::c_int, arg2: *const iovec, arg3: ::std::os::raw::c_int, arg4: __off_t)\n    -> isize;\n}\nunsafe extern \"C\" {\n    pub fn pwritev(\n        arg1: ::std::os::raw::c_int,\n        arg2: *const iovec,\n        arg3: ::std::os::raw::c_int,\n        arg4: __off_t,\n    ) -> isize;\n}\nunsafe extern \"C\" {\n    pub fn readv(arg1: ::std::os::raw::c_int, arg2: *const iovec, arg3: ::std::os::raw::c_int) -> isize;\n}\nunsafe extern \"C\" {\n    pub fn writev(arg1: ::std::os::raw::c_int, arg2: *const iovec, arg3: ::std::os::raw::c_int) -> isize;\n}\npub type u_char = ::std::os::raw::c_uchar;\npub type u_short = ::std::os::raw::c_ushort;\npub type u_int = ::std::os::raw::c_uint;\npub type u_long = ::std::os::raw::c_ulong;\npub type unchar = ::std::os::raw::c_uchar;\npub type ushort = ::std::os::raw::c_ushort;\npub type uint = ::std::os::raw::c_uint;\npub type ulong = ::std::os::raw::c_ulong;\npub type cpuid_t = __cpuid_t;\npub type register_t = __register_t;\npub type u_int8_t = __uint8_t;\npub type u_int16_t = __uint16_t;\npub type u_int32_t = __uint32_t;\npub type u_int64_t = __uint64_t;\npub type quad_t = __int64_t;\npub type u_quad_t = __uint64_t;\npub type vaddr_t = __vaddr_t;\npub type paddr_t = __paddr_t;\npub type vsize_t = __vsize_t;\npub type psize_t = __psize_t;\npub type blkcnt_t = __blkcnt_t;\npub type blksize_t = __blksize_t;\npub type caddr_t = *mut ::std::os::raw::c_char;\npub type daddr32_t = __int32_t;\npub type daddr_t = __int64_t;\npub type dev_t = __dev_t;\npub type fixpt_t = __fixpt_t;\npub type gid_t = __gid_t;\npub type id_t = __id_t;\npub type ino_t = __ino_t;\npub type key_t = __key_t;\npub type mode_t = __mode_t;\npub type nlink_t = __nlink_t;\npub type rlim_t = __rlim_t;\npub type segsz_t = __segsz_t;\npub type uid_t = __uid_t;\npub type useconds_t = __useconds_t;\npub type suseconds_t = __suseconds_t;\npub type fsblkcnt_t = __fsblkcnt_t;\npub type fsfilcnt_t = __fsfilcnt_t;\npub type clock_t = __clock_t;\npub type clockid_t = __clockid_t;\npub type pid_t = __pid_t;\npub type time_t = __time_t;\npub type timer_t = __timer_t;\npub type off_t = __off_t;\nunsafe extern \"C\" {\n    pub fn lseek(arg1: ::std::os::raw::c_int, arg2: off_t, arg3: ::std::os::raw::c_int) -> off_t;\n}\nunsafe extern \"C\" {\n    pub fn ftruncate(arg1: ::std::os::raw::c_int, arg2: off_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn truncate(arg1: *const ::std::os::raw::c_char, arg2: off_t) -> ::std::os::raw::c_int;\n}\npub type socklen_t = __socklen_t;\npub type sa_family_t = __sa_family_t;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct linger {\n    pub l_onoff: ::std::os::raw::c_int,\n    pub l_linger: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_linger() {\n    const UNINIT: ::std::mem::MaybeUninit<linger> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<linger>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(linger))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<linger>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(linger))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).l_onoff) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(linger), \"::\", stringify!(l_onoff))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).l_linger) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(linger), \"::\", stringify!(l_linger))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct timeval {\n    pub tv_sec: time_t,\n    pub tv_usec: suseconds_t,\n}\n#[test]\nfn bindgen_test_layout_timeval() {\n    const UNINIT: ::std::mem::MaybeUninit<timeval> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<timeval>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(timeval))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<timeval>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(timeval))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tv_sec) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(timeval), \"::\", stringify!(tv_sec))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tv_usec) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(timeval), \"::\", stringify!(tv_usec))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct splice {\n    pub sp_fd: ::std::os::raw::c_int,\n    pub sp_max: off_t,\n    pub sp_idle: timeval,\n}\n#[test]\nfn bindgen_test_layout_splice() {\n    const UNINIT: ::std::mem::MaybeUninit<splice> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<splice>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(splice))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<splice>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(splice))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sp_fd) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(splice), \"::\", stringify!(sp_fd))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sp_max) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(splice), \"::\", stringify!(sp_max))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sp_idle) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(splice), \"::\", stringify!(sp_idle))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sockaddr {\n    pub sa_len: __uint8_t,\n    pub sa_family: sa_family_t,\n    pub sa_data: [::std::os::raw::c_char; 14usize],\n}\n#[test]\nfn bindgen_test_layout_sockaddr() {\n    const UNINIT: ::std::mem::MaybeUninit<sockaddr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sockaddr>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(sockaddr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sockaddr>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(sockaddr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sa_len) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr), \"::\", stringify!(sa_len))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sa_family) as usize - ptr as usize },\n        1usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr), \"::\", stringify!(sa_family))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sa_data) as usize - ptr as usize },\n        2usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr), \"::\", stringify!(sa_data))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sockaddr_storage {\n    pub ss_len: __uint8_t,\n    pub ss_family: sa_family_t,\n    pub __ss_pad1: [::std::os::raw::c_uchar; 6usize],\n    pub __ss_pad2: __uint64_t,\n    pub __ss_pad3: [::std::os::raw::c_uchar; 240usize],\n}\n#[test]\nfn bindgen_test_layout_sockaddr_storage() {\n    const UNINIT: ::std::mem::MaybeUninit<sockaddr_storage> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sockaddr_storage>(),\n        256usize,\n        concat!(\"Size of: \", stringify!(sockaddr_storage))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sockaddr_storage>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(sockaddr_storage))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ss_len) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_storage),\n            \"::\",\n            stringify!(ss_len)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ss_family) as usize - ptr as usize },\n        1usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_storage),\n            \"::\",\n            stringify!(ss_family)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ss_pad1) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_storage),\n            \"::\",\n            stringify!(__ss_pad1)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ss_pad2) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_storage),\n            \"::\",\n            stringify!(__ss_pad2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__ss_pad3) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_storage),\n            \"::\",\n            stringify!(__ss_pad3)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sockpeercred {\n    pub uid: uid_t,\n    pub gid: gid_t,\n    pub pid: pid_t,\n}\n#[test]\nfn bindgen_test_layout_sockpeercred() {\n    const UNINIT: ::std::mem::MaybeUninit<sockpeercred> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sockpeercred>(),\n        12usize,\n        concat!(\"Size of: \", stringify!(sockpeercred))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sockpeercred>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(sockpeercred))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uid) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sockpeercred), \"::\", stringify!(uid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).gid) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(sockpeercred), \"::\", stringify!(gid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pid) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(sockpeercred), \"::\", stringify!(pid))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct msghdr {\n    pub msg_name: *mut ::std::os::raw::c_void,\n    pub msg_namelen: socklen_t,\n    pub msg_iov: *mut iovec,\n    pub msg_iovlen: ::std::os::raw::c_uint,\n    pub msg_control: *mut ::std::os::raw::c_void,\n    pub msg_controllen: socklen_t,\n    pub msg_flags: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_msghdr() {\n    const UNINIT: ::std::mem::MaybeUninit<msghdr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<msghdr>(),\n        48usize,\n        concat!(\"Size of: \", stringify!(msghdr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<msghdr>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(msghdr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_name) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(msghdr), \"::\", stringify!(msg_name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_namelen) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(msghdr), \"::\", stringify!(msg_namelen))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_iov) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(msghdr), \"::\", stringify!(msg_iov))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_iovlen) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(msghdr), \"::\", stringify!(msg_iovlen))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_control) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(msghdr), \"::\", stringify!(msg_control))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_controllen) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(msghdr),\n            \"::\",\n            stringify!(msg_controllen)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_flags) as usize - ptr as usize },\n        44usize,\n        concat!(\"Offset of field: \", stringify!(msghdr), \"::\", stringify!(msg_flags))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct mmsghdr {\n    pub msg_hdr: msghdr,\n    pub msg_len: ::std::os::raw::c_uint,\n}\n#[test]\nfn bindgen_test_layout_mmsghdr() {\n    const UNINIT: ::std::mem::MaybeUninit<mmsghdr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<mmsghdr>(),\n        56usize,\n        concat!(\"Size of: \", stringify!(mmsghdr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<mmsghdr>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(mmsghdr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_hdr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(mmsghdr), \"::\", stringify!(msg_hdr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).msg_len) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(mmsghdr), \"::\", stringify!(msg_len))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct cmsghdr {\n    pub cmsg_len: socklen_t,\n    pub cmsg_level: ::std::os::raw::c_int,\n    pub cmsg_type: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_cmsghdr() {\n    const UNINIT: ::std::mem::MaybeUninit<cmsghdr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<cmsghdr>(),\n        12usize,\n        concat!(\"Size of: \", stringify!(cmsghdr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<cmsghdr>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(cmsghdr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cmsg_len) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(cmsghdr), \"::\", stringify!(cmsg_len))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cmsg_level) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(cmsghdr), \"::\", stringify!(cmsg_level))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cmsg_type) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(cmsghdr), \"::\", stringify!(cmsg_type))\n    );\n}\nunsafe extern \"C\" {\n    pub fn accept(arg1: ::std::os::raw::c_int, arg2: *mut sockaddr, arg3: *mut socklen_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn bind(arg1: ::std::os::raw::c_int, arg2: *const sockaddr, arg3: socklen_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn connect(arg1: ::std::os::raw::c_int, arg2: *const sockaddr, arg3: socklen_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn getpeername(arg1: ::std::os::raw::c_int, arg2: *mut sockaddr, arg3: *mut socklen_t)\n    -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn getsockname(arg1: ::std::os::raw::c_int, arg2: *mut sockaddr, arg3: *mut socklen_t)\n    -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn getsockopt(\n        arg1: ::std::os::raw::c_int,\n        arg2: ::std::os::raw::c_int,\n        arg3: ::std::os::raw::c_int,\n        arg4: *mut ::std::os::raw::c_void,\n        arg5: *mut socklen_t,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn listen(arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn recv(\n        arg1: ::std::os::raw::c_int,\n        arg2: *mut ::std::os::raw::c_void,\n        arg3: usize,\n        arg4: ::std::os::raw::c_int,\n    ) -> isize;\n}\nunsafe extern \"C\" {\n    pub fn recvfrom(\n        arg1: ::std::os::raw::c_int,\n        arg2: *mut ::std::os::raw::c_void,\n        arg3: usize,\n        arg4: ::std::os::raw::c_int,\n        arg5: *mut sockaddr,\n        arg6: *mut socklen_t,\n    ) -> isize;\n}\nunsafe extern \"C\" {\n    pub fn recvmsg(arg1: ::std::os::raw::c_int, arg2: *mut msghdr, arg3: ::std::os::raw::c_int) -> isize;\n}\nunsafe extern \"C\" {\n    pub fn recvmmsg(\n        arg1: ::std::os::raw::c_int,\n        arg2: *mut mmsghdr,\n        arg3: ::std::os::raw::c_uint,\n        arg4: ::std::os::raw::c_int,\n        arg5: *mut timespec,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn send(\n        arg1: ::std::os::raw::c_int,\n        arg2: *const ::std::os::raw::c_void,\n        arg3: usize,\n        arg4: ::std::os::raw::c_int,\n    ) -> isize;\n}\nunsafe extern \"C\" {\n    pub fn sendto(\n        arg1: ::std::os::raw::c_int,\n        arg2: *const ::std::os::raw::c_void,\n        arg3: usize,\n        arg4: ::std::os::raw::c_int,\n        arg5: *const sockaddr,\n        arg6: socklen_t,\n    ) -> isize;\n}\nunsafe extern \"C\" {\n    pub fn sendmsg(arg1: ::std::os::raw::c_int, arg2: *const msghdr, arg3: ::std::os::raw::c_int) -> isize;\n}\nunsafe extern \"C\" {\n    pub fn sendmmsg(\n        arg1: ::std::os::raw::c_int,\n        arg2: *mut mmsghdr,\n        arg3: ::std::os::raw::c_uint,\n        arg4: ::std::os::raw::c_int,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn setsockopt(\n        arg1: ::std::os::raw::c_int,\n        arg2: ::std::os::raw::c_int,\n        arg3: ::std::os::raw::c_int,\n        arg4: *const ::std::os::raw::c_void,\n        arg5: socklen_t,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn shutdown(arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn sockatmark(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn socket(\n        arg1: ::std::os::raw::c_int,\n        arg2: ::std::os::raw::c_int,\n        arg3: ::std::os::raw::c_int,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn socketpair(\n        arg1: ::std::os::raw::c_int,\n        arg2: ::std::os::raw::c_int,\n        arg3: ::std::os::raw::c_int,\n        arg4: *mut ::std::os::raw::c_int,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn accept4(\n        arg1: ::std::os::raw::c_int,\n        arg2: *mut sockaddr,\n        arg3: *mut socklen_t,\n        arg4: ::std::os::raw::c_int,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn getpeereid(arg1: ::std::os::raw::c_int, arg2: *mut uid_t, arg3: *mut gid_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn getrtable() -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn setrtable(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct if_nameindex {\n    pub if_index: ::std::os::raw::c_uint,\n    pub if_name: *mut ::std::os::raw::c_char,\n}\n#[test]\nfn bindgen_test_layout_if_nameindex() {\n    const UNINIT: ::std::mem::MaybeUninit<if_nameindex> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_nameindex>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(if_nameindex))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_nameindex>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(if_nameindex))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).if_index) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_nameindex),\n            \"::\",\n            stringify!(if_index)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).if_name) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(if_nameindex), \"::\", stringify!(if_name))\n    );\n}\nunsafe extern \"C\" {\n    pub fn if_nametoindex(arg1: *const ::std::os::raw::c_char) -> ::std::os::raw::c_uint;\n}\nunsafe extern \"C\" {\n    pub fn if_indextoname(\n        arg1: ::std::os::raw::c_uint,\n        arg2: *mut ::std::os::raw::c_char,\n    ) -> *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn if_nameindex() -> *mut if_nameindex;\n}\nunsafe extern \"C\" {\n    pub fn if_freenameindex(arg1: *mut if_nameindex);\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct timespec {\n    pub tv_sec: time_t,\n    pub tv_nsec: ::std::os::raw::c_long,\n}\n#[test]\nfn bindgen_test_layout_timespec() {\n    const UNINIT: ::std::mem::MaybeUninit<timespec> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<timespec>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(timespec))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<timespec>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(timespec))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tv_sec) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(timespec), \"::\", stringify!(tv_sec))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tv_nsec) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(timespec), \"::\", stringify!(tv_nsec))\n    );\n}\npub type __fd_mask = u32;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct fd_set {\n    pub fds_bits: [__fd_mask; 32usize],\n}\n#[test]\nfn bindgen_test_layout_fd_set() {\n    const UNINIT: ::std::mem::MaybeUninit<fd_set> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<fd_set>(),\n        128usize,\n        concat!(\"Size of: \", stringify!(fd_set))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<fd_set>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(fd_set))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fds_bits) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(fd_set), \"::\", stringify!(fds_bits))\n    );\n}\npub type sigset_t = ::std::os::raw::c_uint;\nunsafe extern \"C\" {\n    pub fn select(\n        arg1: ::std::os::raw::c_int,\n        arg2: *mut fd_set,\n        arg3: *mut fd_set,\n        arg4: *mut fd_set,\n        arg5: *mut timeval,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn pselect(\n        arg1: ::std::os::raw::c_int,\n        arg2: *mut fd_set,\n        arg3: *mut fd_set,\n        arg4: *mut fd_set,\n        arg5: *const timespec,\n        arg6: *const sigset_t,\n    ) -> ::std::os::raw::c_int;\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct timezone {\n    pub tz_minuteswest: ::std::os::raw::c_int,\n    pub tz_dsttime: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_timezone() {\n    const UNINIT: ::std::mem::MaybeUninit<timezone> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<timezone>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(timezone))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<timezone>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(timezone))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tz_minuteswest) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(timezone),\n            \"::\",\n            stringify!(tz_minuteswest)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tz_dsttime) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(timezone), \"::\", stringify!(tz_dsttime))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct itimerval {\n    pub it_interval: timeval,\n    pub it_value: timeval,\n}\n#[test]\nfn bindgen_test_layout_itimerval() {\n    const UNINIT: ::std::mem::MaybeUninit<itimerval> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<itimerval>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(itimerval))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<itimerval>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(itimerval))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).it_interval) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(itimerval),\n            \"::\",\n            stringify!(it_interval)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).it_value) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(itimerval), \"::\", stringify!(it_value))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct clockinfo {\n    pub hz: ::std::os::raw::c_int,\n    pub tick: ::std::os::raw::c_int,\n    pub stathz: ::std::os::raw::c_int,\n    pub profhz: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_clockinfo() {\n    const UNINIT: ::std::mem::MaybeUninit<clockinfo> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<clockinfo>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(clockinfo))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<clockinfo>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(clockinfo))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).hz) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(clockinfo), \"::\", stringify!(hz))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tick) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(clockinfo), \"::\", stringify!(tick))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).stathz) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(clockinfo), \"::\", stringify!(stathz))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).profhz) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(clockinfo), \"::\", stringify!(profhz))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct itimerspec {\n    pub it_interval: timespec,\n    pub it_value: timespec,\n}\n#[test]\nfn bindgen_test_layout_itimerspec() {\n    const UNINIT: ::std::mem::MaybeUninit<itimerspec> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<itimerspec>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(itimerspec))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<itimerspec>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(itimerspec))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).it_interval) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(itimerspec),\n            \"::\",\n            stringify!(it_interval)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).it_value) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(itimerspec), \"::\", stringify!(it_value))\n    );\n}\npub type locale_t = *mut ::std::os::raw::c_void;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct tm {\n    pub tm_sec: ::std::os::raw::c_int,\n    pub tm_min: ::std::os::raw::c_int,\n    pub tm_hour: ::std::os::raw::c_int,\n    pub tm_mday: ::std::os::raw::c_int,\n    pub tm_mon: ::std::os::raw::c_int,\n    pub tm_year: ::std::os::raw::c_int,\n    pub tm_wday: ::std::os::raw::c_int,\n    pub tm_yday: ::std::os::raw::c_int,\n    pub tm_isdst: ::std::os::raw::c_int,\n    pub tm_gmtoff: ::std::os::raw::c_long,\n    pub tm_zone: *mut ::std::os::raw::c_char,\n}\n#[test]\nfn bindgen_test_layout_tm() {\n    const UNINIT: ::std::mem::MaybeUninit<tm> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<tm>(),\n        56usize,\n        concat!(\"Size of: \", stringify!(tm))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<tm>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(tm))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_sec) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_sec))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_min) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_min))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_hour) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_hour))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_mday) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_mday))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_mon) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_mon))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_year) as usize - ptr as usize },\n        20usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_year))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_wday) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_wday))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_yday) as usize - ptr as usize },\n        28usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_yday))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_isdst) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_isdst))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_gmtoff) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_gmtoff))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tm_zone) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(tm), \"::\", stringify!(tm_zone))\n    );\n}\nunsafe extern \"C\" {\n    pub fn asctime(arg1: *const tm) -> *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn clock() -> clock_t;\n}\nunsafe extern \"C\" {\n    pub fn ctime(arg1: *const time_t) -> *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn difftime(arg1: time_t, arg2: time_t) -> f64;\n}\nunsafe extern \"C\" {\n    pub fn gmtime(arg1: *const time_t) -> *mut tm;\n}\nunsafe extern \"C\" {\n    pub fn localtime(arg1: *const time_t) -> *mut tm;\n}\nunsafe extern \"C\" {\n    pub fn mktime(arg1: *mut tm) -> time_t;\n}\nunsafe extern \"C\" {\n    pub fn strftime(\n        arg1: *mut ::std::os::raw::c_char,\n        arg2: usize,\n        arg3: *const ::std::os::raw::c_char,\n        arg4: *const tm,\n    ) -> usize;\n}\nunsafe extern \"C\" {\n    pub fn time(arg1: *mut time_t) -> time_t;\n}\nunsafe extern \"C\" {\n    pub static mut daylight: ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub static mut timezone: ::std::os::raw::c_long;\n}\nunsafe extern \"C\" {\n    pub fn strptime(\n        arg1: *const ::std::os::raw::c_char,\n        arg2: *const ::std::os::raw::c_char,\n        arg3: *mut tm,\n    ) -> *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn asctime_r(arg1: *const tm, arg2: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn ctime_r(arg1: *const time_t, arg2: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char;\n}\nunsafe extern \"C\" {\n    pub fn gmtime_r(arg1: *const time_t, arg2: *mut tm) -> *mut tm;\n}\nunsafe extern \"C\" {\n    pub fn localtime_r(arg1: *const time_t, arg2: *mut tm) -> *mut tm;\n}\nunsafe extern \"C\" {\n    pub static mut tzname: [*mut ::std::os::raw::c_char; 2usize];\n}\nunsafe extern \"C\" {\n    pub fn tzset();\n}\nunsafe extern \"C\" {\n    pub fn clock_getres(arg1: clockid_t, arg2: *mut timespec) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn clock_gettime(arg1: clockid_t, arg2: *mut timespec) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn clock_settime(arg1: clockid_t, arg2: *const timespec) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn nanosleep(arg1: *const timespec, arg2: *mut timespec) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn clock_getcpuclockid(arg1: pid_t, arg2: *mut clockid_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn strftime_l(\n        arg1: *mut ::std::os::raw::c_char,\n        arg2: usize,\n        arg3: *const ::std::os::raw::c_char,\n        arg4: *const tm,\n        arg5: locale_t,\n    ) -> usize;\n}\nunsafe extern \"C\" {\n    pub fn timespec_get(_ts: *mut timespec, _base: ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn tzsetwall();\n}\nunsafe extern \"C\" {\n    pub fn timelocal(arg1: *mut tm) -> time_t;\n}\nunsafe extern \"C\" {\n    pub fn timegm(arg1: *mut tm) -> time_t;\n}\nunsafe extern \"C\" {\n    pub fn timeoff(arg1: *mut tm, arg2: ::std::os::raw::c_long) -> time_t;\n}\nunsafe extern \"C\" {\n    pub fn adjtime(arg1: *const timeval, arg2: *mut timeval) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn adjfreq(arg1: *const i64, arg2: *mut i64) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn futimes(arg1: ::std::os::raw::c_int, arg2: *const timeval) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn getitimer(arg1: ::std::os::raw::c_int, arg2: *mut itimerval) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn gettimeofday(arg1: *mut timeval, arg2: *mut timezone) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn setitimer(\n        arg1: ::std::os::raw::c_int,\n        arg2: *const itimerval,\n        arg3: *mut itimerval,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn settimeofday(arg1: *const timeval, arg2: *const timezone) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn utimes(arg1: *const ::std::os::raw::c_char, arg2: *const timeval) -> ::std::os::raw::c_int;\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct if_clonereq {\n    pub ifcr_total: ::std::os::raw::c_int,\n    pub ifcr_count: ::std::os::raw::c_int,\n    pub ifcr_buffer: *mut ::std::os::raw::c_char,\n}\n#[test]\nfn bindgen_test_layout_if_clonereq() {\n    const UNINIT: ::std::mem::MaybeUninit<if_clonereq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_clonereq>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(if_clonereq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_clonereq>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(if_clonereq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifcr_total) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_clonereq),\n            \"::\",\n            stringify!(ifcr_total)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifcr_count) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_clonereq),\n            \"::\",\n            stringify!(ifcr_count)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifcr_buffer) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_clonereq),\n            \"::\",\n            stringify!(ifcr_buffer)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct if_rxring {\n    pub rxr_adjusted: ::std::os::raw::c_int,\n    pub rxr_alive: u_int,\n    pub rxr_cwm: u_int,\n    pub rxr_lwm: u_int,\n    pub rxr_hwm: u_int,\n}\n#[test]\nfn bindgen_test_layout_if_rxring() {\n    const UNINIT: ::std::mem::MaybeUninit<if_rxring> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_rxring>(),\n        20usize,\n        concat!(\"Size of: \", stringify!(if_rxring))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_rxring>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(if_rxring))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rxr_adjusted) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_rxring),\n            \"::\",\n            stringify!(rxr_adjusted)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rxr_alive) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(if_rxring), \"::\", stringify!(rxr_alive))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rxr_cwm) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(if_rxring), \"::\", stringify!(rxr_cwm))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rxr_lwm) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(if_rxring), \"::\", stringify!(rxr_lwm))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rxr_hwm) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(if_rxring), \"::\", stringify!(rxr_hwm))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct if_rxring_info {\n    pub ifr_name: [::std::os::raw::c_char; 16usize],\n    pub ifr_size: u_int,\n    pub ifr_info: if_rxring,\n}\n#[test]\nfn bindgen_test_layout_if_rxring_info() {\n    const UNINIT: ::std::mem::MaybeUninit<if_rxring_info> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_rxring_info>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(if_rxring_info))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_rxring_info>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(if_rxring_info))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifr_name) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_rxring_info),\n            \"::\",\n            stringify!(ifr_name)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifr_size) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_rxring_info),\n            \"::\",\n            stringify!(ifr_size)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifr_info) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_rxring_info),\n            \"::\",\n            stringify!(ifr_info)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct if_rxrinfo {\n    pub ifri_total: u_int,\n    pub ifri_entries: *mut if_rxring_info,\n}\n#[test]\nfn bindgen_test_layout_if_rxrinfo() {\n    const UNINIT: ::std::mem::MaybeUninit<if_rxrinfo> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_rxrinfo>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(if_rxrinfo))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_rxrinfo>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(if_rxrinfo))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifri_total) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_rxrinfo),\n            \"::\",\n            stringify!(ifri_total)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifri_entries) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_rxrinfo),\n            \"::\",\n            stringify!(ifri_entries)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct if_data {\n    pub ifi_type: u_char,\n    pub ifi_addrlen: u_char,\n    pub ifi_hdrlen: u_char,\n    pub ifi_link_state: u_char,\n    pub ifi_mtu: u_int32_t,\n    pub ifi_metric: u_int32_t,\n    pub ifi_rdomain: u_int32_t,\n    pub ifi_baudrate: u_int64_t,\n    pub ifi_ipackets: u_int64_t,\n    pub ifi_ierrors: u_int64_t,\n    pub ifi_opackets: u_int64_t,\n    pub ifi_oerrors: u_int64_t,\n    pub ifi_collisions: u_int64_t,\n    pub ifi_ibytes: u_int64_t,\n    pub ifi_obytes: u_int64_t,\n    pub ifi_imcasts: u_int64_t,\n    pub ifi_omcasts: u_int64_t,\n    pub ifi_iqdrops: u_int64_t,\n    pub ifi_oqdrops: u_int64_t,\n    pub ifi_noproto: u_int64_t,\n    pub ifi_capabilities: u_int32_t,\n    pub ifi_lastchange: timeval,\n}\n#[test]\nfn bindgen_test_layout_if_data() {\n    const UNINIT: ::std::mem::MaybeUninit<if_data> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_data>(),\n        144usize,\n        concat!(\"Size of: \", stringify!(if_data))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_data>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(if_data))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_type) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_type))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_addrlen) as usize - ptr as usize },\n        1usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_addrlen))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_hdrlen) as usize - ptr as usize },\n        2usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_hdrlen))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_link_state) as usize - ptr as usize },\n        3usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data),\n            \"::\",\n            stringify!(ifi_link_state)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_mtu) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_mtu))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_metric) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_metric))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_rdomain) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_rdomain))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_baudrate) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_baudrate))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_ipackets) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_ipackets))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_ierrors) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_ierrors))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_opackets) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_opackets))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_oerrors) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_oerrors))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_collisions) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data),\n            \"::\",\n            stringify!(ifi_collisions)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_ibytes) as usize - ptr as usize },\n        64usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_ibytes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_obytes) as usize - ptr as usize },\n        72usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_obytes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_imcasts) as usize - ptr as usize },\n        80usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_imcasts))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_omcasts) as usize - ptr as usize },\n        88usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_omcasts))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_iqdrops) as usize - ptr as usize },\n        96usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_iqdrops))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_oqdrops) as usize - ptr as usize },\n        104usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_oqdrops))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_noproto) as usize - ptr as usize },\n        112usize,\n        concat!(\"Offset of field: \", stringify!(if_data), \"::\", stringify!(ifi_noproto))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_capabilities) as usize - ptr as usize },\n        120usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data),\n            \"::\",\n            stringify!(ifi_capabilities)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifi_lastchange) as usize - ptr as usize },\n        128usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_data),\n            \"::\",\n            stringify!(ifi_lastchange)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct if_status_description {\n    pub ifs_type: u_char,\n    pub ifs_state: u_char,\n    pub ifs_string: *const ::std::os::raw::c_char,\n}\n#[test]\nfn bindgen_test_layout_if_status_description() {\n    const UNINIT: ::std::mem::MaybeUninit<if_status_description> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_status_description>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(if_status_description))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_status_description>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(if_status_description))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifs_type) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_status_description),\n            \"::\",\n            stringify!(ifs_type)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifs_state) as usize - ptr as usize },\n        1usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_status_description),\n            \"::\",\n            stringify!(ifs_state)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifs_string) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_status_description),\n            \"::\",\n            stringify!(ifs_string)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct if_msghdr {\n    pub ifm_msglen: u_short,\n    pub ifm_version: u_char,\n    pub ifm_type: u_char,\n    pub ifm_hdrlen: u_short,\n    pub ifm_index: u_short,\n    pub ifm_tableid: u_short,\n    pub ifm_pad1: u_char,\n    pub ifm_pad2: u_char,\n    pub ifm_addrs: ::std::os::raw::c_int,\n    pub ifm_flags: ::std::os::raw::c_int,\n    pub ifm_xflags: ::std::os::raw::c_int,\n    pub ifm_data: if_data,\n}\n#[test]\nfn bindgen_test_layout_if_msghdr() {\n    const UNINIT: ::std::mem::MaybeUninit<if_msghdr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_msghdr>(),\n        168usize,\n        concat!(\"Size of: \", stringify!(if_msghdr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_msghdr>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(if_msghdr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_msglen) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(if_msghdr), \"::\", stringify!(ifm_msglen))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_version) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_msghdr),\n            \"::\",\n            stringify!(ifm_version)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_type) as usize - ptr as usize },\n        3usize,\n        concat!(\"Offset of field: \", stringify!(if_msghdr), \"::\", stringify!(ifm_type))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_hdrlen) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(if_msghdr), \"::\", stringify!(ifm_hdrlen))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_index) as usize - ptr as usize },\n        6usize,\n        concat!(\"Offset of field: \", stringify!(if_msghdr), \"::\", stringify!(ifm_index))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_tableid) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_msghdr),\n            \"::\",\n            stringify!(ifm_tableid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_pad1) as usize - ptr as usize },\n        10usize,\n        concat!(\"Offset of field: \", stringify!(if_msghdr), \"::\", stringify!(ifm_pad1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_pad2) as usize - ptr as usize },\n        11usize,\n        concat!(\"Offset of field: \", stringify!(if_msghdr), \"::\", stringify!(ifm_pad2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_addrs) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(if_msghdr), \"::\", stringify!(ifm_addrs))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_flags) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(if_msghdr), \"::\", stringify!(ifm_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_xflags) as usize - ptr as usize },\n        20usize,\n        concat!(\"Offset of field: \", stringify!(if_msghdr), \"::\", stringify!(ifm_xflags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_data) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(if_msghdr), \"::\", stringify!(ifm_data))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ifa_msghdr {\n    pub ifam_msglen: u_short,\n    pub ifam_version: u_char,\n    pub ifam_type: u_char,\n    pub ifam_hdrlen: u_short,\n    pub ifam_index: u_short,\n    pub ifam_tableid: u_short,\n    pub ifam_pad1: u_char,\n    pub ifam_pad2: u_char,\n    pub ifam_addrs: ::std::os::raw::c_int,\n    pub ifam_flags: ::std::os::raw::c_int,\n    pub ifam_metric: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_ifa_msghdr() {\n    const UNINIT: ::std::mem::MaybeUninit<ifa_msghdr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifa_msghdr>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(ifa_msghdr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifa_msghdr>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(ifa_msghdr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifam_msglen) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifa_msghdr),\n            \"::\",\n            stringify!(ifam_msglen)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifam_version) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifa_msghdr),\n            \"::\",\n            stringify!(ifam_version)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifam_type) as usize - ptr as usize },\n        3usize,\n        concat!(\"Offset of field: \", stringify!(ifa_msghdr), \"::\", stringify!(ifam_type))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifam_hdrlen) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifa_msghdr),\n            \"::\",\n            stringify!(ifam_hdrlen)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifam_index) as usize - ptr as usize },\n        6usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifa_msghdr),\n            \"::\",\n            stringify!(ifam_index)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifam_tableid) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifa_msghdr),\n            \"::\",\n            stringify!(ifam_tableid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifam_pad1) as usize - ptr as usize },\n        10usize,\n        concat!(\"Offset of field: \", stringify!(ifa_msghdr), \"::\", stringify!(ifam_pad1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifam_pad2) as usize - ptr as usize },\n        11usize,\n        concat!(\"Offset of field: \", stringify!(ifa_msghdr), \"::\", stringify!(ifam_pad2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifam_addrs) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifa_msghdr),\n            \"::\",\n            stringify!(ifam_addrs)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifam_flags) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifa_msghdr),\n            \"::\",\n            stringify!(ifam_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifam_metric) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifa_msghdr),\n            \"::\",\n            stringify!(ifam_metric)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct if_announcemsghdr {\n    pub ifan_msglen: u_short,\n    pub ifan_version: u_char,\n    pub ifan_type: u_char,\n    pub ifan_hdrlen: u_short,\n    pub ifan_index: u_short,\n    pub ifan_what: u_short,\n    pub ifan_name: [::std::os::raw::c_char; 16usize],\n}\n#[test]\nfn bindgen_test_layout_if_announcemsghdr() {\n    const UNINIT: ::std::mem::MaybeUninit<if_announcemsghdr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_announcemsghdr>(),\n        26usize,\n        concat!(\"Size of: \", stringify!(if_announcemsghdr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_announcemsghdr>(),\n        2usize,\n        concat!(\"Alignment of \", stringify!(if_announcemsghdr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifan_msglen) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_announcemsghdr),\n            \"::\",\n            stringify!(ifan_msglen)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifan_version) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_announcemsghdr),\n            \"::\",\n            stringify!(ifan_version)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifan_type) as usize - ptr as usize },\n        3usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_announcemsghdr),\n            \"::\",\n            stringify!(ifan_type)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifan_hdrlen) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_announcemsghdr),\n            \"::\",\n            stringify!(ifan_hdrlen)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifan_index) as usize - ptr as usize },\n        6usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_announcemsghdr),\n            \"::\",\n            stringify!(ifan_index)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifan_what) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_announcemsghdr),\n            \"::\",\n            stringify!(ifan_what)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifan_name) as usize - ptr as usize },\n        10usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_announcemsghdr),\n            \"::\",\n            stringify!(ifan_name)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct if_ieee80211_data {\n    pub ifie_channel: u8,\n    pub ifie_nwid_len: u8,\n    pub ifie_flags: u32,\n    pub ifie_xflags: u32,\n    pub ifie_nwid: [u8; 32usize],\n    pub ifie_addr: [u8; 6usize],\n}\n#[test]\nfn bindgen_test_layout_if_ieee80211_data() {\n    const UNINIT: ::std::mem::MaybeUninit<if_ieee80211_data> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_ieee80211_data>(),\n        52usize,\n        concat!(\"Size of: \", stringify!(if_ieee80211_data))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_ieee80211_data>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(if_ieee80211_data))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifie_channel) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_ieee80211_data),\n            \"::\",\n            stringify!(ifie_channel)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifie_nwid_len) as usize - ptr as usize },\n        1usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_ieee80211_data),\n            \"::\",\n            stringify!(ifie_nwid_len)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifie_flags) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_ieee80211_data),\n            \"::\",\n            stringify!(ifie_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifie_xflags) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_ieee80211_data),\n            \"::\",\n            stringify!(ifie_xflags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifie_nwid) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_ieee80211_data),\n            \"::\",\n            stringify!(ifie_nwid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifie_addr) as usize - ptr as usize },\n        44usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_ieee80211_data),\n            \"::\",\n            stringify!(ifie_addr)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct if_ieee80211_msghdr {\n    pub ifim_msglen: u16,\n    pub ifim_version: u8,\n    pub ifim_type: u8,\n    pub ifim_hdrlen: u16,\n    pub ifim_index: u16,\n    pub ifim_tableid: u16,\n    pub ifim_ifie: if_ieee80211_data,\n}\n#[test]\nfn bindgen_test_layout_if_ieee80211_msghdr() {\n    const UNINIT: ::std::mem::MaybeUninit<if_ieee80211_msghdr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_ieee80211_msghdr>(),\n        64usize,\n        concat!(\"Size of: \", stringify!(if_ieee80211_msghdr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_ieee80211_msghdr>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(if_ieee80211_msghdr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifim_msglen) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_ieee80211_msghdr),\n            \"::\",\n            stringify!(ifim_msglen)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifim_version) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_ieee80211_msghdr),\n            \"::\",\n            stringify!(ifim_version)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifim_type) as usize - ptr as usize },\n        3usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_ieee80211_msghdr),\n            \"::\",\n            stringify!(ifim_type)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifim_hdrlen) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_ieee80211_msghdr),\n            \"::\",\n            stringify!(ifim_hdrlen)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifim_index) as usize - ptr as usize },\n        6usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_ieee80211_msghdr),\n            \"::\",\n            stringify!(ifim_index)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifim_tableid) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_ieee80211_msghdr),\n            \"::\",\n            stringify!(ifim_tableid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifim_ifie) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_ieee80211_msghdr),\n            \"::\",\n            stringify!(ifim_ifie)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct if_nameindex_msg {\n    pub if_index: ::std::os::raw::c_uint,\n    pub if_name: [::std::os::raw::c_char; 16usize],\n}\n#[test]\nfn bindgen_test_layout_if_nameindex_msg() {\n    const UNINIT: ::std::mem::MaybeUninit<if_nameindex_msg> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_nameindex_msg>(),\n        20usize,\n        concat!(\"Size of: \", stringify!(if_nameindex_msg))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_nameindex_msg>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(if_nameindex_msg))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).if_index) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_nameindex_msg),\n            \"::\",\n            stringify!(if_index)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).if_name) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_nameindex_msg),\n            \"::\",\n            stringify!(if_name)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct ifg_req {\n    pub ifgrq_ifgrqu: ifg_req__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union ifg_req__bindgen_ty_1 {\n    pub ifgrqu_group: [::std::os::raw::c_char; 16usize],\n    pub ifgrqu_member: [::std::os::raw::c_char; 16usize],\n}\n#[test]\nfn bindgen_test_layout_ifg_req__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<ifg_req__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifg_req__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(ifg_req__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifg_req__bindgen_ty_1>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(ifg_req__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifgrqu_group) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifg_req__bindgen_ty_1),\n            \"::\",\n            stringify!(ifgrqu_group)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifgrqu_member) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifg_req__bindgen_ty_1),\n            \"::\",\n            stringify!(ifgrqu_member)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_ifg_req() {\n    const UNINIT: ::std::mem::MaybeUninit<ifg_req> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifg_req>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(ifg_req))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifg_req>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(ifg_req))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifgrq_ifgrqu) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(ifg_req), \"::\", stringify!(ifgrq_ifgrqu))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ifg_attrib {\n    pub ifg_carp_demoted: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_ifg_attrib() {\n    const UNINIT: ::std::mem::MaybeUninit<ifg_attrib> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifg_attrib>(),\n        4usize,\n        concat!(\"Size of: \", stringify!(ifg_attrib))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifg_attrib>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(ifg_attrib))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifg_carp_demoted) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifg_attrib),\n            \"::\",\n            stringify!(ifg_carp_demoted)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct ifgroupreq {\n    pub ifgr_name: [::std::os::raw::c_char; 16usize],\n    pub ifgr_len: u_int,\n    pub ifgr_ifgru: ifgroupreq__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union ifgroupreq__bindgen_ty_1 {\n    pub ifgru_group: [::std::os::raw::c_char; 16usize],\n    pub ifgru_groups: *mut ifg_req,\n    pub ifgru_attrib: ifg_attrib,\n}\n#[test]\nfn bindgen_test_layout_ifgroupreq__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<ifgroupreq__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifgroupreq__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(ifgroupreq__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifgroupreq__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(ifgroupreq__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifgru_group) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifgroupreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifgru_group)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifgru_groups) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifgroupreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifgru_groups)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifgru_attrib) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifgroupreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifgru_attrib)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_ifgroupreq() {\n    const UNINIT: ::std::mem::MaybeUninit<ifgroupreq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifgroupreq>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(ifgroupreq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifgroupreq>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(ifgroupreq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifgr_name) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(ifgroupreq), \"::\", stringify!(ifgr_name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifgr_len) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(ifgroupreq), \"::\", stringify!(ifgr_len))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifgr_ifgru) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifgroupreq),\n            \"::\",\n            stringify!(ifgr_ifgru)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct ifreq {\n    pub ifr_name: [::std::os::raw::c_char; 16usize],\n    pub ifr_ifru: ifreq__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union ifreq__bindgen_ty_1 {\n    pub ifru_addr: sockaddr,\n    pub ifru_dstaddr: sockaddr,\n    pub ifru_broadaddr: sockaddr,\n    pub ifru_flags: ::std::os::raw::c_short,\n    pub ifru_metric: ::std::os::raw::c_int,\n    pub ifru_vnetid: i64,\n    pub ifru_media: u64,\n    pub ifru_data: caddr_t,\n    pub ifru_index: ::std::os::raw::c_uint,\n}\n#[test]\nfn bindgen_test_layout_ifreq__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<ifreq__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifreq__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(ifreq__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifreq__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(ifreq__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifru_addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifru_addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifru_dstaddr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifru_dstaddr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifru_broadaddr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifru_broadaddr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifru_flags) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifru_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifru_metric) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifru_metric)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifru_vnetid) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifru_vnetid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifru_media) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifru_media)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifru_data) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifru_data)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifru_index) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifru_index)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_ifreq() {\n    const UNINIT: ::std::mem::MaybeUninit<ifreq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifreq>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(ifreq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifreq>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(ifreq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifr_name) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(ifreq), \"::\", stringify!(ifr_name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifr_ifru) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(ifreq), \"::\", stringify!(ifr_ifru))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct ifaliasreq {\n    pub ifra_name: [::std::os::raw::c_char; 16usize],\n    pub ifra_ifrau: ifaliasreq__bindgen_ty_1,\n    pub ifra_dstaddr: sockaddr,\n    pub ifra_mask: sockaddr,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union ifaliasreq__bindgen_ty_1 {\n    pub ifrau_addr: sockaddr,\n    pub ifrau_align: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_ifaliasreq__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<ifaliasreq__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifaliasreq__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(ifaliasreq__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifaliasreq__bindgen_ty_1>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(ifaliasreq__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifrau_addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifaliasreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifrau_addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifrau_align) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifaliasreq__bindgen_ty_1),\n            \"::\",\n            stringify!(ifrau_align)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_ifaliasreq() {\n    const UNINIT: ::std::mem::MaybeUninit<ifaliasreq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifaliasreq>(),\n        64usize,\n        concat!(\"Size of: \", stringify!(ifaliasreq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifaliasreq>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(ifaliasreq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifra_name) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(ifaliasreq), \"::\", stringify!(ifra_name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifra_ifrau) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifaliasreq),\n            \"::\",\n            stringify!(ifra_ifrau)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifra_dstaddr) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifaliasreq),\n            \"::\",\n            stringify!(ifra_dstaddr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifra_mask) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(ifaliasreq), \"::\", stringify!(ifra_mask))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ifmediareq {\n    pub ifm_name: [::std::os::raw::c_char; 16usize],\n    pub ifm_current: u64,\n    pub ifm_mask: u64,\n    pub ifm_status: u64,\n    pub ifm_active: u64,\n    pub ifm_count: ::std::os::raw::c_int,\n    pub ifm_ulist: *mut u64,\n}\n#[test]\nfn bindgen_test_layout_ifmediareq() {\n    const UNINIT: ::std::mem::MaybeUninit<ifmediareq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifmediareq>(),\n        64usize,\n        concat!(\"Size of: \", stringify!(ifmediareq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifmediareq>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(ifmediareq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_name) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(ifmediareq), \"::\", stringify!(ifm_name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_current) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifmediareq),\n            \"::\",\n            stringify!(ifm_current)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_mask) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(ifmediareq), \"::\", stringify!(ifm_mask))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_status) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifmediareq),\n            \"::\",\n            stringify!(ifm_status)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_active) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifmediareq),\n            \"::\",\n            stringify!(ifm_active)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_count) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(ifmediareq), \"::\", stringify!(ifm_count))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifm_ulist) as usize - ptr as usize },\n        56usize,\n        concat!(\"Offset of field: \", stringify!(ifmediareq), \"::\", stringify!(ifm_ulist))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ifkalivereq {\n    pub ikar_name: [::std::os::raw::c_char; 16usize],\n    pub ikar_timeo: ::std::os::raw::c_int,\n    pub ikar_cnt: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_ifkalivereq() {\n    const UNINIT: ::std::mem::MaybeUninit<ifkalivereq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifkalivereq>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(ifkalivereq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifkalivereq>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(ifkalivereq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ikar_name) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifkalivereq),\n            \"::\",\n            stringify!(ikar_name)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ikar_timeo) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifkalivereq),\n            \"::\",\n            stringify!(ikar_timeo)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ikar_cnt) as usize - ptr as usize },\n        20usize,\n        concat!(\"Offset of field: \", stringify!(ifkalivereq), \"::\", stringify!(ikar_cnt))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct ifconf {\n    pub ifc_len: ::std::os::raw::c_int,\n    pub ifc_ifcu: ifconf__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union ifconf__bindgen_ty_1 {\n    pub ifcu_buf: caddr_t,\n    pub ifcu_req: *mut ifreq,\n}\n#[test]\nfn bindgen_test_layout_ifconf__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<ifconf__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifconf__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(ifconf__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifconf__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(ifconf__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifcu_buf) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifconf__bindgen_ty_1),\n            \"::\",\n            stringify!(ifcu_buf)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifcu_req) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ifconf__bindgen_ty_1),\n            \"::\",\n            stringify!(ifcu_req)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_ifconf() {\n    const UNINIT: ::std::mem::MaybeUninit<ifconf> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ifconf>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(ifconf))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ifconf>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(ifconf))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifc_len) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(ifconf), \"::\", stringify!(ifc_len))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifc_ifcu) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(ifconf), \"::\", stringify!(ifc_ifcu))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct if_laddrreq {\n    pub iflr_name: [::std::os::raw::c_char; 16usize],\n    pub flags: ::std::os::raw::c_uint,\n    pub prefixlen: ::std::os::raw::c_uint,\n    pub addr: sockaddr_storage,\n    pub dstaddr: sockaddr_storage,\n}\n#[test]\nfn bindgen_test_layout_if_laddrreq() {\n    const UNINIT: ::std::mem::MaybeUninit<if_laddrreq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_laddrreq>(),\n        536usize,\n        concat!(\"Size of: \", stringify!(if_laddrreq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_laddrreq>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(if_laddrreq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).iflr_name) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_laddrreq),\n            \"::\",\n            stringify!(iflr_name)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flags) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(if_laddrreq), \"::\", stringify!(flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).prefixlen) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_laddrreq),\n            \"::\",\n            stringify!(prefixlen)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(if_laddrreq), \"::\", stringify!(addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dstaddr) as usize - ptr as usize },\n        280usize,\n        concat!(\"Offset of field: \", stringify!(if_laddrreq), \"::\", stringify!(dstaddr))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct if_afreq {\n    pub ifar_name: [::std::os::raw::c_char; 16usize],\n    pub ifar_af: sa_family_t,\n}\n#[test]\nfn bindgen_test_layout_if_afreq() {\n    const UNINIT: ::std::mem::MaybeUninit<if_afreq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_afreq>(),\n        17usize,\n        concat!(\"Size of: \", stringify!(if_afreq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_afreq>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(if_afreq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifar_name) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(if_afreq), \"::\", stringify!(ifar_name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifar_af) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(if_afreq), \"::\", stringify!(ifar_af))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct if_parent {\n    pub ifp_name: [::std::os::raw::c_char; 16usize],\n    pub ifp_parent: [::std::os::raw::c_char; 16usize],\n}\n#[test]\nfn bindgen_test_layout_if_parent() {\n    const UNINIT: ::std::mem::MaybeUninit<if_parent> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_parent>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(if_parent))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_parent>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(if_parent))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifp_name) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(if_parent), \"::\", stringify!(ifp_name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifp_parent) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(if_parent), \"::\", stringify!(ifp_parent))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct if_sffpage {\n    pub sff_ifname: [::std::os::raw::c_char; 16usize],\n    pub sff_addr: u8,\n    pub sff_page: u8,\n    pub sff_data: [u8; 256usize],\n}\n#[test]\nfn bindgen_test_layout_if_sffpage() {\n    const UNINIT: ::std::mem::MaybeUninit<if_sffpage> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<if_sffpage>(),\n        274usize,\n        concat!(\"Size of: \", stringify!(if_sffpage))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<if_sffpage>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(if_sffpage))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sff_ifname) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(if_sffpage),\n            \"::\",\n            stringify!(sff_ifname)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sff_addr) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(if_sffpage), \"::\", stringify!(sff_addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sff_page) as usize - ptr as usize },\n        17usize,\n        concat!(\"Offset of field: \", stringify!(if_sffpage), \"::\", stringify!(sff_page))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sff_data) as usize - ptr as usize },\n        18usize,\n        concat!(\"Offset of field: \", stringify!(if_sffpage), \"::\", stringify!(sff_data))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct arphdr {\n    pub ar_hrd: u_int16_t,\n    pub ar_pro: u_int16_t,\n    pub ar_hln: u_int8_t,\n    pub ar_pln: u_int8_t,\n    pub ar_op: u_int16_t,\n}\n#[test]\nfn bindgen_test_layout_arphdr() {\n    const UNINIT: ::std::mem::MaybeUninit<arphdr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<arphdr>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(arphdr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<arphdr>(),\n        2usize,\n        concat!(\"Alignment of \", stringify!(arphdr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ar_hrd) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(arphdr), \"::\", stringify!(ar_hrd))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ar_pro) as usize - ptr as usize },\n        2usize,\n        concat!(\"Offset of field: \", stringify!(arphdr), \"::\", stringify!(ar_pro))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ar_hln) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(arphdr), \"::\", stringify!(ar_hln))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ar_pln) as usize - ptr as usize },\n        5usize,\n        concat!(\"Offset of field: \", stringify!(arphdr), \"::\", stringify!(ar_pln))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ar_op) as usize - ptr as usize },\n        6usize,\n        concat!(\"Offset of field: \", stringify!(arphdr), \"::\", stringify!(ar_op))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct arpreq {\n    pub arp_pa: sockaddr,\n    pub arp_ha: sockaddr,\n    pub arp_flags: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_arpreq() {\n    const UNINIT: ::std::mem::MaybeUninit<arpreq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<arpreq>(),\n        36usize,\n        concat!(\"Size of: \", stringify!(arpreq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<arpreq>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(arpreq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).arp_pa) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(arpreq), \"::\", stringify!(arp_pa))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).arp_ha) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(arpreq), \"::\", stringify!(arp_ha))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).arp_flags) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(arpreq), \"::\", stringify!(arp_flags))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct rb_type {\n    pub t_compare: ::std::option::Option<\n        unsafe extern \"C\" fn(\n            arg1: *const ::std::os::raw::c_void,\n            arg2: *const ::std::os::raw::c_void,\n        ) -> ::std::os::raw::c_int,\n    >,\n    pub t_augment: ::std::option::Option<unsafe extern \"C\" fn(arg1: *mut ::std::os::raw::c_void)>,\n    pub t_offset: ::std::os::raw::c_uint,\n}\n#[test]\nfn bindgen_test_layout_rb_type() {\n    const UNINIT: ::std::mem::MaybeUninit<rb_type> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<rb_type>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(rb_type))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<rb_type>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(rb_type))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).t_compare) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(rb_type), \"::\", stringify!(t_compare))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).t_augment) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(rb_type), \"::\", stringify!(t_augment))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).t_offset) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(rb_type), \"::\", stringify!(t_offset))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct rb_tree {\n    pub rbt_root: *mut rb_entry,\n}\n#[test]\nfn bindgen_test_layout_rb_tree() {\n    const UNINIT: ::std::mem::MaybeUninit<rb_tree> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<rb_tree>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(rb_tree))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<rb_tree>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(rb_tree))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbt_root) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(rb_tree), \"::\", stringify!(rbt_root))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct rb_entry {\n    pub rbt_parent: *mut rb_entry,\n    pub rbt_left: *mut rb_entry,\n    pub rbt_right: *mut rb_entry,\n    pub rbt_color: ::std::os::raw::c_uint,\n}\n#[test]\nfn bindgen_test_layout_rb_entry() {\n    const UNINIT: ::std::mem::MaybeUninit<rb_entry> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<rb_entry>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(rb_entry))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<rb_entry>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(rb_entry))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbt_parent) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(rb_entry), \"::\", stringify!(rbt_parent))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbt_left) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(rb_entry), \"::\", stringify!(rbt_left))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbt_right) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(rb_entry), \"::\", stringify!(rbt_right))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbt_color) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(rb_entry), \"::\", stringify!(rbt_color))\n    );\n}\nunsafe extern \"C\" {\n    pub fn _rb_insert(\n        arg1: *const rb_type,\n        arg2: *mut rb_tree,\n        arg3: *mut ::std::os::raw::c_void,\n    ) -> *mut ::std::os::raw::c_void;\n}\nunsafe extern \"C\" {\n    pub fn _rb_remove(\n        arg1: *const rb_type,\n        arg2: *mut rb_tree,\n        arg3: *mut ::std::os::raw::c_void,\n    ) -> *mut ::std::os::raw::c_void;\n}\nunsafe extern \"C\" {\n    pub fn _rb_find(\n        arg1: *const rb_type,\n        arg2: *mut rb_tree,\n        arg3: *const ::std::os::raw::c_void,\n    ) -> *mut ::std::os::raw::c_void;\n}\nunsafe extern \"C\" {\n    pub fn _rb_nfind(\n        arg1: *const rb_type,\n        arg2: *mut rb_tree,\n        arg3: *const ::std::os::raw::c_void,\n    ) -> *mut ::std::os::raw::c_void;\n}\nunsafe extern \"C\" {\n    pub fn _rb_root(arg1: *const rb_type, arg2: *mut rb_tree) -> *mut ::std::os::raw::c_void;\n}\nunsafe extern \"C\" {\n    pub fn _rb_min(arg1: *const rb_type, arg2: *mut rb_tree) -> *mut ::std::os::raw::c_void;\n}\nunsafe extern \"C\" {\n    pub fn _rb_max(arg1: *const rb_type, arg2: *mut rb_tree) -> *mut ::std::os::raw::c_void;\n}\nunsafe extern \"C\" {\n    pub fn _rb_next(arg1: *const rb_type, arg2: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void;\n}\nunsafe extern \"C\" {\n    pub fn _rb_prev(arg1: *const rb_type, arg2: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void;\n}\nunsafe extern \"C\" {\n    pub fn _rb_left(arg1: *const rb_type, arg2: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void;\n}\nunsafe extern \"C\" {\n    pub fn _rb_right(arg1: *const rb_type, arg2: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void;\n}\nunsafe extern \"C\" {\n    pub fn _rb_parent(arg1: *const rb_type, arg2: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void;\n}\nunsafe extern \"C\" {\n    pub fn _rb_set_left(arg1: *const rb_type, arg2: *mut ::std::os::raw::c_void, arg3: *mut ::std::os::raw::c_void);\n}\nunsafe extern \"C\" {\n    pub fn _rb_set_right(arg1: *const rb_type, arg2: *mut ::std::os::raw::c_void, arg3: *mut ::std::os::raw::c_void);\n}\nunsafe extern \"C\" {\n    pub fn _rb_set_parent(arg1: *const rb_type, arg2: *mut ::std::os::raw::c_void, arg3: *mut ::std::os::raw::c_void);\n}\nunsafe extern \"C\" {\n    pub fn _rb_poison(arg1: *const rb_type, arg2: *mut ::std::os::raw::c_void, arg3: ::std::os::raw::c_ulong);\n}\nunsafe extern \"C\" {\n    pub fn _rb_check(\n        arg1: *const rb_type,\n        arg2: *mut ::std::os::raw::c_void,\n        arg3: ::std::os::raw::c_ulong,\n    ) -> ::std::os::raw::c_int;\n}\npub const lock_class_index_LO_CLASS_KERNEL_LOCK: lock_class_index = 0;\npub const lock_class_index_LO_CLASS_SCHED_LOCK: lock_class_index = 1;\npub const lock_class_index_LO_CLASS_MUTEX: lock_class_index = 2;\npub const lock_class_index_LO_CLASS_RWLOCK: lock_class_index = 3;\npub const lock_class_index_LO_CLASS_RRWLOCK: lock_class_index = 4;\npub type lock_class_index = ::std::os::raw::c_uint;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct lock_object {\n    pub lo_type: *const lock_type,\n    pub lo_name: *const ::std::os::raw::c_char,\n    pub lo_witness: *mut witness,\n    pub lo_flags: ::std::os::raw::c_uint,\n}\n#[test]\nfn bindgen_test_layout_lock_object() {\n    const UNINIT: ::std::mem::MaybeUninit<lock_object> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<lock_object>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(lock_object))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<lock_object>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(lock_object))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lo_type) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(lock_object), \"::\", stringify!(lo_type))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lo_name) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(lock_object), \"::\", stringify!(lo_name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lo_witness) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(lock_object),\n            \"::\",\n            stringify!(lo_witness)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lo_flags) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(lock_object), \"::\", stringify!(lo_flags))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct lock_type {\n    pub lt_name: *const ::std::os::raw::c_char,\n}\n#[test]\nfn bindgen_test_layout_lock_type() {\n    const UNINIT: ::std::mem::MaybeUninit<lock_type> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<lock_type>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(lock_type))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<lock_type>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(lock_type))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lt_name) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(lock_type), \"::\", stringify!(lt_name))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct proc_ {\n    _unused: [u8; 0],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct rwlock {\n    pub rwl_owner: ::std::os::raw::c_ulong,\n    pub rwl_name: *const ::std::os::raw::c_char,\n}\n#[test]\nfn bindgen_test_layout_rwlock() {\n    const UNINIT: ::std::mem::MaybeUninit<rwlock> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<rwlock>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(rwlock))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<rwlock>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(rwlock))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rwl_owner) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(rwlock), \"::\", stringify!(rwl_owner))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rwl_name) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(rwlock), \"::\", stringify!(rwl_name))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct rrwlock {\n    pub rrwl_lock: rwlock,\n    pub rrwl_wcnt: u32,\n}\n#[test]\nfn bindgen_test_layout_rrwlock() {\n    const UNINIT: ::std::mem::MaybeUninit<rrwlock> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<rrwlock>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(rrwlock))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<rrwlock>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(rrwlock))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rrwl_lock) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(rrwlock), \"::\", stringify!(rrwl_lock))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rrwl_wcnt) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(rrwlock), \"::\", stringify!(rrwl_wcnt))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct refcnt {\n    pub r_refs: ::std::os::raw::c_uint,\n    pub r_traceidx: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_refcnt() {\n    const UNINIT: ::std::mem::MaybeUninit<refcnt> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<refcnt>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(refcnt))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<refcnt>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(refcnt))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).r_refs) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(refcnt), \"::\", stringify!(r_refs))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).r_traceidx) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(refcnt), \"::\", stringify!(r_traceidx))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct circq {\n    pub next: *mut circq,\n    pub prev: *mut circq,\n}\n#[test]\nfn bindgen_test_layout_circq() {\n    const UNINIT: ::std::mem::MaybeUninit<circq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<circq>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(circq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<circq>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(circq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).next) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(circq), \"::\", stringify!(next))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).prev) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(circq), \"::\", stringify!(prev))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct timeout {\n    pub to_list: circq,\n    pub to_abstime: timespec,\n    pub to_func: ::std::option::Option<unsafe extern \"C\" fn(arg1: *mut ::std::os::raw::c_void)>,\n    pub to_arg: *mut ::std::os::raw::c_void,\n    pub to_process: *mut process,\n    pub to_time: ::std::os::raw::c_int,\n    pub to_flags: ::std::os::raw::c_int,\n    pub to_kclock: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_timeout() {\n    const UNINIT: ::std::mem::MaybeUninit<timeout> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<timeout>(),\n        72usize,\n        concat!(\"Size of: \", stringify!(timeout))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<timeout>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(timeout))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).to_list) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(timeout), \"::\", stringify!(to_list))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).to_abstime) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(timeout), \"::\", stringify!(to_abstime))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).to_func) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(timeout), \"::\", stringify!(to_func))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).to_arg) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(timeout), \"::\", stringify!(to_arg))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).to_process) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(timeout), \"::\", stringify!(to_process))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).to_time) as usize - ptr as usize },\n        56usize,\n        concat!(\"Offset of field: \", stringify!(timeout), \"::\", stringify!(to_time))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).to_flags) as usize - ptr as usize },\n        60usize,\n        concat!(\"Offset of field: \", stringify!(timeout), \"::\", stringify!(to_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).to_kclock) as usize - ptr as usize },\n        64usize,\n        concat!(\"Offset of field: \", stringify!(timeout), \"::\", stringify!(to_kclock))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct timeoutstat {\n    pub tos_added: u64,\n    pub tos_cancelled: u64,\n    pub tos_deleted: u64,\n    pub tos_late: u64,\n    pub tos_pending: u64,\n    pub tos_readded: u64,\n    pub tos_rescheduled: u64,\n    pub tos_run_softclock: u64,\n    pub tos_run_thread: u64,\n    pub tos_scheduled: u64,\n    pub tos_softclocks: u64,\n    pub tos_thread_wakeups: u64,\n}\n#[test]\nfn bindgen_test_layout_timeoutstat() {\n    const UNINIT: ::std::mem::MaybeUninit<timeoutstat> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<timeoutstat>(),\n        96usize,\n        concat!(\"Size of: \", stringify!(timeoutstat))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<timeoutstat>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(timeoutstat))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tos_added) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(timeoutstat),\n            \"::\",\n            stringify!(tos_added)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tos_cancelled) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(timeoutstat),\n            \"::\",\n            stringify!(tos_cancelled)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tos_deleted) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(timeoutstat),\n            \"::\",\n            stringify!(tos_deleted)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tos_late) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(timeoutstat), \"::\", stringify!(tos_late))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tos_pending) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(timeoutstat),\n            \"::\",\n            stringify!(tos_pending)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tos_readded) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(timeoutstat),\n            \"::\",\n            stringify!(tos_readded)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tos_rescheduled) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(timeoutstat),\n            \"::\",\n            stringify!(tos_rescheduled)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tos_run_softclock) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(timeoutstat),\n            \"::\",\n            stringify!(tos_run_softclock)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tos_run_thread) as usize - ptr as usize },\n        64usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(timeoutstat),\n            \"::\",\n            stringify!(tos_run_thread)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tos_scheduled) as usize - ptr as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(timeoutstat),\n            \"::\",\n            stringify!(tos_scheduled)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tos_softclocks) as usize - ptr as usize },\n        80usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(timeoutstat),\n            \"::\",\n            stringify!(tos_softclocks)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tos_thread_wakeups) as usize - ptr as usize },\n        88usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(timeoutstat),\n            \"::\",\n            stringify!(tos_thread_wakeups)\n        )\n    );\n}\npub type in_addr_t = __in_addr_t;\npub type in_port_t = __in_port_t;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct in_addr {\n    pub s_addr: in_addr_t,\n}\n#[test]\nfn bindgen_test_layout_in_addr() {\n    const UNINIT: ::std::mem::MaybeUninit<in_addr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<in_addr>(),\n        4usize,\n        concat!(\"Size of: \", stringify!(in_addr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<in_addr>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(in_addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).s_addr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(in_addr), \"::\", stringify!(s_addr))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sockaddr_in {\n    pub sin_len: u_int8_t,\n    pub sin_family: sa_family_t,\n    pub sin_port: in_port_t,\n    pub sin_addr: in_addr,\n    pub sin_zero: [i8; 8usize],\n}\n#[test]\nfn bindgen_test_layout_sockaddr_in() {\n    const UNINIT: ::std::mem::MaybeUninit<sockaddr_in> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sockaddr_in>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(sockaddr_in))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sockaddr_in>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(sockaddr_in))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin_len) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr_in), \"::\", stringify!(sin_len))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin_family) as usize - ptr as usize },\n        1usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_in),\n            \"::\",\n            stringify!(sin_family)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin_port) as usize - ptr as usize },\n        2usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr_in), \"::\", stringify!(sin_port))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin_addr) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr_in), \"::\", stringify!(sin_addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin_zero) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(sockaddr_in), \"::\", stringify!(sin_zero))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ip_opts {\n    pub ip_dst: in_addr,\n    pub ip_opts: [i8; 40usize],\n}\n#[test]\nfn bindgen_test_layout_ip_opts() {\n    const UNINIT: ::std::mem::MaybeUninit<ip_opts> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ip_opts>(),\n        44usize,\n        concat!(\"Size of: \", stringify!(ip_opts))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ip_opts>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(ip_opts))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ip_dst) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(ip_opts), \"::\", stringify!(ip_dst))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ip_opts) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(ip_opts), \"::\", stringify!(ip_opts))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ip_mreq {\n    pub imr_multiaddr: in_addr,\n    pub imr_interface: in_addr,\n}\n#[test]\nfn bindgen_test_layout_ip_mreq() {\n    const UNINIT: ::std::mem::MaybeUninit<ip_mreq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ip_mreq>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(ip_mreq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ip_mreq>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(ip_mreq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).imr_multiaddr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ip_mreq),\n            \"::\",\n            stringify!(imr_multiaddr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).imr_interface) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ip_mreq),\n            \"::\",\n            stringify!(imr_interface)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ip_mreqn {\n    pub imr_multiaddr: in_addr,\n    pub imr_address: in_addr,\n    pub imr_ifindex: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_ip_mreqn() {\n    const UNINIT: ::std::mem::MaybeUninit<ip_mreqn> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ip_mreqn>(),\n        12usize,\n        concat!(\"Size of: \", stringify!(ip_mreqn))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ip_mreqn>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(ip_mreqn))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).imr_multiaddr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ip_mreqn),\n            \"::\",\n            stringify!(imr_multiaddr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).imr_address) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(ip_mreqn), \"::\", stringify!(imr_address))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).imr_ifindex) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(ip_mreqn), \"::\", stringify!(imr_ifindex))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct in6_addr {\n    pub __u6_addr: in6_addr__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union in6_addr__bindgen_ty_1 {\n    pub __u6_addr8: [u_int8_t; 16usize],\n    pub __u6_addr16: [u_int16_t; 8usize],\n    pub __u6_addr32: [u_int32_t; 4usize],\n}\n#[test]\nfn bindgen_test_layout_in6_addr__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<in6_addr__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<in6_addr__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(in6_addr__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<in6_addr__bindgen_ty_1>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(in6_addr__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__u6_addr8) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(in6_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(__u6_addr8)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__u6_addr16) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(in6_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(__u6_addr16)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__u6_addr32) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(in6_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(__u6_addr32)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_in6_addr() {\n    const UNINIT: ::std::mem::MaybeUninit<in6_addr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<in6_addr>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(in6_addr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<in6_addr>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(in6_addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).__u6_addr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(in6_addr), \"::\", stringify!(__u6_addr))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct sockaddr_in6 {\n    pub sin6_len: u_int8_t,\n    pub sin6_family: sa_family_t,\n    pub sin6_port: in_port_t,\n    pub sin6_flowinfo: u_int32_t,\n    pub sin6_addr: in6_addr,\n    pub sin6_scope_id: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_sockaddr_in6() {\n    const UNINIT: ::std::mem::MaybeUninit<sockaddr_in6> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sockaddr_in6>(),\n        28usize,\n        concat!(\"Size of: \", stringify!(sockaddr_in6))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sockaddr_in6>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(sockaddr_in6))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin6_len) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_in6),\n            \"::\",\n            stringify!(sin6_len)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin6_family) as usize - ptr as usize },\n        1usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_in6),\n            \"::\",\n            stringify!(sin6_family)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin6_port) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_in6),\n            \"::\",\n            stringify!(sin6_port)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin6_flowinfo) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_in6),\n            \"::\",\n            stringify!(sin6_flowinfo)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin6_addr) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_in6),\n            \"::\",\n            stringify!(sin6_addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin6_scope_id) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_in6),\n            \"::\",\n            stringify!(sin6_scope_id)\n        )\n    );\n}\nunsafe extern \"C\" {\n    pub static in6addr_any: in6_addr;\n}\nunsafe extern \"C\" {\n    pub static in6addr_loopback: in6_addr;\n}\nunsafe extern \"C\" {\n    pub static in6addr_intfacelocal_allnodes: in6_addr;\n}\nunsafe extern \"C\" {\n    pub static in6addr_linklocal_allnodes: in6_addr;\n}\nunsafe extern \"C\" {\n    pub static in6addr_linklocal_allrouters: in6_addr;\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct ipv6_mreq {\n    pub ipv6mr_multiaddr: in6_addr,\n    pub ipv6mr_interface: ::std::os::raw::c_uint,\n}\n#[test]\nfn bindgen_test_layout_ipv6_mreq() {\n    const UNINIT: ::std::mem::MaybeUninit<ipv6_mreq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ipv6_mreq>(),\n        20usize,\n        concat!(\"Size of: \", stringify!(ipv6_mreq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ipv6_mreq>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(ipv6_mreq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ipv6mr_multiaddr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ipv6_mreq),\n            \"::\",\n            stringify!(ipv6mr_multiaddr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ipv6mr_interface) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ipv6_mreq),\n            \"::\",\n            stringify!(ipv6mr_interface)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct in6_pktinfo {\n    pub ipi6_addr: in6_addr,\n    pub ipi6_ifindex: ::std::os::raw::c_uint,\n}\n#[test]\nfn bindgen_test_layout_in6_pktinfo() {\n    const UNINIT: ::std::mem::MaybeUninit<in6_pktinfo> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<in6_pktinfo>(),\n        20usize,\n        concat!(\"Size of: \", stringify!(in6_pktinfo))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<in6_pktinfo>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(in6_pktinfo))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ipi6_addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(in6_pktinfo),\n            \"::\",\n            stringify!(ipi6_addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ipi6_ifindex) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(in6_pktinfo),\n            \"::\",\n            stringify!(ipi6_ifindex)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct ip6_mtuinfo {\n    pub ip6m_addr: sockaddr_in6,\n    pub ip6m_mtu: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_ip6_mtuinfo() {\n    const UNINIT: ::std::mem::MaybeUninit<ip6_mtuinfo> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<ip6_mtuinfo>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(ip6_mtuinfo))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<ip6_mtuinfo>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(ip6_mtuinfo))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ip6m_addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ip6_mtuinfo),\n            \"::\",\n            stringify!(ip6m_addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ip6m_mtu) as usize - ptr as usize },\n        28usize,\n        concat!(\"Offset of field: \", stringify!(ip6_mtuinfo), \"::\", stringify!(ip6m_mtu))\n    );\n}\nunsafe extern \"C\" {\n    pub fn inet6_opt_init(arg1: *mut ::std::os::raw::c_void, arg2: socklen_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_opt_append(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: socklen_t,\n        arg3: ::std::os::raw::c_int,\n        arg4: u_int8_t,\n        arg5: socklen_t,\n        arg6: u_int8_t,\n        arg7: *mut *mut ::std::os::raw::c_void,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_opt_finish(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: socklen_t,\n        arg3: ::std::os::raw::c_int,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_opt_set_val(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: ::std::os::raw::c_int,\n        arg3: *mut ::std::os::raw::c_void,\n        arg4: socklen_t,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_opt_next(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: socklen_t,\n        arg3: ::std::os::raw::c_int,\n        arg4: *mut u_int8_t,\n        arg5: *mut socklen_t,\n        arg6: *mut *mut ::std::os::raw::c_void,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_opt_find(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: socklen_t,\n        arg3: ::std::os::raw::c_int,\n        arg4: u_int8_t,\n        arg5: *mut socklen_t,\n        arg6: *mut *mut ::std::os::raw::c_void,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_opt_get_val(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: ::std::os::raw::c_int,\n        arg3: *mut ::std::os::raw::c_void,\n        arg4: socklen_t,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rth_space(arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int) -> socklen_t;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rth_init(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: socklen_t,\n        arg3: ::std::os::raw::c_int,\n        arg4: ::std::os::raw::c_int,\n    ) -> *mut ::std::os::raw::c_void;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rth_add(arg1: *mut ::std::os::raw::c_void, arg2: *const in6_addr) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rth_reverse(\n        arg1: *const ::std::os::raw::c_void,\n        arg2: *mut ::std::os::raw::c_void,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rth_segments(arg1: *const ::std::os::raw::c_void) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn inet6_rth_getaddr(arg1: *const ::std::os::raw::c_void, arg2: ::std::os::raw::c_int) -> *mut in6_addr;\n}\nunsafe extern \"C\" {\n    pub fn bindresvport(arg1: ::std::os::raw::c_int, arg2: *mut sockaddr_in) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn bindresvport_sa(arg1: ::std::os::raw::c_int, arg2: *mut sockaddr) -> ::std::os::raw::c_int;\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct radix_node {\n    pub rn_mklist: *mut radix_mask,\n    pub rn_p: *mut radix_node,\n    pub rn_b: ::std::os::raw::c_short,\n    pub rn_bmask: ::std::os::raw::c_char,\n    pub rn_flags: u_char,\n    pub rn_u: radix_node__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union radix_node__bindgen_ty_1 {\n    pub rn_leaf: radix_node__bindgen_ty_1__bindgen_ty_1,\n    pub rn_node: radix_node__bindgen_ty_1__bindgen_ty_2,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct radix_node__bindgen_ty_1__bindgen_ty_1 {\n    pub rn_Key: caddr_t,\n    pub rn_Mask: caddr_t,\n    pub rn_Dupedkey: *mut radix_node,\n}\n#[test]\nfn bindgen_test_layout_radix_node__bindgen_ty_1__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<radix_node__bindgen_ty_1__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<radix_node__bindgen_ty_1__bindgen_ty_1>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(radix_node__bindgen_ty_1__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<radix_node__bindgen_ty_1__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(radix_node__bindgen_ty_1__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_Key) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(rn_Key)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_Mask) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(rn_Mask)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_Dupedkey) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(rn_Dupedkey)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct radix_node__bindgen_ty_1__bindgen_ty_2 {\n    pub rn_Off: ::std::os::raw::c_int,\n    pub rn_L: *mut radix_node,\n    pub rn_R: *mut radix_node,\n}\n#[test]\nfn bindgen_test_layout_radix_node__bindgen_ty_1__bindgen_ty_2() {\n    const UNINIT: ::std::mem::MaybeUninit<radix_node__bindgen_ty_1__bindgen_ty_2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<radix_node__bindgen_ty_1__bindgen_ty_2>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(radix_node__bindgen_ty_1__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<radix_node__bindgen_ty_1__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(radix_node__bindgen_ty_1__bindgen_ty_2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_Off) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node__bindgen_ty_1__bindgen_ty_2),\n            \"::\",\n            stringify!(rn_Off)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_L) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node__bindgen_ty_1__bindgen_ty_2),\n            \"::\",\n            stringify!(rn_L)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_R) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node__bindgen_ty_1__bindgen_ty_2),\n            \"::\",\n            stringify!(rn_R)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_radix_node__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<radix_node__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<radix_node__bindgen_ty_1>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(radix_node__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<radix_node__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(radix_node__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_leaf) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node__bindgen_ty_1),\n            \"::\",\n            stringify!(rn_leaf)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_node) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node__bindgen_ty_1),\n            \"::\",\n            stringify!(rn_node)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_radix_node() {\n    const UNINIT: ::std::mem::MaybeUninit<radix_node> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<radix_node>(),\n        48usize,\n        concat!(\"Size of: \", stringify!(radix_node))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<radix_node>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(radix_node))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_mklist) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(radix_node), \"::\", stringify!(rn_mklist))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_p) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(radix_node), \"::\", stringify!(rn_p))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_b) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(radix_node), \"::\", stringify!(rn_b))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_bmask) as usize - ptr as usize },\n        18usize,\n        concat!(\"Offset of field: \", stringify!(radix_node), \"::\", stringify!(rn_bmask))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_flags) as usize - ptr as usize },\n        19usize,\n        concat!(\"Offset of field: \", stringify!(radix_node), \"::\", stringify!(rn_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rn_u) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(radix_node), \"::\", stringify!(rn_u))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct radix_mask {\n    pub rm_b: ::std::os::raw::c_short,\n    pub rm_unused: ::std::os::raw::c_char,\n    pub rm_flags: u_char,\n    pub rm_mklist: *mut radix_mask,\n    pub rm_rmu: radix_mask__bindgen_ty_1,\n    pub rm_refs: ::std::os::raw::c_int,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union radix_mask__bindgen_ty_1 {\n    pub rmu_mask: caddr_t,\n    pub rmu_leaf: *mut radix_node,\n}\n#[test]\nfn bindgen_test_layout_radix_mask__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<radix_mask__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<radix_mask__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(radix_mask__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<radix_mask__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(radix_mask__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmu_mask) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_mask__bindgen_ty_1),\n            \"::\",\n            stringify!(rmu_mask)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmu_leaf) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_mask__bindgen_ty_1),\n            \"::\",\n            stringify!(rmu_leaf)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_radix_mask() {\n    const UNINIT: ::std::mem::MaybeUninit<radix_mask> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<radix_mask>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(radix_mask))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<radix_mask>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(radix_mask))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rm_b) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(radix_mask), \"::\", stringify!(rm_b))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rm_unused) as usize - ptr as usize },\n        2usize,\n        concat!(\"Offset of field: \", stringify!(radix_mask), \"::\", stringify!(rm_unused))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rm_flags) as usize - ptr as usize },\n        3usize,\n        concat!(\"Offset of field: \", stringify!(radix_mask), \"::\", stringify!(rm_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rm_mklist) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(radix_mask), \"::\", stringify!(rm_mklist))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rm_rmu) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(radix_mask), \"::\", stringify!(rm_rmu))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rm_refs) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(radix_mask), \"::\", stringify!(rm_refs))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct radix_node_head {\n    pub rnh_treetop: *mut radix_node,\n    pub rnh_addrsize: ::std::os::raw::c_int,\n    pub rnh_pktsize: ::std::os::raw::c_int,\n    pub rnh_nodes: [radix_node; 3usize],\n    pub rnh_rtableid: u_int,\n}\n#[test]\nfn bindgen_test_layout_radix_node_head() {\n    const UNINIT: ::std::mem::MaybeUninit<radix_node_head> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<radix_node_head>(),\n        168usize,\n        concat!(\"Size of: \", stringify!(radix_node_head))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<radix_node_head>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(radix_node_head))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_treetop) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_treetop)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_addrsize) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_addrsize)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_pktsize) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_pktsize)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_nodes) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_nodes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rnh_rtableid) as usize - ptr as usize },\n        160usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(radix_node_head),\n            \"::\",\n            stringify!(rnh_rtableid)\n        )\n    );\n}\nunsafe extern \"C\" {\n    pub fn rn_init(arg1: ::std::os::raw::c_uint);\n}\nunsafe extern \"C\" {\n    pub fn rn_inithead(arg1: *mut *mut ::std::os::raw::c_void, arg2: ::std::os::raw::c_int) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn rn_walktree(\n        arg1: *mut radix_node_head,\n        arg2: ::std::option::Option<\n            unsafe extern \"C\" fn(\n                arg1: *mut radix_node,\n                arg2: *mut ::std::os::raw::c_void,\n                arg3: u_int,\n            ) -> ::std::os::raw::c_int,\n        >,\n        arg3: *mut ::std::os::raw::c_void,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn rn_addroute(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: *mut ::std::os::raw::c_void,\n        arg3: *mut radix_node_head,\n        arg4: *mut radix_node,\n        arg5: u_int8_t,\n    ) -> *mut radix_node;\n}\nunsafe extern \"C\" {\n    pub fn rn_delete(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: *mut ::std::os::raw::c_void,\n        arg3: *mut radix_node_head,\n        arg4: *mut radix_node,\n    ) -> *mut radix_node;\n}\nunsafe extern \"C\" {\n    pub fn rn_lookup(\n        arg1: *mut ::std::os::raw::c_void,\n        arg2: *mut ::std::os::raw::c_void,\n        arg3: *mut radix_node_head,\n    ) -> *mut radix_node;\n}\nunsafe extern \"C\" {\n    pub fn rn_match(arg1: *mut ::std::os::raw::c_void, arg2: *mut radix_node_head) -> *mut radix_node;\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct rt_metrics {\n    pub rmx_pksent: u_int64_t,\n    pub rmx_expire: i64,\n    pub rmx_locks: u_int,\n    pub rmx_mtu: u_int,\n    pub rmx_refcnt: u_int,\n    pub rmx_hopcount: u_int,\n    pub rmx_recvpipe: u_int,\n    pub rmx_sendpipe: u_int,\n    pub rmx_ssthresh: u_int,\n    pub rmx_rtt: u_int,\n    pub rmx_rttvar: u_int,\n    pub rmx_pad: u_int,\n}\n#[test]\nfn bindgen_test_layout_rt_metrics() {\n    const UNINIT: ::std::mem::MaybeUninit<rt_metrics> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<rt_metrics>(),\n        56usize,\n        concat!(\"Size of: \", stringify!(rt_metrics))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<rt_metrics>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(rt_metrics))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmx_pksent) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_metrics),\n            \"::\",\n            stringify!(rmx_pksent)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmx_expire) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_metrics),\n            \"::\",\n            stringify!(rmx_expire)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmx_locks) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(rt_metrics), \"::\", stringify!(rmx_locks))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmx_mtu) as usize - ptr as usize },\n        20usize,\n        concat!(\"Offset of field: \", stringify!(rt_metrics), \"::\", stringify!(rmx_mtu))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmx_refcnt) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_metrics),\n            \"::\",\n            stringify!(rmx_refcnt)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmx_hopcount) as usize - ptr as usize },\n        28usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_metrics),\n            \"::\",\n            stringify!(rmx_hopcount)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmx_recvpipe) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_metrics),\n            \"::\",\n            stringify!(rmx_recvpipe)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmx_sendpipe) as usize - ptr as usize },\n        36usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_metrics),\n            \"::\",\n            stringify!(rmx_sendpipe)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmx_ssthresh) as usize - ptr as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_metrics),\n            \"::\",\n            stringify!(rmx_ssthresh)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmx_rtt) as usize - ptr as usize },\n        44usize,\n        concat!(\"Offset of field: \", stringify!(rt_metrics), \"::\", stringify!(rmx_rtt))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmx_rttvar) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_metrics),\n            \"::\",\n            stringify!(rmx_rttvar)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rmx_pad) as usize - ptr as usize },\n        52usize,\n        concat!(\"Offset of field: \", stringify!(rt_metrics), \"::\", stringify!(rmx_pad))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct rtstat {\n    pub rts_badredirect: u_int32_t,\n    pub rts_dynamic: u_int32_t,\n    pub rts_newgateway: u_int32_t,\n    pub rts_unreach: u_int32_t,\n    pub rts_wildcard: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_rtstat() {\n    const UNINIT: ::std::mem::MaybeUninit<rtstat> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<rtstat>(),\n        20usize,\n        concat!(\"Size of: \", stringify!(rtstat))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<rtstat>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(rtstat))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rts_badredirect) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rtstat),\n            \"::\",\n            stringify!(rts_badredirect)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rts_dynamic) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(rtstat), \"::\", stringify!(rts_dynamic))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rts_newgateway) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rtstat),\n            \"::\",\n            stringify!(rts_newgateway)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rts_unreach) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(rtstat), \"::\", stringify!(rts_unreach))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rts_wildcard) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(rtstat), \"::\", stringify!(rts_wildcard))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct rt_tableinfo {\n    pub rti_tableid: u_short,\n    pub rti_domainid: u_short,\n}\n#[test]\nfn bindgen_test_layout_rt_tableinfo() {\n    const UNINIT: ::std::mem::MaybeUninit<rt_tableinfo> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<rt_tableinfo>(),\n        4usize,\n        concat!(\"Size of: \", stringify!(rt_tableinfo))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<rt_tableinfo>(),\n        2usize,\n        concat!(\"Alignment of \", stringify!(rt_tableinfo))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rti_tableid) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_tableinfo),\n            \"::\",\n            stringify!(rti_tableid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rti_domainid) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_tableinfo),\n            \"::\",\n            stringify!(rti_domainid)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct rt_msghdr {\n    pub rtm_msglen: u_short,\n    pub rtm_version: u_char,\n    pub rtm_type: u_char,\n    pub rtm_hdrlen: u_short,\n    pub rtm_index: u_short,\n    pub rtm_tableid: u_short,\n    pub rtm_priority: u_char,\n    pub rtm_mpls: u_char,\n    pub rtm_addrs: ::std::os::raw::c_int,\n    pub rtm_flags: ::std::os::raw::c_int,\n    pub rtm_fmask: ::std::os::raw::c_int,\n    pub rtm_pid: pid_t,\n    pub rtm_seq: ::std::os::raw::c_int,\n    pub rtm_errno: ::std::os::raw::c_int,\n    pub rtm_inits: u_int,\n    pub rtm_rmx: rt_metrics,\n}\n#[test]\nfn bindgen_test_layout_rt_msghdr() {\n    const UNINIT: ::std::mem::MaybeUninit<rt_msghdr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<rt_msghdr>(),\n        96usize,\n        concat!(\"Size of: \", stringify!(rt_msghdr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<rt_msghdr>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(rt_msghdr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_msglen) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr), \"::\", stringify!(rtm_msglen))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_version) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_msghdr),\n            \"::\",\n            stringify!(rtm_version)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_type) as usize - ptr as usize },\n        3usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr), \"::\", stringify!(rtm_type))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_hdrlen) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr), \"::\", stringify!(rtm_hdrlen))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_index) as usize - ptr as usize },\n        6usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr), \"::\", stringify!(rtm_index))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_tableid) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_msghdr),\n            \"::\",\n            stringify!(rtm_tableid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_priority) as usize - ptr as usize },\n        10usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_msghdr),\n            \"::\",\n            stringify!(rtm_priority)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_mpls) as usize - ptr as usize },\n        11usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr), \"::\", stringify!(rtm_mpls))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_addrs) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr), \"::\", stringify!(rtm_addrs))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_flags) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr), \"::\", stringify!(rtm_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_fmask) as usize - ptr as usize },\n        20usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr), \"::\", stringify!(rtm_fmask))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_pid) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr), \"::\", stringify!(rtm_pid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_seq) as usize - ptr as usize },\n        28usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr), \"::\", stringify!(rtm_seq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_errno) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr), \"::\", stringify!(rtm_errno))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_inits) as usize - ptr as usize },\n        36usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr), \"::\", stringify!(rtm_inits))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtm_rmx) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(rt_msghdr), \"::\", stringify!(rtm_rmx))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sockaddr_rtlabel {\n    pub sr_len: u_int8_t,\n    pub sr_family: sa_family_t,\n    pub sr_label: [::std::os::raw::c_char; 32usize],\n}\n#[test]\nfn bindgen_test_layout_sockaddr_rtlabel() {\n    const UNINIT: ::std::mem::MaybeUninit<sockaddr_rtlabel> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sockaddr_rtlabel>(),\n        34usize,\n        concat!(\"Size of: \", stringify!(sockaddr_rtlabel))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sockaddr_rtlabel>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(sockaddr_rtlabel))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sr_len) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_rtlabel),\n            \"::\",\n            stringify!(sr_len)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sr_family) as usize - ptr as usize },\n        1usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_rtlabel),\n            \"::\",\n            stringify!(sr_family)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sr_label) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_rtlabel),\n            \"::\",\n            stringify!(sr_label)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sockaddr_rtdns {\n    pub sr_len: u_int8_t,\n    pub sr_family: sa_family_t,\n    pub sr_dns: [::std::os::raw::c_char; 128usize],\n}\n#[test]\nfn bindgen_test_layout_sockaddr_rtdns() {\n    const UNINIT: ::std::mem::MaybeUninit<sockaddr_rtdns> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sockaddr_rtdns>(),\n        130usize,\n        concat!(\"Size of: \", stringify!(sockaddr_rtdns))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sockaddr_rtdns>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(sockaddr_rtdns))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sr_len) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_rtdns),\n            \"::\",\n            stringify!(sr_len)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sr_family) as usize - ptr as usize },\n        1usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_rtdns),\n            \"::\",\n            stringify!(sr_family)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sr_dns) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_rtdns),\n            \"::\",\n            stringify!(sr_dns)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sockaddr_rtstatic {\n    pub sr_len: u_int8_t,\n    pub sr_family: sa_family_t,\n    pub sr_static: [::std::os::raw::c_char; 128usize],\n}\n#[test]\nfn bindgen_test_layout_sockaddr_rtstatic() {\n    const UNINIT: ::std::mem::MaybeUninit<sockaddr_rtstatic> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sockaddr_rtstatic>(),\n        130usize,\n        concat!(\"Size of: \", stringify!(sockaddr_rtstatic))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sockaddr_rtstatic>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(sockaddr_rtstatic))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sr_len) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_rtstatic),\n            \"::\",\n            stringify!(sr_len)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sr_family) as usize - ptr as usize },\n        1usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_rtstatic),\n            \"::\",\n            stringify!(sr_family)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sr_static) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_rtstatic),\n            \"::\",\n            stringify!(sr_static)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct sockaddr_rtsearch {\n    pub sr_len: u_int8_t,\n    pub sr_family: sa_family_t,\n    pub sr_search: [::std::os::raw::c_char; 128usize],\n}\n#[test]\nfn bindgen_test_layout_sockaddr_rtsearch() {\n    const UNINIT: ::std::mem::MaybeUninit<sockaddr_rtsearch> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<sockaddr_rtsearch>(),\n        130usize,\n        concat!(\"Size of: \", stringify!(sockaddr_rtsearch))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<sockaddr_rtsearch>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(sockaddr_rtsearch))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sr_len) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_rtsearch),\n            \"::\",\n            stringify!(sr_len)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sr_family) as usize - ptr as usize },\n        1usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_rtsearch),\n            \"::\",\n            stringify!(sr_family)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sr_search) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(sockaddr_rtsearch),\n            \"::\",\n            stringify!(sr_search)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct rt_addrinfo {\n    pub rti_addrs: ::std::os::raw::c_int,\n    pub rti_info: [*const sockaddr; 15usize],\n    pub rti_flags: ::std::os::raw::c_int,\n    pub rti_ifa: *mut ifaddr,\n    pub rti_rtm: *mut rt_msghdr,\n    pub rti_mpls: u_char,\n}\n#[test]\nfn bindgen_test_layout_rt_addrinfo() {\n    const UNINIT: ::std::mem::MaybeUninit<rt_addrinfo> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<rt_addrinfo>(),\n        160usize,\n        concat!(\"Size of: \", stringify!(rt_addrinfo))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<rt_addrinfo>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(rt_addrinfo))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rti_addrs) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_addrinfo),\n            \"::\",\n            stringify!(rti_addrs)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rti_info) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(rt_addrinfo), \"::\", stringify!(rti_info))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rti_flags) as usize - ptr as usize },\n        128usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(rt_addrinfo),\n            \"::\",\n            stringify!(rti_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rti_ifa) as usize - ptr as usize },\n        136usize,\n        concat!(\"Offset of field: \", stringify!(rt_addrinfo), \"::\", stringify!(rti_ifa))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rti_rtm) as usize - ptr as usize },\n        144usize,\n        concat!(\"Offset of field: \", stringify!(rt_addrinfo), \"::\", stringify!(rti_rtm))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rti_mpls) as usize - ptr as usize },\n        152usize,\n        concat!(\"Offset of field: \", stringify!(rt_addrinfo), \"::\", stringify!(rti_mpls))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct route {\n    pub ro_rt: *mut rtentry,\n    pub ro_generation: u_long,\n    pub ro_tableid: u_long,\n    pub __bindgen_anon_1: route__bindgen_ty_1,\n    pub __bindgen_anon_2: route__bindgen_ty_2,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union route__bindgen_ty_1 {\n    pub ro_dstsa: sockaddr,\n    pub ro_dstsin: sockaddr_in,\n    pub ro_dstsin6: sockaddr_in6,\n}\n#[test]\nfn bindgen_test_layout_route__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<route__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<route__bindgen_ty_1>(),\n        28usize,\n        concat!(\"Size of: \", stringify!(route__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<route__bindgen_ty_1>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(route__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ro_dstsa) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(route__bindgen_ty_1),\n            \"::\",\n            stringify!(ro_dstsa)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ro_dstsin) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(route__bindgen_ty_1),\n            \"::\",\n            stringify!(ro_dstsin)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ro_dstsin6) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(route__bindgen_ty_1),\n            \"::\",\n            stringify!(ro_dstsin6)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union route__bindgen_ty_2 {\n    pub ro_srcin: in_addr,\n    pub ro_srcin6: in6_addr,\n}\n#[test]\nfn bindgen_test_layout_route__bindgen_ty_2() {\n    const UNINIT: ::std::mem::MaybeUninit<route__bindgen_ty_2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<route__bindgen_ty_2>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(route__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<route__bindgen_ty_2>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(route__bindgen_ty_2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ro_srcin) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(route__bindgen_ty_2),\n            \"::\",\n            stringify!(ro_srcin)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ro_srcin6) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(route__bindgen_ty_2),\n            \"::\",\n            stringify!(ro_srcin6)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_route() {\n    const UNINIT: ::std::mem::MaybeUninit<route> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<route>(),\n        72usize,\n        concat!(\"Size of: \", stringify!(route))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<route>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(route))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ro_rt) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(route), \"::\", stringify!(ro_rt))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ro_generation) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(route), \"::\", stringify!(ro_generation))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ro_tableid) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(route), \"::\", stringify!(ro_tableid))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ip {\n    _unused: [u8; 0],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ip6_hdr {\n    _unused: [u8; 0],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct mbuf_list {\n    _unused: [u8; 0],\n}\npub type pf_refcnt_t = refcnt;\npub const PF_INOUT: _bindgen_ty_1 = 0;\npub const PF_IN: _bindgen_ty_1 = 1;\npub const PF_OUT: _bindgen_ty_1 = 2;\npub const PF_FWD: _bindgen_ty_1 = 3;\npub type _bindgen_ty_1 = ::std::os::raw::c_uint;\npub const PF_PASS: _bindgen_ty_2 = 0;\npub const PF_DROP: _bindgen_ty_2 = 1;\npub const PF_SCRUB: _bindgen_ty_2 = 2;\npub const PF_NOSCRUB: _bindgen_ty_2 = 3;\npub const PF_NAT: _bindgen_ty_2 = 4;\npub const PF_NONAT: _bindgen_ty_2 = 5;\npub const PF_BINAT: _bindgen_ty_2 = 6;\npub const PF_NOBINAT: _bindgen_ty_2 = 7;\npub const PF_RDR: _bindgen_ty_2 = 8;\npub const PF_NORDR: _bindgen_ty_2 = 9;\npub const PF_SYNPROXY_DROP: _bindgen_ty_2 = 10;\npub const PF_DEFER: _bindgen_ty_2 = 11;\npub const PF_MATCH: _bindgen_ty_2 = 12;\npub const PF_DIVERT: _bindgen_ty_2 = 13;\npub const PF_RT: _bindgen_ty_2 = 14;\npub const PF_AFRT: _bindgen_ty_2 = 15;\npub type _bindgen_ty_2 = ::std::os::raw::c_uint;\npub const PF_TRANS_RULESET: _bindgen_ty_3 = 0;\npub const PF_TRANS_TABLE: _bindgen_ty_3 = 1;\npub type _bindgen_ty_3 = ::std::os::raw::c_uint;\npub const PF_OP_NONE: _bindgen_ty_4 = 0;\npub const PF_OP_IRG: _bindgen_ty_4 = 1;\npub const PF_OP_EQ: _bindgen_ty_4 = 2;\npub const PF_OP_NE: _bindgen_ty_4 = 3;\npub const PF_OP_LT: _bindgen_ty_4 = 4;\npub const PF_OP_LE: _bindgen_ty_4 = 5;\npub const PF_OP_GT: _bindgen_ty_4 = 6;\npub const PF_OP_GE: _bindgen_ty_4 = 7;\npub const PF_OP_XRG: _bindgen_ty_4 = 8;\npub const PF_OP_RRG: _bindgen_ty_4 = 9;\npub type _bindgen_ty_4 = ::std::os::raw::c_uint;\npub const PF_CHANGE_NONE: _bindgen_ty_5 = 0;\npub const PF_CHANGE_ADD_HEAD: _bindgen_ty_5 = 1;\npub const PF_CHANGE_ADD_TAIL: _bindgen_ty_5 = 2;\npub const PF_CHANGE_ADD_BEFORE: _bindgen_ty_5 = 3;\npub const PF_CHANGE_ADD_AFTER: _bindgen_ty_5 = 4;\npub const PF_CHANGE_REMOVE: _bindgen_ty_5 = 5;\npub const PF_CHANGE_GET_TICKET: _bindgen_ty_5 = 6;\npub type _bindgen_ty_5 = ::std::os::raw::c_uint;\npub const PF_GET_NONE: _bindgen_ty_6 = 0;\npub const PF_GET_CLR_CNTR: _bindgen_ty_6 = 1;\npub type _bindgen_ty_6 = ::std::os::raw::c_uint;\npub const PF_SK_WIRE: _bindgen_ty_7 = 0;\npub const PF_SK_STACK: _bindgen_ty_7 = 1;\npub const PF_SK_BOTH: _bindgen_ty_7 = 2;\npub type _bindgen_ty_7 = ::std::os::raw::c_uint;\npub const PF_PEER_SRC: _bindgen_ty_8 = 0;\npub const PF_PEER_DST: _bindgen_ty_8 = 1;\npub const PF_PEER_BOTH: _bindgen_ty_8 = 2;\npub type _bindgen_ty_8 = ::std::os::raw::c_uint;\npub const PFTM_TCP_FIRST_PACKET: _bindgen_ty_9 = 0;\npub const PFTM_TCP_OPENING: _bindgen_ty_9 = 1;\npub const PFTM_TCP_ESTABLISHED: _bindgen_ty_9 = 2;\npub const PFTM_TCP_CLOSING: _bindgen_ty_9 = 3;\npub const PFTM_TCP_FIN_WAIT: _bindgen_ty_9 = 4;\npub const PFTM_TCP_CLOSED: _bindgen_ty_9 = 5;\npub const PFTM_UDP_FIRST_PACKET: _bindgen_ty_9 = 6;\npub const PFTM_UDP_SINGLE: _bindgen_ty_9 = 7;\npub const PFTM_UDP_MULTIPLE: _bindgen_ty_9 = 8;\npub const PFTM_ICMP_FIRST_PACKET: _bindgen_ty_9 = 9;\npub const PFTM_ICMP_ERROR_REPLY: _bindgen_ty_9 = 10;\npub const PFTM_OTHER_FIRST_PACKET: _bindgen_ty_9 = 11;\npub const PFTM_OTHER_SINGLE: _bindgen_ty_9 = 12;\npub const PFTM_OTHER_MULTIPLE: _bindgen_ty_9 = 13;\npub const PFTM_FRAG: _bindgen_ty_9 = 14;\npub const PFTM_INTERVAL: _bindgen_ty_9 = 15;\npub const PFTM_ADAPTIVE_START: _bindgen_ty_9 = 16;\npub const PFTM_ADAPTIVE_END: _bindgen_ty_9 = 17;\npub const PFTM_SRC_NODE: _bindgen_ty_9 = 18;\npub const PFTM_TS_DIFF: _bindgen_ty_9 = 19;\npub const PFTM_MAX: _bindgen_ty_9 = 20;\npub const PFTM_PURGE: _bindgen_ty_9 = 21;\npub const PFTM_UNLINKED: _bindgen_ty_9 = 22;\npub type _bindgen_ty_9 = ::std::os::raw::c_uint;\npub const PF_NOPFROUTE: _bindgen_ty_10 = 0;\npub const PF_ROUTETO: _bindgen_ty_10 = 1;\npub const PF_DUPTO: _bindgen_ty_10 = 2;\npub const PF_REPLYTO: _bindgen_ty_10 = 3;\npub type _bindgen_ty_10 = ::std::os::raw::c_uint;\npub const PF_LIMIT_STATES: _bindgen_ty_11 = 0;\npub const PF_LIMIT_SRC_NODES: _bindgen_ty_11 = 1;\npub const PF_LIMIT_FRAGS: _bindgen_ty_11 = 2;\npub const PF_LIMIT_TABLES: _bindgen_ty_11 = 3;\npub const PF_LIMIT_TABLE_ENTRIES: _bindgen_ty_11 = 4;\npub const PF_LIMIT_PKTDELAY_PKTS: _bindgen_ty_11 = 5;\npub const PF_LIMIT_ANCHORS: _bindgen_ty_11 = 6;\npub const PF_LIMIT_MAX: _bindgen_ty_11 = 7;\npub type _bindgen_ty_11 = ::std::os::raw::c_uint;\npub const PF_POOL_NONE: _bindgen_ty_12 = 0;\npub const PF_POOL_BITMASK: _bindgen_ty_12 = 1;\npub const PF_POOL_RANDOM: _bindgen_ty_12 = 2;\npub const PF_POOL_SRCHASH: _bindgen_ty_12 = 3;\npub const PF_POOL_ROUNDROBIN: _bindgen_ty_12 = 4;\npub const PF_POOL_LEASTSTATES: _bindgen_ty_12 = 5;\npub type _bindgen_ty_12 = ::std::os::raw::c_uint;\npub const PF_ADDR_ADDRMASK: _bindgen_ty_13 = 0;\npub const PF_ADDR_NOROUTE: _bindgen_ty_13 = 1;\npub const PF_ADDR_DYNIFTL: _bindgen_ty_13 = 2;\npub const PF_ADDR_TABLE: _bindgen_ty_13 = 3;\npub const PF_ADDR_RTLABEL: _bindgen_ty_13 = 4;\npub const PF_ADDR_URPFFAILED: _bindgen_ty_13 = 5;\npub const PF_ADDR_RANGE: _bindgen_ty_13 = 6;\npub const PF_ADDR_NONE: _bindgen_ty_13 = 7;\npub type _bindgen_ty_13 = ::std::os::raw::c_uint;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_addr {\n    pub pfa: pf_addr__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pf_addr__bindgen_ty_1 {\n    pub v4: in_addr,\n    pub v6: in6_addr,\n    pub addr8: [u_int8_t; 16usize],\n    pub addr16: [u_int16_t; 8usize],\n    pub addr32: [u_int32_t; 4usize],\n}\n#[test]\nfn bindgen_test_layout_pf_addr__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_addr__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_addr__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_addr__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_addr__bindgen_ty_1>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_addr__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).v4) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(v4)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).v6) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(v6)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr8) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(addr8)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr16) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(addr16)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr32) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(addr32)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_addr() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_addr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_addr>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_addr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_addr>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfa) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_addr), \"::\", stringify!(pfa))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_addr_wrap {\n    pub v: pf_addr_wrap__bindgen_ty_1,\n    pub p: pf_addr_wrap__bindgen_ty_2,\n    pub type_: u_int8_t,\n    pub iflags: u_int8_t,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pf_addr_wrap__bindgen_ty_1 {\n    pub a: pf_addr_wrap__bindgen_ty_1__bindgen_ty_1,\n    pub ifname: [::std::os::raw::c_char; 16usize],\n    pub tblname: [::std::os::raw::c_char; 32usize],\n    pub rtlabelname: [::std::os::raw::c_char; 32usize],\n    pub rtlabel: u_int32_t,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_addr_wrap__bindgen_ty_1__bindgen_ty_1 {\n    pub addr: pf_addr,\n    pub mask: pf_addr,\n}\n#[test]\nfn bindgen_test_layout_pf_addr_wrap__bindgen_ty_1__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_addr_wrap__bindgen_ty_1__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_addr_wrap__bindgen_ty_1__bindgen_ty_1>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(pf_addr_wrap__bindgen_ty_1__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_addr_wrap__bindgen_ty_1__bindgen_ty_1>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_addr_wrap__bindgen_ty_1__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mask) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(mask)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_addr_wrap__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_addr_wrap__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_addr_wrap__bindgen_ty_1>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(pf_addr_wrap__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_addr_wrap__bindgen_ty_1>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_addr_wrap__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_1),\n            \"::\",\n            stringify!(a)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifname) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_1),\n            \"::\",\n            stringify!(ifname)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tblname) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_1),\n            \"::\",\n            stringify!(tblname)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtlabelname) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_1),\n            \"::\",\n            stringify!(rtlabelname)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtlabel) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_1),\n            \"::\",\n            stringify!(rtlabel)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pf_addr_wrap__bindgen_ty_2 {\n    pub dyn_: *mut pfi_dynaddr,\n    pub tbl: *mut pfr_ktable,\n    pub dyncnt: ::std::os::raw::c_int,\n    pub tblcnt: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_pf_addr_wrap__bindgen_ty_2() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_addr_wrap__bindgen_ty_2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_addr_wrap__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_addr_wrap__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_addr_wrap__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_addr_wrap__bindgen_ty_2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dyn_) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_2),\n            \"::\",\n            stringify!(dyn_)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tbl) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_2),\n            \"::\",\n            stringify!(tbl)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dyncnt) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_2),\n            \"::\",\n            stringify!(dyncnt)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tblcnt) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_addr_wrap__bindgen_ty_2),\n            \"::\",\n            stringify!(tblcnt)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_addr_wrap() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_addr_wrap> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_addr_wrap>(),\n        48usize,\n        concat!(\"Size of: \", stringify!(pf_addr_wrap))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_addr_wrap>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_addr_wrap))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).v) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_addr_wrap), \"::\", stringify!(v))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).p) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(pf_addr_wrap), \"::\", stringify!(p))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).type_) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(pf_addr_wrap), \"::\", stringify!(type_))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).iflags) as usize - ptr as usize },\n        41usize,\n        concat!(\"Offset of field: \", stringify!(pf_addr_wrap), \"::\", stringify!(iflags))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_rule_uid {\n    pub uid: [uid_t; 2usize],\n    pub op: u_int8_t,\n}\n#[test]\nfn bindgen_test_layout_pf_rule_uid() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rule_uid> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rule_uid>(),\n        12usize,\n        concat!(\"Size of: \", stringify!(pf_rule_uid))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rule_uid>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_rule_uid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uid) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_uid), \"::\", stringify!(uid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).op) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_uid), \"::\", stringify!(op))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_rule_gid {\n    pub gid: [uid_t; 2usize],\n    pub op: u_int8_t,\n}\n#[test]\nfn bindgen_test_layout_pf_rule_gid() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rule_gid> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rule_gid>(),\n        12usize,\n        concat!(\"Size of: \", stringify!(pf_rule_gid))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rule_gid>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_rule_gid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).gid) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_gid), \"::\", stringify!(gid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).op) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_gid), \"::\", stringify!(op))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_rule_addr {\n    pub addr: pf_addr_wrap,\n    pub port: [u_int16_t; 2usize],\n    pub neg: u_int8_t,\n    pub port_op: u_int8_t,\n    pub weight: u_int16_t,\n}\n#[test]\nfn bindgen_test_layout_pf_rule_addr() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rule_addr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rule_addr>(),\n        56usize,\n        concat!(\"Size of: \", stringify!(pf_rule_addr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rule_addr>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_rule_addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_addr), \"::\", stringify!(addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).port) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_addr), \"::\", stringify!(port))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).neg) as usize - ptr as usize },\n        52usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_addr), \"::\", stringify!(neg))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).port_op) as usize - ptr as usize },\n        53usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_addr), \"::\", stringify!(port_op))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).weight) as usize - ptr as usize },\n        54usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_addr), \"::\", stringify!(weight))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_threshold {\n    pub limit: u_int32_t,\n    pub seconds: u_int32_t,\n    pub count: u_int32_t,\n    pub last: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_pf_threshold() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_threshold> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_threshold>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_threshold))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_threshold>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_threshold))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).limit) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_threshold), \"::\", stringify!(limit))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).seconds) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(pf_threshold), \"::\", stringify!(seconds))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).count) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pf_threshold), \"::\", stringify!(count))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).last) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(pf_threshold), \"::\", stringify!(last))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_poolhashkey {\n    pub pfk: pf_poolhashkey__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pf_poolhashkey__bindgen_ty_1 {\n    pub key8: [u_int8_t; 16usize],\n    pub key16: [u_int16_t; 8usize],\n    pub key32: [u_int32_t; 4usize],\n}\n#[test]\nfn bindgen_test_layout_pf_poolhashkey__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_poolhashkey__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_poolhashkey__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_poolhashkey__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_poolhashkey__bindgen_ty_1>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_poolhashkey__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).key8) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_poolhashkey__bindgen_ty_1),\n            \"::\",\n            stringify!(key8)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).key16) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_poolhashkey__bindgen_ty_1),\n            \"::\",\n            stringify!(key16)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).key32) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_poolhashkey__bindgen_ty_1),\n            \"::\",\n            stringify!(key32)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_poolhashkey() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_poolhashkey> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_poolhashkey>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_poolhashkey))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_poolhashkey>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_poolhashkey))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfk) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_poolhashkey), \"::\", stringify!(pfk))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_pool {\n    pub addr: pf_addr_wrap,\n    pub key: pf_poolhashkey,\n    pub counter: pf_addr,\n    pub ifname: [::std::os::raw::c_char; 16usize],\n    pub kif: *mut pfi_kif,\n    pub tblidx: ::std::os::raw::c_int,\n    pub states: u_int64_t,\n    pub curweight: ::std::os::raw::c_int,\n    pub weight: u_int16_t,\n    pub proxy_port: [u_int16_t; 2usize],\n    pub port_op: u_int8_t,\n    pub opts: u_int8_t,\n}\n#[test]\nfn bindgen_test_layout_pf_pool() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_pool> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_pool>(),\n        136usize,\n        concat!(\"Size of: \", stringify!(pf_pool))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_pool>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_pool))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_pool), \"::\", stringify!(addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).key) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(pf_pool), \"::\", stringify!(key))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).counter) as usize - ptr as usize },\n        64usize,\n        concat!(\"Offset of field: \", stringify!(pf_pool), \"::\", stringify!(counter))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifname) as usize - ptr as usize },\n        80usize,\n        concat!(\"Offset of field: \", stringify!(pf_pool), \"::\", stringify!(ifname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).kif) as usize - ptr as usize },\n        96usize,\n        concat!(\"Offset of field: \", stringify!(pf_pool), \"::\", stringify!(kif))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tblidx) as usize - ptr as usize },\n        104usize,\n        concat!(\"Offset of field: \", stringify!(pf_pool), \"::\", stringify!(tblidx))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).states) as usize - ptr as usize },\n        112usize,\n        concat!(\"Offset of field: \", stringify!(pf_pool), \"::\", stringify!(states))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).curweight) as usize - ptr as usize },\n        120usize,\n        concat!(\"Offset of field: \", stringify!(pf_pool), \"::\", stringify!(curweight))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).weight) as usize - ptr as usize },\n        124usize,\n        concat!(\"Offset of field: \", stringify!(pf_pool), \"::\", stringify!(weight))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).proxy_port) as usize - ptr as usize },\n        126usize,\n        concat!(\"Offset of field: \", stringify!(pf_pool), \"::\", stringify!(proxy_port))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).port_op) as usize - ptr as usize },\n        130usize,\n        concat!(\"Offset of field: \", stringify!(pf_pool), \"::\", stringify!(port_op))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).opts) as usize - ptr as usize },\n        131usize,\n        concat!(\"Offset of field: \", stringify!(pf_pool), \"::\", stringify!(opts))\n    );\n}\npub type pf_osfp_t = u_int32_t;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_osfp_entry {\n    pub fp_entry: pf_osfp_entry__bindgen_ty_1,\n    pub fp_os: pf_osfp_t,\n    pub fp_enflags: ::std::os::raw::c_int,\n    pub fp_class_nm: [u_char; 32usize],\n    pub fp_version_nm: [u_char; 32usize],\n    pub fp_subtype_nm: [u_char; 32usize],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_osfp_entry__bindgen_ty_1 {\n    pub sle_next: *mut pf_osfp_entry,\n}\n#[test]\nfn bindgen_test_layout_pf_osfp_entry__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_osfp_entry__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_osfp_entry__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_osfp_entry__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_osfp_entry__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_osfp_entry__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sle_next) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_entry__bindgen_ty_1),\n            \"::\",\n            stringify!(sle_next)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_osfp_entry() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_osfp_entry> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_osfp_entry>(),\n        112usize,\n        concat!(\"Size of: \", stringify!(pf_osfp_entry))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_osfp_entry>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_osfp_entry))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_entry) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_entry),\n            \"::\",\n            stringify!(fp_entry)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_os) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pf_osfp_entry), \"::\", stringify!(fp_os))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_enflags) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_entry),\n            \"::\",\n            stringify!(fp_enflags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_class_nm) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_entry),\n            \"::\",\n            stringify!(fp_class_nm)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_version_nm) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_entry),\n            \"::\",\n            stringify!(fp_version_nm)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_subtype_nm) as usize - ptr as usize },\n        80usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_entry),\n            \"::\",\n            stringify!(fp_subtype_nm)\n        )\n    );\n}\npub type pf_tcpopts_t = u_int64_t;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_os_fingerprint {\n    pub fp_oses: pf_os_fingerprint_pf_osfp_enlist,\n    pub fp_tcpopts: pf_tcpopts_t,\n    pub fp_wsize: u_int16_t,\n    pub fp_psize: u_int16_t,\n    pub fp_mss: u_int16_t,\n    pub fp_flags: u_int16_t,\n    pub fp_optcnt: u_int8_t,\n    pub fp_wscale: u_int8_t,\n    pub fp_ttl: u_int8_t,\n    pub fp_next: pf_os_fingerprint__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_os_fingerprint_pf_osfp_enlist {\n    pub slh_first: *mut pf_osfp_entry,\n}\n#[test]\nfn bindgen_test_layout_pf_os_fingerprint_pf_osfp_enlist() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_os_fingerprint_pf_osfp_enlist> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_os_fingerprint_pf_osfp_enlist>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_os_fingerprint_pf_osfp_enlist))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_os_fingerprint_pf_osfp_enlist>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_os_fingerprint_pf_osfp_enlist))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).slh_first) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint_pf_osfp_enlist),\n            \"::\",\n            stringify!(slh_first)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_os_fingerprint__bindgen_ty_1 {\n    pub sle_next: *mut pf_os_fingerprint,\n}\n#[test]\nfn bindgen_test_layout_pf_os_fingerprint__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_os_fingerprint__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_os_fingerprint__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_os_fingerprint__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_os_fingerprint__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_os_fingerprint__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sle_next) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint__bindgen_ty_1),\n            \"::\",\n            stringify!(sle_next)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_os_fingerprint() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_os_fingerprint> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_os_fingerprint>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(pf_os_fingerprint))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_os_fingerprint>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_os_fingerprint))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_oses) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_oses)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_tcpopts) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_tcpopts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_wsize) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_wsize)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_psize) as usize - ptr as usize },\n        18usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_psize)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_mss) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_mss)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_flags) as usize - ptr as usize },\n        22usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_optcnt) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_optcnt)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_wscale) as usize - ptr as usize },\n        25usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_wscale)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_ttl) as usize - ptr as usize },\n        26usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_ttl)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_next) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_os_fingerprint),\n            \"::\",\n            stringify!(fp_next)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_osfp_ioctl {\n    pub fp_os: pf_osfp_entry,\n    pub fp_tcpopts: pf_tcpopts_t,\n    pub fp_wsize: u_int16_t,\n    pub fp_psize: u_int16_t,\n    pub fp_mss: u_int16_t,\n    pub fp_flags: u_int16_t,\n    pub fp_optcnt: u_int8_t,\n    pub fp_wscale: u_int8_t,\n    pub fp_ttl: u_int8_t,\n    pub fp_getnum: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_pf_osfp_ioctl() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_osfp_ioctl> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_osfp_ioctl>(),\n        136usize,\n        concat!(\"Size of: \", stringify!(pf_osfp_ioctl))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_osfp_ioctl>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_osfp_ioctl))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_os) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_osfp_ioctl), \"::\", stringify!(fp_os))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_tcpopts) as usize - ptr as usize },\n        112usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_ioctl),\n            \"::\",\n            stringify!(fp_tcpopts)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_wsize) as usize - ptr as usize },\n        120usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_ioctl),\n            \"::\",\n            stringify!(fp_wsize)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_psize) as usize - ptr as usize },\n        122usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_ioctl),\n            \"::\",\n            stringify!(fp_psize)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_mss) as usize - ptr as usize },\n        124usize,\n        concat!(\"Offset of field: \", stringify!(pf_osfp_ioctl), \"::\", stringify!(fp_mss))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_flags) as usize - ptr as usize },\n        126usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_ioctl),\n            \"::\",\n            stringify!(fp_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_optcnt) as usize - ptr as usize },\n        128usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_ioctl),\n            \"::\",\n            stringify!(fp_optcnt)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_wscale) as usize - ptr as usize },\n        129usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_ioctl),\n            \"::\",\n            stringify!(fp_wscale)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_ttl) as usize - ptr as usize },\n        130usize,\n        concat!(\"Offset of field: \", stringify!(pf_osfp_ioctl), \"::\", stringify!(fp_ttl))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_getnum) as usize - ptr as usize },\n        132usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_osfp_ioctl),\n            \"::\",\n            stringify!(fp_getnum)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_rule_actions {\n    pub rtableid: ::std::os::raw::c_int,\n    pub qid: u_int16_t,\n    pub pqid: u_int16_t,\n    pub max_mss: u_int16_t,\n    pub flags: u_int16_t,\n    pub delay: u_int16_t,\n    pub log: u_int8_t,\n    pub set_tos: u_int8_t,\n    pub min_ttl: u_int8_t,\n    pub set_prio: [u_int8_t; 2usize],\n    pub pad: [u_int8_t; 1usize],\n}\n#[test]\nfn bindgen_test_layout_pf_rule_actions() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rule_actions> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rule_actions>(),\n        20usize,\n        concat!(\"Size of: \", stringify!(pf_rule_actions))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rule_actions>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_rule_actions))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtableid) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule_actions),\n            \"::\",\n            stringify!(rtableid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).qid) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_actions), \"::\", stringify!(qid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pqid) as usize - ptr as usize },\n        6usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_actions), \"::\", stringify!(pqid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_mss) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule_actions),\n            \"::\",\n            stringify!(max_mss)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flags) as usize - ptr as usize },\n        10usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule_actions),\n            \"::\",\n            stringify!(flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).delay) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule_actions),\n            \"::\",\n            stringify!(delay)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).log) as usize - ptr as usize },\n        14usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_actions), \"::\", stringify!(log))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).set_tos) as usize - ptr as usize },\n        15usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule_actions),\n            \"::\",\n            stringify!(set_tos)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).min_ttl) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule_actions),\n            \"::\",\n            stringify!(min_ttl)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).set_prio) as usize - ptr as usize },\n        17usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule_actions),\n            \"::\",\n            stringify!(set_prio)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pad) as usize - ptr as usize },\n        19usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_actions), \"::\", stringify!(pad))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pf_rule_ptr {\n    pub ptr: *mut pf_rule,\n    pub nr: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_pf_rule_ptr() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rule_ptr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rule_ptr>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_rule_ptr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rule_ptr>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_rule_ptr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ptr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_ptr), \"::\", stringify!(ptr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_ptr), \"::\", stringify!(nr))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_rule {\n    pub src: pf_rule_addr,\n    pub dst: pf_rule_addr,\n    pub skip: [pf_rule_ptr; 9usize],\n    pub label: [::std::os::raw::c_char; 64usize],\n    pub ifname: [::std::os::raw::c_char; 16usize],\n    pub rcv_ifname: [::std::os::raw::c_char; 16usize],\n    pub qname: [::std::os::raw::c_char; 64usize],\n    pub pqname: [::std::os::raw::c_char; 64usize],\n    pub tagname: [::std::os::raw::c_char; 64usize],\n    pub match_tagname: [::std::os::raw::c_char; 64usize],\n    pub overload_tblname: [::std::os::raw::c_char; 32usize],\n    pub entries: pf_rule__bindgen_ty_1,\n    pub nat: pf_pool,\n    pub rdr: pf_pool,\n    pub route: pf_pool,\n    pub pktrate: pf_threshold,\n    pub evaluations: u_int64_t,\n    pub packets: [u_int64_t; 2usize],\n    pub bytes: [u_int64_t; 2usize],\n    pub kif: *mut pfi_kif,\n    pub rcv_kif: *mut pfi_kif,\n    pub anchor: *mut pf_anchor,\n    pub overload_tbl: *mut pfr_ktable,\n    pub os_fingerprint: pf_osfp_t,\n    pub rtableid: ::std::os::raw::c_int,\n    pub onrdomain: ::std::os::raw::c_int,\n    pub timeout: [u_int32_t; 20usize],\n    pub states_cur: u_int32_t,\n    pub states_tot: u_int32_t,\n    pub max_states: u_int32_t,\n    pub src_nodes: u_int32_t,\n    pub max_src_nodes: u_int32_t,\n    pub max_src_states: u_int32_t,\n    pub max_src_conn: u_int32_t,\n    pub max_src_conn_rate: pf_rule__bindgen_ty_2,\n    pub qid: u_int32_t,\n    pub pqid: u_int32_t,\n    pub rt_listid: u_int32_t,\n    pub nr: u_int32_t,\n    pub prob: u_int32_t,\n    pub cuid: uid_t,\n    pub cpid: pid_t,\n    pub return_icmp: u_int16_t,\n    pub return_icmp6: u_int16_t,\n    pub max_mss: u_int16_t,\n    pub tag: u_int16_t,\n    pub match_tag: u_int16_t,\n    pub scrub_flags: u_int16_t,\n    pub delay: u_int16_t,\n    pub uid: pf_rule_uid,\n    pub gid: pf_rule_gid,\n    pub rule_flag: u_int32_t,\n    pub action: u_int8_t,\n    pub direction: u_int8_t,\n    pub log: u_int8_t,\n    pub logif: u_int8_t,\n    pub quick: u_int8_t,\n    pub ifnot: u_int8_t,\n    pub match_tag_not: u_int8_t,\n    pub keep_state: u_int8_t,\n    pub af: sa_family_t,\n    pub proto: u_int8_t,\n    pub type_: u_int16_t,\n    pub code: u_int16_t,\n    pub flags: u_int8_t,\n    pub flagset: u_int8_t,\n    pub min_ttl: u_int8_t,\n    pub allow_opts: u_int8_t,\n    pub rt: u_int8_t,\n    pub return_ttl: u_int8_t,\n    pub tos: u_int8_t,\n    pub set_tos: u_int8_t,\n    pub anchor_relative: u_int8_t,\n    pub anchor_wildcard: u_int8_t,\n    pub flush: u_int8_t,\n    pub prio: u_int8_t,\n    pub set_prio: [u_int8_t; 2usize],\n    pub naf: sa_family_t,\n    pub rcvifnot: u_int8_t,\n    pub divert: pf_rule__bindgen_ty_3,\n    pub exptime: time_t,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_rule__bindgen_ty_1 {\n    pub tqe_next: *mut pf_rule,\n    pub tqe_prev: *mut *mut pf_rule,\n}\n#[test]\nfn bindgen_test_layout_pf_rule__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rule__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rule__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_rule__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rule__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_rule__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqe_next) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule__bindgen_ty_1),\n            \"::\",\n            stringify!(tqe_next)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqe_prev) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule__bindgen_ty_1),\n            \"::\",\n            stringify!(tqe_prev)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_rule__bindgen_ty_2 {\n    pub limit: u_int32_t,\n    pub seconds: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_pf_rule__bindgen_ty_2() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rule__bindgen_ty_2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rule__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_rule__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rule__bindgen_ty_2>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_rule__bindgen_ty_2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).limit) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule__bindgen_ty_2),\n            \"::\",\n            stringify!(limit)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).seconds) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule__bindgen_ty_2),\n            \"::\",\n            stringify!(seconds)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_rule__bindgen_ty_3 {\n    pub addr: pf_addr,\n    pub port: u_int16_t,\n    pub type_: u_int8_t,\n}\n#[test]\nfn bindgen_test_layout_pf_rule__bindgen_ty_3() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rule__bindgen_ty_3> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rule__bindgen_ty_3>(),\n        20usize,\n        concat!(\"Size of: \", stringify!(pf_rule__bindgen_ty_3))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rule__bindgen_ty_3>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_rule__bindgen_ty_3))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule__bindgen_ty_3),\n            \"::\",\n            stringify!(addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).port) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule__bindgen_ty_3),\n            \"::\",\n            stringify!(port)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).type_) as usize - ptr as usize },\n        18usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule__bindgen_ty_3),\n            \"::\",\n            stringify!(type_)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_rule() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rule> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rule>(),\n        1344usize,\n        concat!(\"Size of: \", stringify!(pf_rule))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rule>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_rule))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).src) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(src))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dst) as usize - ptr as usize },\n        56usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(dst))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).skip) as usize - ptr as usize },\n        112usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(skip))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).label) as usize - ptr as usize },\n        184usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(label))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifname) as usize - ptr as usize },\n        248usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(ifname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rcv_ifname) as usize - ptr as usize },\n        264usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(rcv_ifname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).qname) as usize - ptr as usize },\n        280usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(qname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pqname) as usize - ptr as usize },\n        344usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(pqname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tagname) as usize - ptr as usize },\n        408usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(tagname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).match_tagname) as usize - ptr as usize },\n        472usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule),\n            \"::\",\n            stringify!(match_tagname)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).overload_tblname) as usize - ptr as usize },\n        536usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule),\n            \"::\",\n            stringify!(overload_tblname)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).entries) as usize - ptr as usize },\n        568usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(entries))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nat) as usize - ptr as usize },\n        584usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(nat))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rdr) as usize - ptr as usize },\n        720usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(rdr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).route) as usize - ptr as usize },\n        856usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(route))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pktrate) as usize - ptr as usize },\n        992usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(pktrate))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).evaluations) as usize - ptr as usize },\n        1008usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(evaluations))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).packets) as usize - ptr as usize },\n        1016usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(packets))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).bytes) as usize - ptr as usize },\n        1032usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(bytes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).kif) as usize - ptr as usize },\n        1048usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(kif))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rcv_kif) as usize - ptr as usize },\n        1056usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(rcv_kif))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor) as usize - ptr as usize },\n        1064usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(anchor))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).overload_tbl) as usize - ptr as usize },\n        1072usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(overload_tbl))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).os_fingerprint) as usize - ptr as usize },\n        1080usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule),\n            \"::\",\n            stringify!(os_fingerprint)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtableid) as usize - ptr as usize },\n        1084usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(rtableid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).onrdomain) as usize - ptr as usize },\n        1088usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(onrdomain))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).timeout) as usize - ptr as usize },\n        1092usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(timeout))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).states_cur) as usize - ptr as usize },\n        1172usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(states_cur))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).states_tot) as usize - ptr as usize },\n        1176usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(states_tot))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_states) as usize - ptr as usize },\n        1180usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(max_states))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).src_nodes) as usize - ptr as usize },\n        1184usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(src_nodes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_src_nodes) as usize - ptr as usize },\n        1188usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule),\n            \"::\",\n            stringify!(max_src_nodes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_src_states) as usize - ptr as usize },\n        1192usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule),\n            \"::\",\n            stringify!(max_src_states)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_src_conn) as usize - ptr as usize },\n        1196usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(max_src_conn))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_src_conn_rate) as usize - ptr as usize },\n        1200usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule),\n            \"::\",\n            stringify!(max_src_conn_rate)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).qid) as usize - ptr as usize },\n        1208usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(qid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pqid) as usize - ptr as usize },\n        1212usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(pqid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rt_listid) as usize - ptr as usize },\n        1216usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(rt_listid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nr) as usize - ptr as usize },\n        1220usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(nr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).prob) as usize - ptr as usize },\n        1224usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(prob))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cuid) as usize - ptr as usize },\n        1228usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(cuid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).cpid) as usize - ptr as usize },\n        1232usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(cpid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).return_icmp) as usize - ptr as usize },\n        1236usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(return_icmp))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).return_icmp6) as usize - ptr as usize },\n        1238usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(return_icmp6))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_mss) as usize - ptr as usize },\n        1240usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(max_mss))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tag) as usize - ptr as usize },\n        1242usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(tag))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).match_tag) as usize - ptr as usize },\n        1244usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(match_tag))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scrub_flags) as usize - ptr as usize },\n        1246usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(scrub_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).delay) as usize - ptr as usize },\n        1248usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(delay))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).uid) as usize - ptr as usize },\n        1252usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(uid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).gid) as usize - ptr as usize },\n        1264usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(gid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rule_flag) as usize - ptr as usize },\n        1276usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(rule_flag))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).action) as usize - ptr as usize },\n        1280usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(action))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).direction) as usize - ptr as usize },\n        1281usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(direction))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).log) as usize - ptr as usize },\n        1282usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(log))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).logif) as usize - ptr as usize },\n        1283usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(logif))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).quick) as usize - ptr as usize },\n        1284usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(quick))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifnot) as usize - ptr as usize },\n        1285usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(ifnot))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).match_tag_not) as usize - ptr as usize },\n        1286usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule),\n            \"::\",\n            stringify!(match_tag_not)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).keep_state) as usize - ptr as usize },\n        1287usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(keep_state))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).af) as usize - ptr as usize },\n        1288usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(af))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).proto) as usize - ptr as usize },\n        1289usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(proto))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).type_) as usize - ptr as usize },\n        1290usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(type_))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).code) as usize - ptr as usize },\n        1292usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(code))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flags) as usize - ptr as usize },\n        1294usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flagset) as usize - ptr as usize },\n        1295usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(flagset))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).min_ttl) as usize - ptr as usize },\n        1296usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(min_ttl))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).allow_opts) as usize - ptr as usize },\n        1297usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(allow_opts))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rt) as usize - ptr as usize },\n        1298usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(rt))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).return_ttl) as usize - ptr as usize },\n        1299usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(return_ttl))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tos) as usize - ptr as usize },\n        1300usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(tos))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).set_tos) as usize - ptr as usize },\n        1301usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(set_tos))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor_relative) as usize - ptr as usize },\n        1302usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule),\n            \"::\",\n            stringify!(anchor_relative)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor_wildcard) as usize - ptr as usize },\n        1303usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule),\n            \"::\",\n            stringify!(anchor_wildcard)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flush) as usize - ptr as usize },\n        1304usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(flush))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).prio) as usize - ptr as usize },\n        1305usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(prio))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).set_prio) as usize - ptr as usize },\n        1306usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(set_prio))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).naf) as usize - ptr as usize },\n        1308usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(naf))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rcvifnot) as usize - ptr as usize },\n        1309usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(rcvifnot))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).divert) as usize - ptr as usize },\n        1312usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(divert))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).exptime) as usize - ptr as usize },\n        1336usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule), \"::\", stringify!(exptime))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_rule_item {\n    pub entry: pf_rule_item__bindgen_ty_1,\n    pub r: *mut pf_rule,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_rule_item__bindgen_ty_1 {\n    pub sle_next: *mut pf_rule_item,\n}\n#[test]\nfn bindgen_test_layout_pf_rule_item__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rule_item__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rule_item__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_rule_item__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rule_item__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_rule_item__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sle_next) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule_item__bindgen_ty_1),\n            \"::\",\n            stringify!(sle_next)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_rule_item() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rule_item> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rule_item>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_rule_item))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rule_item>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_rule_item))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).entry) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_item), \"::\", stringify!(entry))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).r) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pf_rule_item), \"::\", stringify!(r))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_rule_slist {\n    pub slh_first: *mut pf_rule_item,\n}\n#[test]\nfn bindgen_test_layout_pf_rule_slist() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rule_slist> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rule_slist>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_rule_slist))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rule_slist>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_rule_slist))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).slh_first) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rule_slist),\n            \"::\",\n            stringify!(slh_first)\n        )\n    );\n}\npub const pf_sn_types_PF_SN_NONE: pf_sn_types = 0;\npub const pf_sn_types_PF_SN_NAT: pf_sn_types = 1;\npub const pf_sn_types_PF_SN_RDR: pf_sn_types = 2;\npub const pf_sn_types_PF_SN_ROUTE: pf_sn_types = 3;\npub const pf_sn_types_PF_SN_MAX: pf_sn_types = 4;\npub type pf_sn_types = ::std::os::raw::c_uint;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_src_node {\n    pub entry: pf_src_node__bindgen_ty_1,\n    pub addr: pf_addr,\n    pub raddr: pf_addr,\n    pub rule: pf_rule_ptr,\n    pub kif: *mut pfi_kif,\n    pub bytes: [u_int64_t; 2usize],\n    pub packets: [u_int64_t; 2usize],\n    pub states: u_int32_t,\n    pub conn: u_int32_t,\n    pub conn_rate: pf_threshold,\n    pub creation: i32,\n    pub expire: i32,\n    pub af: sa_family_t,\n    pub naf: sa_family_t,\n    pub type_: u_int8_t,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_src_node__bindgen_ty_1 {\n    pub rbe_left: *mut pf_src_node,\n    pub rbe_right: *mut pf_src_node,\n    pub rbe_parent: *mut pf_src_node,\n    pub rbe_color: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_pf_src_node__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_src_node__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_src_node__bindgen_ty_1>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(pf_src_node__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_src_node__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_src_node__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_left) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_src_node__bindgen_ty_1),\n            \"::\",\n            stringify!(rbe_left)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_right) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_src_node__bindgen_ty_1),\n            \"::\",\n            stringify!(rbe_right)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_parent) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_src_node__bindgen_ty_1),\n            \"::\",\n            stringify!(rbe_parent)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_color) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_src_node__bindgen_ty_1),\n            \"::\",\n            stringify!(rbe_color)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_src_node() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_src_node> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_src_node>(),\n        152usize,\n        concat!(\"Size of: \", stringify!(pf_src_node))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_src_node>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_src_node))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).entry) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(entry))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).raddr) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(raddr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rule) as usize - ptr as usize },\n        64usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(rule))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).kif) as usize - ptr as usize },\n        72usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(kif))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).bytes) as usize - ptr as usize },\n        80usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(bytes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).packets) as usize - ptr as usize },\n        96usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(packets))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).states) as usize - ptr as usize },\n        112usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(states))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).conn) as usize - ptr as usize },\n        116usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(conn))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).conn_rate) as usize - ptr as usize },\n        120usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_src_node),\n            \"::\",\n            stringify!(conn_rate)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).creation) as usize - ptr as usize },\n        136usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(creation))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).expire) as usize - ptr as usize },\n        140usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(expire))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).af) as usize - ptr as usize },\n        144usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(af))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).naf) as usize - ptr as usize },\n        145usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(naf))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).type_) as usize - ptr as usize },\n        146usize,\n        concat!(\"Offset of field: \", stringify!(pf_src_node), \"::\", stringify!(type_))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_sn_item {\n    pub next: pf_sn_item__bindgen_ty_1,\n    pub sn: *mut pf_src_node,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_sn_item__bindgen_ty_1 {\n    pub sle_next: *mut pf_sn_item,\n}\n#[test]\nfn bindgen_test_layout_pf_sn_item__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_sn_item__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_sn_item__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_sn_item__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_sn_item__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_sn_item__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sle_next) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_sn_item__bindgen_ty_1),\n            \"::\",\n            stringify!(sle_next)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_sn_item() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_sn_item> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_sn_item>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_sn_item))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_sn_item>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_sn_item))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).next) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_sn_item), \"::\", stringify!(next))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sn) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pf_sn_item), \"::\", stringify!(sn))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_sn_head {\n    pub slh_first: *mut pf_sn_item,\n}\n#[test]\nfn bindgen_test_layout_pf_sn_head() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_sn_head> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_sn_head>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_sn_head))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_sn_head>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_sn_head))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).slh_first) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_sn_head), \"::\", stringify!(slh_first))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_state_scrub {\n    pub pfss_last: timeval,\n    pub pfss_tsecr: u_int32_t,\n    pub pfss_tsval: u_int32_t,\n    pub pfss_tsval0: u_int32_t,\n    pub pfss_flags: u_int16_t,\n    pub pfss_ttl: u_int8_t,\n    pub pad: u_int8_t,\n    pub pfss_ts_mod: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_pf_state_scrub() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_state_scrub> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_state_scrub>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(pf_state_scrub))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_state_scrub>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_state_scrub))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfss_last) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_scrub),\n            \"::\",\n            stringify!(pfss_last)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfss_tsecr) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_scrub),\n            \"::\",\n            stringify!(pfss_tsecr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfss_tsval) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_scrub),\n            \"::\",\n            stringify!(pfss_tsval)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfss_tsval0) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_scrub),\n            \"::\",\n            stringify!(pfss_tsval0)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfss_flags) as usize - ptr as usize },\n        28usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_scrub),\n            \"::\",\n            stringify!(pfss_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfss_ttl) as usize - ptr as usize },\n        30usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_scrub),\n            \"::\",\n            stringify!(pfss_ttl)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pad) as usize - ptr as usize },\n        31usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_scrub), \"::\", stringify!(pad))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfss_ts_mod) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_scrub),\n            \"::\",\n            stringify!(pfss_ts_mod)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_state_host {\n    pub addr: pf_addr,\n    pub port: u_int16_t,\n    pub pad: u_int16_t,\n}\n#[test]\nfn bindgen_test_layout_pf_state_host() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_state_host> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_state_host>(),\n        20usize,\n        concat!(\"Size of: \", stringify!(pf_state_host))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_state_host>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_state_host))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_host), \"::\", stringify!(addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).port) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_host), \"::\", stringify!(port))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pad) as usize - ptr as usize },\n        18usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_host), \"::\", stringify!(pad))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_state_peer {\n    pub scrub: *mut pf_state_scrub,\n    pub seqlo: u_int32_t,\n    pub seqhi: u_int32_t,\n    pub seqdiff: u_int32_t,\n    pub max_win: u_int16_t,\n    pub mss: u_int16_t,\n    pub state: u_int8_t,\n    pub wscale: u_int8_t,\n    pub tcp_est: u_int8_t,\n    pub pad: [u_int8_t; 1usize],\n}\n#[test]\nfn bindgen_test_layout_pf_state_peer() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_state_peer> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_state_peer>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(pf_state_peer))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_state_peer>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_state_peer))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scrub) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_peer), \"::\", stringify!(scrub))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).seqlo) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_peer), \"::\", stringify!(seqlo))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).seqhi) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_peer), \"::\", stringify!(seqhi))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).seqdiff) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_peer),\n            \"::\",\n            stringify!(seqdiff)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_win) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_peer),\n            \"::\",\n            stringify!(max_win)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mss) as usize - ptr as usize },\n        22usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_peer), \"::\", stringify!(mss))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).state) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_peer), \"::\", stringify!(state))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).wscale) as usize - ptr as usize },\n        25usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_peer), \"::\", stringify!(wscale))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tcp_est) as usize - ptr as usize },\n        26usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_peer),\n            \"::\",\n            stringify!(tcp_est)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pad) as usize - ptr as usize },\n        27usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_peer), \"::\", stringify!(pad))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_state_queue {\n    pub tqh_first: *mut pf_state,\n    pub tqh_last: *mut *mut pf_state,\n}\n#[test]\nfn bindgen_test_layout_pf_state_queue() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_state_queue> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_state_queue>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_state_queue))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_state_queue>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_state_queue))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqh_first) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_queue),\n            \"::\",\n            stringify!(tqh_first)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqh_last) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_queue),\n            \"::\",\n            stringify!(tqh_last)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_state_key_cmp {\n    pub addr: [pf_addr; 2usize],\n    pub port: [u_int16_t; 2usize],\n    pub rdomain: u_int16_t,\n    pub hash: u_int16_t,\n    pub af: sa_family_t,\n    pub proto: u_int8_t,\n}\n#[test]\nfn bindgen_test_layout_pf_state_key_cmp() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_state_key_cmp> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_state_key_cmp>(),\n        44usize,\n        concat!(\"Size of: \", stringify!(pf_state_key_cmp))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_state_key_cmp>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_state_key_cmp))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_key_cmp),\n            \"::\",\n            stringify!(addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).port) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_key_cmp),\n            \"::\",\n            stringify!(port)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rdomain) as usize - ptr as usize },\n        36usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_key_cmp),\n            \"::\",\n            stringify!(rdomain)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).hash) as usize - ptr as usize },\n        38usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_key_cmp),\n            \"::\",\n            stringify!(hash)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).af) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_key_cmp), \"::\", stringify!(af))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).proto) as usize - ptr as usize },\n        41usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_key_cmp),\n            \"::\",\n            stringify!(proto)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_state_cmp {\n    pub id: u_int64_t,\n    pub creatorid: u_int32_t,\n    pub direction: u_int8_t,\n    pub pad: [u_int8_t; 3usize],\n}\n#[test]\nfn bindgen_test_layout_pf_state_cmp() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_state_cmp> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_state_cmp>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_state_cmp))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_state_cmp>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_state_cmp))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).id) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_cmp), \"::\", stringify!(id))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).creatorid) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_cmp),\n            \"::\",\n            stringify!(creatorid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).direction) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_cmp),\n            \"::\",\n            stringify!(direction)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pad) as usize - ptr as usize },\n        13usize,\n        concat!(\"Offset of field: \", stringify!(pf_state_cmp), \"::\", stringify!(pad))\n    );\n}\n#[repr(C, packed)]\n#[derive(Debug, Copy, Clone)]\npub struct pfsync_state_scrub {\n    pub pfss_flags: u_int16_t,\n    pub pfss_ttl: u_int8_t,\n    pub scrub_flag: u_int8_t,\n    pub pfss_ts_mod: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_pfsync_state_scrub() {\n    const UNINIT: ::std::mem::MaybeUninit<pfsync_state_scrub> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfsync_state_scrub>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pfsync_state_scrub))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfsync_state_scrub>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(pfsync_state_scrub))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfss_flags) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_scrub),\n            \"::\",\n            stringify!(pfss_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfss_ttl) as usize - ptr as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_scrub),\n            \"::\",\n            stringify!(pfss_ttl)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scrub_flag) as usize - ptr as usize },\n        3usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_scrub),\n            \"::\",\n            stringify!(scrub_flag)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfss_ts_mod) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_scrub),\n            \"::\",\n            stringify!(pfss_ts_mod)\n        )\n    );\n}\n#[repr(C, packed)]\n#[derive(Debug, Copy, Clone)]\npub struct pfsync_state_peer {\n    pub scrub: pfsync_state_scrub,\n    pub seqlo: u_int32_t,\n    pub seqhi: u_int32_t,\n    pub seqdiff: u_int32_t,\n    pub max_win: u_int16_t,\n    pub mss: u_int16_t,\n    pub state: u_int8_t,\n    pub wscale: u_int8_t,\n    pub pad: [u_int8_t; 6usize],\n}\n#[test]\nfn bindgen_test_layout_pfsync_state_peer() {\n    const UNINIT: ::std::mem::MaybeUninit<pfsync_state_peer> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfsync_state_peer>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(pfsync_state_peer))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfsync_state_peer>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(pfsync_state_peer))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scrub) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_peer),\n            \"::\",\n            stringify!(scrub)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).seqlo) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_peer),\n            \"::\",\n            stringify!(seqlo)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).seqhi) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_peer),\n            \"::\",\n            stringify!(seqhi)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).seqdiff) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_peer),\n            \"::\",\n            stringify!(seqdiff)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_win) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_peer),\n            \"::\",\n            stringify!(max_win)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).mss) as usize - ptr as usize },\n        22usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_peer),\n            \"::\",\n            stringify!(mss)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).state) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_peer),\n            \"::\",\n            stringify!(state)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).wscale) as usize - ptr as usize },\n        25usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_peer),\n            \"::\",\n            stringify!(wscale)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pad) as usize - ptr as usize },\n        26usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_peer),\n            \"::\",\n            stringify!(pad)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfsync_state_key {\n    pub addr: [pf_addr; 2usize],\n    pub port: [u_int16_t; 2usize],\n    pub rdomain: u_int16_t,\n    pub af: sa_family_t,\n    pub pad: u_int8_t,\n}\n#[test]\nfn bindgen_test_layout_pfsync_state_key() {\n    const UNINIT: ::std::mem::MaybeUninit<pfsync_state_key> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfsync_state_key>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(pfsync_state_key))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfsync_state_key>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pfsync_state_key))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_key),\n            \"::\",\n            stringify!(addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).port) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_key),\n            \"::\",\n            stringify!(port)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rdomain) as usize - ptr as usize },\n        36usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state_key),\n            \"::\",\n            stringify!(rdomain)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).af) as usize - ptr as usize },\n        38usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state_key), \"::\", stringify!(af))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pad) as usize - ptr as usize },\n        39usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state_key), \"::\", stringify!(pad))\n    );\n}\n#[repr(C, packed)]\n#[derive(Copy, Clone)]\npub struct pfsync_state {\n    pub id: u_int64_t,\n    pub ifname: [::std::os::raw::c_char; 16usize],\n    pub key: [pfsync_state_key; 2usize],\n    pub src: pfsync_state_peer,\n    pub dst: pfsync_state_peer,\n    pub rt_addr: pf_addr,\n    pub rule: u_int32_t,\n    pub anchor: u_int32_t,\n    pub nat_rule: u_int32_t,\n    pub creation: u_int32_t,\n    pub expire: u_int32_t,\n    pub packets: [[u_int32_t; 2usize]; 2usize],\n    pub bytes: [[u_int32_t; 2usize]; 2usize],\n    pub creatorid: u_int32_t,\n    pub rtableid: [i32; 2usize],\n    pub max_mss: u_int16_t,\n    pub af: sa_family_t,\n    pub proto: u_int8_t,\n    pub direction: u_int8_t,\n    pub log: u_int8_t,\n    pub rt: u_int8_t,\n    pub timeout: u_int8_t,\n    pub sync_flags: u_int8_t,\n    pub updates: u_int8_t,\n    pub min_ttl: u_int8_t,\n    pub set_tos: u_int8_t,\n    pub state_flags: u_int16_t,\n    pub set_prio: [u_int8_t; 2usize],\n}\n#[test]\nfn bindgen_test_layout_pfsync_state() {\n    const UNINIT: ::std::mem::MaybeUninit<pfsync_state> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfsync_state>(),\n        264usize,\n        concat!(\"Size of: \", stringify!(pfsync_state))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfsync_state>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(pfsync_state))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).id) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(id))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifname) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(ifname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).key) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(key))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).src) as usize - ptr as usize },\n        104usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(src))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dst) as usize - ptr as usize },\n        136usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(dst))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rt_addr) as usize - ptr as usize },\n        168usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(rt_addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rule) as usize - ptr as usize },\n        184usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(rule))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor) as usize - ptr as usize },\n        188usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(anchor))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nat_rule) as usize - ptr as usize },\n        192usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state),\n            \"::\",\n            stringify!(nat_rule)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).creation) as usize - ptr as usize },\n        196usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state),\n            \"::\",\n            stringify!(creation)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).expire) as usize - ptr as usize },\n        200usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(expire))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).packets) as usize - ptr as usize },\n        204usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(packets))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).bytes) as usize - ptr as usize },\n        220usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(bytes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).creatorid) as usize - ptr as usize },\n        236usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state),\n            \"::\",\n            stringify!(creatorid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtableid) as usize - ptr as usize },\n        240usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state),\n            \"::\",\n            stringify!(rtableid)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).max_mss) as usize - ptr as usize },\n        248usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(max_mss))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).af) as usize - ptr as usize },\n        250usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(af))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).proto) as usize - ptr as usize },\n        251usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(proto))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).direction) as usize - ptr as usize },\n        252usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state),\n            \"::\",\n            stringify!(direction)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).log) as usize - ptr as usize },\n        253usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(log))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rt) as usize - ptr as usize },\n        254usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(rt))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).timeout) as usize - ptr as usize },\n        255usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(timeout))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sync_flags) as usize - ptr as usize },\n        256usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state),\n            \"::\",\n            stringify!(sync_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).updates) as usize - ptr as usize },\n        257usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(updates))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).min_ttl) as usize - ptr as usize },\n        258usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(min_ttl))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).set_tos) as usize - ptr as usize },\n        259usize,\n        concat!(\"Offset of field: \", stringify!(pfsync_state), \"::\", stringify!(set_tos))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).state_flags) as usize - ptr as usize },\n        260usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state),\n            \"::\",\n            stringify!(state_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).set_prio) as usize - ptr as usize },\n        262usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsync_state),\n            \"::\",\n            stringify!(set_prio)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_rulequeue {\n    pub tqh_first: *mut pf_rule,\n    pub tqh_last: *mut *mut pf_rule,\n}\n#[test]\nfn bindgen_test_layout_pf_rulequeue() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_rulequeue> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_rulequeue>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_rulequeue))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_rulequeue>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_rulequeue))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqh_first) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rulequeue),\n            \"::\",\n            stringify!(tqh_first)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqh_last) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_rulequeue),\n            \"::\",\n            stringify!(tqh_last)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_ruleset {\n    pub rules: pf_ruleset__bindgen_ty_1,\n    pub anchor: *mut pf_anchor,\n    pub tticket: u_int32_t,\n    pub tables: ::std::os::raw::c_int,\n    pub topen: ::std::os::raw::c_int,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_ruleset__bindgen_ty_1 {\n    pub queues: [pf_rulequeue; 2usize],\n    pub active: pf_ruleset__bindgen_ty_1__bindgen_ty_1,\n    pub inactive: pf_ruleset__bindgen_ty_1__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_ruleset__bindgen_ty_1__bindgen_ty_1 {\n    pub ptr: *mut pf_rulequeue,\n    pub rcount: u_int32_t,\n    pub version: u_int32_t,\n    pub open: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_pf_ruleset__bindgen_ty_1__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_ruleset__bindgen_ty_1__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_ruleset__bindgen_ty_1__bindgen_ty_1>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(pf_ruleset__bindgen_ty_1__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_ruleset__bindgen_ty_1__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_ruleset__bindgen_ty_1__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ptr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_ruleset__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(ptr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rcount) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_ruleset__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(rcount)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).version) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_ruleset__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(version)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).open) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_ruleset__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(open)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_ruleset__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_ruleset__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_ruleset__bindgen_ty_1>(),\n        80usize,\n        concat!(\"Size of: \", stringify!(pf_ruleset__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_ruleset__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_ruleset__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).queues) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_ruleset__bindgen_ty_1),\n            \"::\",\n            stringify!(queues)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).active) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_ruleset__bindgen_ty_1),\n            \"::\",\n            stringify!(active)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).inactive) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_ruleset__bindgen_ty_1),\n            \"::\",\n            stringify!(inactive)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_ruleset() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_ruleset> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_ruleset>(),\n        104usize,\n        concat!(\"Size of: \", stringify!(pf_ruleset))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_ruleset>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_ruleset))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rules) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_ruleset), \"::\", stringify!(rules))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor) as usize - ptr as usize },\n        80usize,\n        concat!(\"Offset of field: \", stringify!(pf_ruleset), \"::\", stringify!(anchor))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tticket) as usize - ptr as usize },\n        88usize,\n        concat!(\"Offset of field: \", stringify!(pf_ruleset), \"::\", stringify!(tticket))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tables) as usize - ptr as usize },\n        92usize,\n        concat!(\"Offset of field: \", stringify!(pf_ruleset), \"::\", stringify!(tables))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).topen) as usize - ptr as usize },\n        96usize,\n        concat!(\"Offset of field: \", stringify!(pf_ruleset), \"::\", stringify!(topen))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_anchor_global {\n    pub rbh_root: *mut pf_anchor,\n}\n#[test]\nfn bindgen_test_layout_pf_anchor_global() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_anchor_global> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_anchor_global>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_anchor_global))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_anchor_global>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_anchor_global))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbh_root) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_anchor_global),\n            \"::\",\n            stringify!(rbh_root)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_anchor_node {\n    pub rbh_root: *mut pf_anchor,\n}\n#[test]\nfn bindgen_test_layout_pf_anchor_node() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_anchor_node> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_anchor_node>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_anchor_node))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_anchor_node>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_anchor_node))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbh_root) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_anchor_node),\n            \"::\",\n            stringify!(rbh_root)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_anchor {\n    pub entry_global: pf_anchor__bindgen_ty_1,\n    pub entry_node: pf_anchor__bindgen_ty_2,\n    pub parent: *mut pf_anchor,\n    pub children: pf_anchor_node,\n    pub name: [::std::os::raw::c_char; 64usize],\n    pub path: [::std::os::raw::c_char; 1024usize],\n    pub ruleset: pf_ruleset,\n    pub refcnt: ::std::os::raw::c_int,\n    pub match_: ::std::os::raw::c_int,\n    pub ref_: refcnt,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_anchor__bindgen_ty_1 {\n    pub rbe_left: *mut pf_anchor,\n    pub rbe_right: *mut pf_anchor,\n    pub rbe_parent: *mut pf_anchor,\n    pub rbe_color: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_pf_anchor__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_anchor__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_anchor__bindgen_ty_1>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(pf_anchor__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_anchor__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_anchor__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_left) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_anchor__bindgen_ty_1),\n            \"::\",\n            stringify!(rbe_left)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_right) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_anchor__bindgen_ty_1),\n            \"::\",\n            stringify!(rbe_right)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_parent) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_anchor__bindgen_ty_1),\n            \"::\",\n            stringify!(rbe_parent)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_color) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_anchor__bindgen_ty_1),\n            \"::\",\n            stringify!(rbe_color)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_anchor__bindgen_ty_2 {\n    pub rbe_left: *mut pf_anchor,\n    pub rbe_right: *mut pf_anchor,\n    pub rbe_parent: *mut pf_anchor,\n    pub rbe_color: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_pf_anchor__bindgen_ty_2() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_anchor__bindgen_ty_2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_anchor__bindgen_ty_2>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(pf_anchor__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_anchor__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_anchor__bindgen_ty_2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_left) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_anchor__bindgen_ty_2),\n            \"::\",\n            stringify!(rbe_left)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_right) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_anchor__bindgen_ty_2),\n            \"::\",\n            stringify!(rbe_right)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_parent) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_anchor__bindgen_ty_2),\n            \"::\",\n            stringify!(rbe_parent)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_color) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_anchor__bindgen_ty_2),\n            \"::\",\n            stringify!(rbe_color)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_anchor() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_anchor> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_anchor>(),\n        1288usize,\n        concat!(\"Size of: \", stringify!(pf_anchor))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_anchor>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_anchor))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).entry_global) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_anchor),\n            \"::\",\n            stringify!(entry_global)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).entry_node) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(pf_anchor), \"::\", stringify!(entry_node))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).parent) as usize - ptr as usize },\n        64usize,\n        concat!(\"Offset of field: \", stringify!(pf_anchor), \"::\", stringify!(parent))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).children) as usize - ptr as usize },\n        72usize,\n        concat!(\"Offset of field: \", stringify!(pf_anchor), \"::\", stringify!(children))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).name) as usize - ptr as usize },\n        80usize,\n        concat!(\"Offset of field: \", stringify!(pf_anchor), \"::\", stringify!(name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).path) as usize - ptr as usize },\n        144usize,\n        concat!(\"Offset of field: \", stringify!(pf_anchor), \"::\", stringify!(path))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ruleset) as usize - ptr as usize },\n        1168usize,\n        concat!(\"Offset of field: \", stringify!(pf_anchor), \"::\", stringify!(ruleset))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).refcnt) as usize - ptr as usize },\n        1272usize,\n        concat!(\"Offset of field: \", stringify!(pf_anchor), \"::\", stringify!(refcnt))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).match_) as usize - ptr as usize },\n        1276usize,\n        concat!(\"Offset of field: \", stringify!(pf_anchor), \"::\", stringify!(match_))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ref_) as usize - ptr as usize },\n        1280usize,\n        concat!(\"Offset of field: \", stringify!(pf_anchor), \"::\", stringify!(ref_))\n    );\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_INSERT_COLOR(arg1: *mut pf_anchor_global, arg2: *mut pf_anchor);\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_REMOVE_COLOR(arg1: *mut pf_anchor_global, arg2: *mut pf_anchor, arg3: *mut pf_anchor);\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_REMOVE(arg1: *mut pf_anchor_global, arg2: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_INSERT(arg1: *mut pf_anchor_global, arg2: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_FIND(arg1: *mut pf_anchor_global, arg2: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_NFIND(arg1: *mut pf_anchor_global, arg2: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_NEXT(arg1: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_PREV(arg1: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_global_RB_MINMAX(arg1: *mut pf_anchor_global, arg2: ::std::os::raw::c_int) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_INSERT_COLOR(arg1: *mut pf_anchor_node, arg2: *mut pf_anchor);\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_REMOVE_COLOR(arg1: *mut pf_anchor_node, arg2: *mut pf_anchor, arg3: *mut pf_anchor);\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_REMOVE(arg1: *mut pf_anchor_node, arg2: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_INSERT(arg1: *mut pf_anchor_node, arg2: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_FIND(arg1: *mut pf_anchor_node, arg2: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_NFIND(arg1: *mut pf_anchor_node, arg2: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_NEXT(arg1: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_PREV(arg1: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_node_RB_MINMAX(arg1: *mut pf_anchor_node, arg2: ::std::os::raw::c_int) -> *mut pf_anchor;\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfr_table {\n    pub pfrt_anchor: [::std::os::raw::c_char; 1024usize],\n    pub pfrt_name: [::std::os::raw::c_char; 32usize],\n    pub pfrt_flags: u_int32_t,\n    pub pfrt_fback: u_int8_t,\n}\n#[test]\nfn bindgen_test_layout_pfr_table() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_table> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_table>(),\n        1064usize,\n        concat!(\"Size of: \", stringify!(pfr_table))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_table>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pfr_table))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrt_anchor) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_table),\n            \"::\",\n            stringify!(pfrt_anchor)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrt_name) as usize - ptr as usize },\n        1024usize,\n        concat!(\"Offset of field: \", stringify!(pfr_table), \"::\", stringify!(pfrt_name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrt_flags) as usize - ptr as usize },\n        1056usize,\n        concat!(\"Offset of field: \", stringify!(pfr_table), \"::\", stringify!(pfrt_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrt_fback) as usize - ptr as usize },\n        1060usize,\n        concat!(\"Offset of field: \", stringify!(pfr_table), \"::\", stringify!(pfrt_fback))\n    );\n}\npub const PFR_FB_NONE: _bindgen_ty_14 = 0;\npub const PFR_FB_MATCH: _bindgen_ty_14 = 1;\npub const PFR_FB_ADDED: _bindgen_ty_14 = 2;\npub const PFR_FB_DELETED: _bindgen_ty_14 = 3;\npub const PFR_FB_CHANGED: _bindgen_ty_14 = 4;\npub const PFR_FB_CLEARED: _bindgen_ty_14 = 5;\npub const PFR_FB_DUPLICATE: _bindgen_ty_14 = 6;\npub const PFR_FB_NOTMATCH: _bindgen_ty_14 = 7;\npub const PFR_FB_CONFLICT: _bindgen_ty_14 = 8;\npub const PFR_FB_NOCOUNT: _bindgen_ty_14 = 9;\npub const PFR_FB_MAX: _bindgen_ty_14 = 10;\npub type _bindgen_ty_14 = ::std::os::raw::c_uint;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfr_addr {\n    pub pfra_u: pfr_addr__bindgen_ty_1,\n    pub pfra_ifname: [::std::os::raw::c_char; 16usize],\n    pub pfra_states: u_int32_t,\n    pub pfra_weight: u_int16_t,\n    pub pfra_af: u_int8_t,\n    pub pfra_net: u_int8_t,\n    pub pfra_not: u_int8_t,\n    pub pfra_fback: u_int8_t,\n    pub pfra_type: u_int8_t,\n    pub pad: [u_int8_t; 7usize],\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pfr_addr__bindgen_ty_1 {\n    pub _pfra_ip4addr: in_addr,\n    pub _pfra_ip6addr: in6_addr,\n}\n#[test]\nfn bindgen_test_layout_pfr_addr__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_addr__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_addr__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pfr_addr__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_addr__bindgen_ty_1>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pfr_addr__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._pfra_ip4addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(_pfra_ip4addr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._pfra_ip6addr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_addr__bindgen_ty_1),\n            \"::\",\n            stringify!(_pfra_ip6addr)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pfr_addr() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_addr> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_addr>(),\n        52usize,\n        concat!(\"Size of: \", stringify!(pfr_addr))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_addr>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pfr_addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfra_u) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfr_addr), \"::\", stringify!(pfra_u))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfra_ifname) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pfr_addr), \"::\", stringify!(pfra_ifname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfra_states) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(pfr_addr), \"::\", stringify!(pfra_states))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfra_weight) as usize - ptr as usize },\n        36usize,\n        concat!(\"Offset of field: \", stringify!(pfr_addr), \"::\", stringify!(pfra_weight))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfra_af) as usize - ptr as usize },\n        38usize,\n        concat!(\"Offset of field: \", stringify!(pfr_addr), \"::\", stringify!(pfra_af))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfra_net) as usize - ptr as usize },\n        39usize,\n        concat!(\"Offset of field: \", stringify!(pfr_addr), \"::\", stringify!(pfra_net))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfra_not) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(pfr_addr), \"::\", stringify!(pfra_not))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfra_fback) as usize - ptr as usize },\n        41usize,\n        concat!(\"Offset of field: \", stringify!(pfr_addr), \"::\", stringify!(pfra_fback))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfra_type) as usize - ptr as usize },\n        42usize,\n        concat!(\"Offset of field: \", stringify!(pfr_addr), \"::\", stringify!(pfra_type))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pad) as usize - ptr as usize },\n        43usize,\n        concat!(\"Offset of field: \", stringify!(pfr_addr), \"::\", stringify!(pad))\n    );\n}\npub const PFR_DIR_IN: _bindgen_ty_15 = 0;\npub const PFR_DIR_OUT: _bindgen_ty_15 = 1;\npub const PFR_DIR_MAX: _bindgen_ty_15 = 2;\npub type _bindgen_ty_15 = ::std::os::raw::c_uint;\npub const PFR_OP_BLOCK: _bindgen_ty_16 = 0;\npub const PFR_OP_MATCH: _bindgen_ty_16 = 1;\npub const PFR_OP_PASS: _bindgen_ty_16 = 2;\npub const PFR_OP_ADDR_MAX: _bindgen_ty_16 = 3;\npub const PFR_OP_TABLE_MAX: _bindgen_ty_16 = 4;\npub type _bindgen_ty_16 = ::std::os::raw::c_uint;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfr_astats {\n    pub pfras_a: pfr_addr,\n    pub pfras_packets: [[u_int64_t; 3usize]; 2usize],\n    pub pfras_bytes: [[u_int64_t; 3usize]; 2usize],\n    pub pfras_tzero: time_t,\n}\n#[test]\nfn bindgen_test_layout_pfr_astats() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_astats> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_astats>(),\n        160usize,\n        concat!(\"Size of: \", stringify!(pfr_astats))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_astats>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfr_astats))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfras_a) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfr_astats), \"::\", stringify!(pfras_a))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfras_packets) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_astats),\n            \"::\",\n            stringify!(pfras_packets)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfras_bytes) as usize - ptr as usize },\n        104usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_astats),\n            \"::\",\n            stringify!(pfras_bytes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfras_tzero) as usize - ptr as usize },\n        152usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_astats),\n            \"::\",\n            stringify!(pfras_tzero)\n        )\n    );\n}\npub const PFR_REFCNT_RULE: _bindgen_ty_17 = 0;\npub const PFR_REFCNT_ANCHOR: _bindgen_ty_17 = 1;\npub const PFR_REFCNT_MAX: _bindgen_ty_17 = 2;\npub type _bindgen_ty_17 = ::std::os::raw::c_uint;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfr_tstats {\n    pub pfrts_t: pfr_table,\n    pub pfrts_packets: [[u_int64_t; 4usize]; 2usize],\n    pub pfrts_bytes: [[u_int64_t; 4usize]; 2usize],\n    pub pfrts_match: u_int64_t,\n    pub pfrts_nomatch: u_int64_t,\n    pub pfrts_tzero: time_t,\n    pub pfrts_cnt: ::std::os::raw::c_int,\n    pub pfrts_refcnt: [::std::os::raw::c_int; 2usize],\n}\n#[test]\nfn bindgen_test_layout_pfr_tstats() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_tstats> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_tstats>(),\n        1232usize,\n        concat!(\"Size of: \", stringify!(pfr_tstats))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_tstats>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfr_tstats))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrts_t) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfr_tstats), \"::\", stringify!(pfrts_t))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrts_packets) as usize - ptr as usize },\n        1064usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_tstats),\n            \"::\",\n            stringify!(pfrts_packets)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrts_bytes) as usize - ptr as usize },\n        1128usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_tstats),\n            \"::\",\n            stringify!(pfrts_bytes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrts_match) as usize - ptr as usize },\n        1192usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_tstats),\n            \"::\",\n            stringify!(pfrts_match)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrts_nomatch) as usize - ptr as usize },\n        1200usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_tstats),\n            \"::\",\n            stringify!(pfrts_nomatch)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrts_tzero) as usize - ptr as usize },\n        1208usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_tstats),\n            \"::\",\n            stringify!(pfrts_tzero)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrts_cnt) as usize - ptr as usize },\n        1216usize,\n        concat!(\"Offset of field: \", stringify!(pfr_tstats), \"::\", stringify!(pfrts_cnt))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrts_refcnt) as usize - ptr as usize },\n        1220usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_tstats),\n            \"::\",\n            stringify!(pfrts_refcnt)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfr_kcounters {\n    pub pfrkc_packets: [[u_int64_t; 3usize]; 2usize],\n    pub pfrkc_bytes: [[u_int64_t; 3usize]; 2usize],\n    pub states: u_int64_t,\n}\n#[test]\nfn bindgen_test_layout_pfr_kcounters() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_kcounters> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_kcounters>(),\n        104usize,\n        concat!(\"Size of: \", stringify!(pfr_kcounters))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_kcounters>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfr_kcounters))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrkc_packets) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_kcounters),\n            \"::\",\n            stringify!(pfrkc_packets)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrkc_bytes) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_kcounters),\n            \"::\",\n            stringify!(pfrkc_bytes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).states) as usize - ptr as usize },\n        96usize,\n        concat!(\"Offset of field: \", stringify!(pfr_kcounters), \"::\", stringify!(states))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pfsockaddr_union {\n    pub sa: sockaddr,\n    pub sin: sockaddr_in,\n    pub sin6: sockaddr_in6,\n}\n#[test]\nfn bindgen_test_layout_pfsockaddr_union() {\n    const UNINIT: ::std::mem::MaybeUninit<pfsockaddr_union> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfsockaddr_union>(),\n        28usize,\n        concat!(\"Size of: \", stringify!(pfsockaddr_union))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfsockaddr_union>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pfsockaddr_union))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sa) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfsockaddr_union), \"::\", stringify!(sa))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfsockaddr_union), \"::\", stringify!(sin))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sin6) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfsockaddr_union),\n            \"::\",\n            stringify!(sin6)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfr_kentryworkq {\n    pub slh_first: *mut pfr_kentry,\n}\n#[test]\nfn bindgen_test_layout_pfr_kentryworkq() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_kentryworkq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_kentryworkq>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pfr_kentryworkq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_kentryworkq>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfr_kentryworkq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).slh_first) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_kentryworkq),\n            \"::\",\n            stringify!(slh_first)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct _pfr_kentry {\n    pub _pfrke_node: [radix_node; 2usize],\n    pub _pfrke_sa: pfsockaddr_union,\n    pub _pfrke_workq: _pfr_kentry__bindgen_ty_1,\n    pub _pfrke_ioq: _pfr_kentry__bindgen_ty_2,\n    pub _pfrke_counters: *mut pfr_kcounters,\n    pub _pfrke_tzero: time_t,\n    pub _pfrke_af: u_int8_t,\n    pub _pfrke_net: u_int8_t,\n    pub _pfrke_flags: u_int8_t,\n    pub _pfrke_type: u_int8_t,\n    pub _pfrke_fb: u_int8_t,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct _pfr_kentry__bindgen_ty_1 {\n    pub sle_next: *mut pfr_kentry,\n}\n#[test]\nfn bindgen_test_layout__pfr_kentry__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<_pfr_kentry__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<_pfr_kentry__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(_pfr_kentry__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<_pfr_kentry__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(_pfr_kentry__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sle_next) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_pfr_kentry__bindgen_ty_1),\n            \"::\",\n            stringify!(sle_next)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct _pfr_kentry__bindgen_ty_2 {\n    pub sle_next: *mut pfr_kentry,\n}\n#[test]\nfn bindgen_test_layout__pfr_kentry__bindgen_ty_2() {\n    const UNINIT: ::std::mem::MaybeUninit<_pfr_kentry__bindgen_ty_2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<_pfr_kentry__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(_pfr_kentry__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<_pfr_kentry__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(_pfr_kentry__bindgen_ty_2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sle_next) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_pfr_kentry__bindgen_ty_2),\n            \"::\",\n            stringify!(sle_next)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout__pfr_kentry() {\n    const UNINIT: ::std::mem::MaybeUninit<_pfr_kentry> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<_pfr_kentry>(),\n        168usize,\n        concat!(\"Size of: \", stringify!(_pfr_kentry))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<_pfr_kentry>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(_pfr_kentry))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._pfrke_node) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_pfr_kentry),\n            \"::\",\n            stringify!(_pfrke_node)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._pfrke_sa) as usize - ptr as usize },\n        96usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_pfr_kentry),\n            \"::\",\n            stringify!(_pfrke_sa)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._pfrke_workq) as usize - ptr as usize },\n        128usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_pfr_kentry),\n            \"::\",\n            stringify!(_pfrke_workq)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._pfrke_ioq) as usize - ptr as usize },\n        136usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_pfr_kentry),\n            \"::\",\n            stringify!(_pfrke_ioq)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._pfrke_counters) as usize - ptr as usize },\n        144usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_pfr_kentry),\n            \"::\",\n            stringify!(_pfrke_counters)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._pfrke_tzero) as usize - ptr as usize },\n        152usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_pfr_kentry),\n            \"::\",\n            stringify!(_pfrke_tzero)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._pfrke_af) as usize - ptr as usize },\n        160usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_pfr_kentry),\n            \"::\",\n            stringify!(_pfrke_af)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._pfrke_net) as usize - ptr as usize },\n        161usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_pfr_kentry),\n            \"::\",\n            stringify!(_pfrke_net)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._pfrke_flags) as usize - ptr as usize },\n        162usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_pfr_kentry),\n            \"::\",\n            stringify!(_pfrke_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._pfrke_type) as usize - ptr as usize },\n        163usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_pfr_kentry),\n            \"::\",\n            stringify!(_pfrke_type)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._pfrke_fb) as usize - ptr as usize },\n        164usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(_pfr_kentry),\n            \"::\",\n            stringify!(_pfrke_fb)\n        )\n    );\n}\npub const PFRKE_PLAIN: _bindgen_ty_18 = 0;\npub const PFRKE_ROUTE: _bindgen_ty_18 = 1;\npub const PFRKE_COST: _bindgen_ty_18 = 2;\npub const PFRKE_MAX: _bindgen_ty_18 = 3;\npub type _bindgen_ty_18 = ::std::os::raw::c_uint;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfr_kentry {\n    pub u: pfr_kentry__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pfr_kentry__bindgen_ty_1 {\n    pub _ke: _pfr_kentry,\n}\n#[test]\nfn bindgen_test_layout_pfr_kentry__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_kentry__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_kentry__bindgen_ty_1>(),\n        168usize,\n        concat!(\"Size of: \", stringify!(pfr_kentry__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_kentry__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfr_kentry__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._ke) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_kentry__bindgen_ty_1),\n            \"::\",\n            stringify!(_ke)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pfr_kentry() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_kentry> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_kentry>(),\n        168usize,\n        concat!(\"Size of: \", stringify!(pfr_kentry))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_kentry>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfr_kentry))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).u) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfr_kentry), \"::\", stringify!(u))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfr_kentry_route {\n    pub u: pfr_kentry_route__bindgen_ty_1,\n    pub kif: *mut pfi_kif,\n    pub ifname: [::std::os::raw::c_char; 16usize],\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pfr_kentry_route__bindgen_ty_1 {\n    pub _ke: _pfr_kentry,\n}\n#[test]\nfn bindgen_test_layout_pfr_kentry_route__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_kentry_route__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_kentry_route__bindgen_ty_1>(),\n        168usize,\n        concat!(\"Size of: \", stringify!(pfr_kentry_route__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_kentry_route__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfr_kentry_route__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._ke) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_kentry_route__bindgen_ty_1),\n            \"::\",\n            stringify!(_ke)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pfr_kentry_route() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_kentry_route> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_kentry_route>(),\n        192usize,\n        concat!(\"Size of: \", stringify!(pfr_kentry_route))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_kentry_route>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfr_kentry_route))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).u) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfr_kentry_route), \"::\", stringify!(u))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).kif) as usize - ptr as usize },\n        168usize,\n        concat!(\"Offset of field: \", stringify!(pfr_kentry_route), \"::\", stringify!(kif))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifname) as usize - ptr as usize },\n        176usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_kentry_route),\n            \"::\",\n            stringify!(ifname)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfr_kentry_cost {\n    pub u: pfr_kentry_cost__bindgen_ty_1,\n    pub kif: *mut pfi_kif,\n    pub ifname: [::std::os::raw::c_char; 16usize],\n    pub weight: u_int16_t,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pfr_kentry_cost__bindgen_ty_1 {\n    pub _ke: _pfr_kentry,\n}\n#[test]\nfn bindgen_test_layout_pfr_kentry_cost__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_kentry_cost__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_kentry_cost__bindgen_ty_1>(),\n        168usize,\n        concat!(\"Size of: \", stringify!(pfr_kentry_cost__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_kentry_cost__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfr_kentry_cost__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._ke) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_kentry_cost__bindgen_ty_1),\n            \"::\",\n            stringify!(_ke)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pfr_kentry_cost() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_kentry_cost> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_kentry_cost>(),\n        200usize,\n        concat!(\"Size of: \", stringify!(pfr_kentry_cost))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_kentry_cost>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfr_kentry_cost))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).u) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfr_kentry_cost), \"::\", stringify!(u))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).kif) as usize - ptr as usize },\n        168usize,\n        concat!(\"Offset of field: \", stringify!(pfr_kentry_cost), \"::\", stringify!(kif))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifname) as usize - ptr as usize },\n        176usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_kentry_cost),\n            \"::\",\n            stringify!(ifname)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).weight) as usize - ptr as usize },\n        192usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_kentry_cost),\n            \"::\",\n            stringify!(weight)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfr_kentry_all {\n    pub u: pfr_kentry_all__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pfr_kentry_all__bindgen_ty_1 {\n    pub _ke: _pfr_kentry,\n    pub kr: pfr_kentry_route,\n    pub kc: pfr_kentry_cost,\n}\n#[test]\nfn bindgen_test_layout_pfr_kentry_all__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_kentry_all__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_kentry_all__bindgen_ty_1>(),\n        200usize,\n        concat!(\"Size of: \", stringify!(pfr_kentry_all__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_kentry_all__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfr_kentry_all__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr)._ke) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_kentry_all__bindgen_ty_1),\n            \"::\",\n            stringify!(_ke)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).kr) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_kentry_all__bindgen_ty_1),\n            \"::\",\n            stringify!(kr)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).kc) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_kentry_all__bindgen_ty_1),\n            \"::\",\n            stringify!(kc)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pfr_kentry_all() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_kentry_all> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_kentry_all>(),\n        200usize,\n        concat!(\"Size of: \", stringify!(pfr_kentry_all))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_kentry_all>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfr_kentry_all))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).u) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfr_kentry_all), \"::\", stringify!(u))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfr_ktableworkq {\n    pub slh_first: *mut pfr_ktable,\n}\n#[test]\nfn bindgen_test_layout_pfr_ktableworkq() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_ktableworkq> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_ktableworkq>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pfr_ktableworkq))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_ktableworkq>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfr_ktableworkq))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).slh_first) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_ktableworkq),\n            \"::\",\n            stringify!(slh_first)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfr_ktablehead {\n    pub rbh_root: *mut pfr_ktable,\n}\n#[test]\nfn bindgen_test_layout_pfr_ktablehead() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_ktablehead> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_ktablehead>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pfr_ktablehead))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_ktablehead>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfr_ktablehead))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbh_root) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_ktablehead),\n            \"::\",\n            stringify!(rbh_root)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfr_ktable {\n    pub pfrkt_ts: pfr_tstats,\n    pub pfrkt_tree: pfr_ktable__bindgen_ty_1,\n    pub pfrkt_workq: pfr_ktable__bindgen_ty_2,\n    pub pfrkt_ip4: *mut radix_node_head,\n    pub pfrkt_ip6: *mut radix_node_head,\n    pub pfrkt_shadow: *mut pfr_ktable,\n    pub pfrkt_root: *mut pfr_ktable,\n    pub pfrkt_rs: *mut pf_ruleset,\n    pub pfrkt_larg: ::std::os::raw::c_long,\n    pub pfrkt_nflags: ::std::os::raw::c_int,\n    pub pfrkt_refcntcost: u_int64_t,\n    pub pfrkt_gcdweight: u_int16_t,\n    pub pfrkt_maxweight: u_int16_t,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfr_ktable__bindgen_ty_1 {\n    pub rbe_left: *mut pfr_ktable,\n    pub rbe_right: *mut pfr_ktable,\n    pub rbe_parent: *mut pfr_ktable,\n    pub rbe_color: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_pfr_ktable__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_ktable__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_ktable__bindgen_ty_1>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(pfr_ktable__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_ktable__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfr_ktable__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_left) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_ktable__bindgen_ty_1),\n            \"::\",\n            stringify!(rbe_left)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_right) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_ktable__bindgen_ty_1),\n            \"::\",\n            stringify!(rbe_right)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_parent) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_ktable__bindgen_ty_1),\n            \"::\",\n            stringify!(rbe_parent)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_color) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_ktable__bindgen_ty_1),\n            \"::\",\n            stringify!(rbe_color)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfr_ktable__bindgen_ty_2 {\n    pub sle_next: *mut pfr_ktable,\n}\n#[test]\nfn bindgen_test_layout_pfr_ktable__bindgen_ty_2() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_ktable__bindgen_ty_2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_ktable__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pfr_ktable__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_ktable__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfr_ktable__bindgen_ty_2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sle_next) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_ktable__bindgen_ty_2),\n            \"::\",\n            stringify!(sle_next)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pfr_ktable() {\n    const UNINIT: ::std::mem::MaybeUninit<pfr_ktable> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfr_ktable>(),\n        1344usize,\n        concat!(\"Size of: \", stringify!(pfr_ktable))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfr_ktable>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfr_ktable))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrkt_ts) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfr_ktable), \"::\", stringify!(pfrkt_ts))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrkt_tree) as usize - ptr as usize },\n        1232usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_ktable),\n            \"::\",\n            stringify!(pfrkt_tree)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrkt_workq) as usize - ptr as usize },\n        1264usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_ktable),\n            \"::\",\n            stringify!(pfrkt_workq)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrkt_ip4) as usize - ptr as usize },\n        1272usize,\n        concat!(\"Offset of field: \", stringify!(pfr_ktable), \"::\", stringify!(pfrkt_ip4))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrkt_ip6) as usize - ptr as usize },\n        1280usize,\n        concat!(\"Offset of field: \", stringify!(pfr_ktable), \"::\", stringify!(pfrkt_ip6))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrkt_shadow) as usize - ptr as usize },\n        1288usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_ktable),\n            \"::\",\n            stringify!(pfrkt_shadow)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrkt_root) as usize - ptr as usize },\n        1296usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_ktable),\n            \"::\",\n            stringify!(pfrkt_root)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrkt_rs) as usize - ptr as usize },\n        1304usize,\n        concat!(\"Offset of field: \", stringify!(pfr_ktable), \"::\", stringify!(pfrkt_rs))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrkt_larg) as usize - ptr as usize },\n        1312usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_ktable),\n            \"::\",\n            stringify!(pfrkt_larg)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrkt_nflags) as usize - ptr as usize },\n        1320usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_ktable),\n            \"::\",\n            stringify!(pfrkt_nflags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrkt_refcntcost) as usize - ptr as usize },\n        1328usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_ktable),\n            \"::\",\n            stringify!(pfrkt_refcntcost)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrkt_gcdweight) as usize - ptr as usize },\n        1336usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_ktable),\n            \"::\",\n            stringify!(pfrkt_gcdweight)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrkt_maxweight) as usize - ptr as usize },\n        1338usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfr_ktable),\n            \"::\",\n            stringify!(pfrkt_maxweight)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_state_tree_ext_gwy {\n    pub rbh_root: *mut pf_state_key,\n}\n#[test]\nfn bindgen_test_layout_pf_state_tree_ext_gwy() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_state_tree_ext_gwy> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_state_tree_ext_gwy>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_state_tree_ext_gwy))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_state_tree_ext_gwy>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_state_tree_ext_gwy))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbh_root) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_state_tree_ext_gwy),\n            \"::\",\n            stringify!(rbh_root)\n        )\n    );\n}\nunsafe extern \"C\" {\n    pub fn pf_state_tree_ext_gwy_RB_INSERT_COLOR(arg1: *mut pf_state_tree_ext_gwy, arg2: *mut pf_state_key);\n}\nunsafe extern \"C\" {\n    pub fn pf_state_tree_ext_gwy_RB_REMOVE_COLOR(\n        arg1: *mut pf_state_tree_ext_gwy,\n        arg2: *mut pf_state_key,\n        arg3: *mut pf_state_key,\n    );\n}\nunsafe extern \"C\" {\n    pub fn pf_state_tree_ext_gwy_RB_REMOVE(\n        arg1: *mut pf_state_tree_ext_gwy,\n        arg2: *mut pf_state_key,\n    ) -> *mut pf_state_key;\n}\nunsafe extern \"C\" {\n    pub fn pf_state_tree_ext_gwy_RB_INSERT(\n        arg1: *mut pf_state_tree_ext_gwy,\n        arg2: *mut pf_state_key,\n    ) -> *mut pf_state_key;\n}\nunsafe extern \"C\" {\n    pub fn pf_state_tree_ext_gwy_RB_FIND(\n        arg1: *mut pf_state_tree_ext_gwy,\n        arg2: *mut pf_state_key,\n    ) -> *mut pf_state_key;\n}\nunsafe extern \"C\" {\n    pub fn pf_state_tree_ext_gwy_RB_NFIND(\n        arg1: *mut pf_state_tree_ext_gwy,\n        arg2: *mut pf_state_key,\n    ) -> *mut pf_state_key;\n}\nunsafe extern \"C\" {\n    pub fn pf_state_tree_ext_gwy_RB_NEXT(arg1: *mut pf_state_key) -> *mut pf_state_key;\n}\nunsafe extern \"C\" {\n    pub fn pf_state_tree_ext_gwy_RB_PREV(arg1: *mut pf_state_key) -> *mut pf_state_key;\n}\nunsafe extern \"C\" {\n    pub fn pf_state_tree_ext_gwy_RB_MINMAX(\n        arg1: *mut pf_state_tree_ext_gwy,\n        arg2: ::std::os::raw::c_int,\n    ) -> *mut pf_state_key;\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfi_ifhead {\n    pub rbh_root: *mut pfi_kif,\n}\n#[test]\nfn bindgen_test_layout_pfi_ifhead() {\n    const UNINIT: ::std::mem::MaybeUninit<pfi_ifhead> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfi_ifhead>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pfi_ifhead))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfi_ifhead>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfi_ifhead))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbh_root) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfi_ifhead), \"::\", stringify!(rbh_root))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_state_tree {\n    _unused: [u8; 0],\n}\nunsafe extern \"C\" {\n    pub static mut pf_statetbl: pf_state_tree;\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfi_kif_cmp {\n    pub pfik_name: [::std::os::raw::c_char; 16usize],\n}\n#[test]\nfn bindgen_test_layout_pfi_kif_cmp() {\n    const UNINIT: ::std::mem::MaybeUninit<pfi_kif_cmp> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfi_kif_cmp>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pfi_kif_cmp))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfi_kif_cmp>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(pfi_kif_cmp))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_name) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfi_kif_cmp),\n            \"::\",\n            stringify!(pfik_name)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ifnet {\n    _unused: [u8; 0],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ifg_group {\n    _unused: [u8; 0],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfi_kif {\n    pub pfik_name: [::std::os::raw::c_char; 16usize],\n    pub pfik_tree: pfi_kif__bindgen_ty_1,\n    pub pfik_packets: [[[u_int64_t; 2usize]; 2usize]; 2usize],\n    pub pfik_bytes: [[[u_int64_t; 2usize]; 2usize]; 2usize],\n    pub pfik_tzero: time_t,\n    pub pfik_flags: ::std::os::raw::c_int,\n    pub pfik_flags_new: ::std::os::raw::c_int,\n    pub pfik_ah_cookie: *mut ::std::os::raw::c_void,\n    pub pfik_ifp: *mut ifnet,\n    pub pfik_group: *mut ifg_group,\n    pub pfik_states: ::std::os::raw::c_int,\n    pub pfik_rules: ::std::os::raw::c_int,\n    pub pfik_routes: ::std::os::raw::c_int,\n    pub pfik_srcnodes: ::std::os::raw::c_int,\n    pub pfik_flagrefs: ::std::os::raw::c_int,\n    pub pfik_dynaddrs: pfi_kif__bindgen_ty_2,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfi_kif__bindgen_ty_1 {\n    pub rbe_left: *mut pfi_kif,\n    pub rbe_right: *mut pfi_kif,\n    pub rbe_parent: *mut pfi_kif,\n    pub rbe_color: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_pfi_kif__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pfi_kif__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfi_kif__bindgen_ty_1>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(pfi_kif__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfi_kif__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfi_kif__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_left) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfi_kif__bindgen_ty_1),\n            \"::\",\n            stringify!(rbe_left)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_right) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfi_kif__bindgen_ty_1),\n            \"::\",\n            stringify!(rbe_right)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_parent) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfi_kif__bindgen_ty_1),\n            \"::\",\n            stringify!(rbe_parent)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rbe_color) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfi_kif__bindgen_ty_1),\n            \"::\",\n            stringify!(rbe_color)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfi_kif__bindgen_ty_2 {\n    pub tqh_first: *mut pfi_dynaddr,\n    pub tqh_last: *mut *mut pfi_dynaddr,\n}\n#[test]\nfn bindgen_test_layout_pfi_kif__bindgen_ty_2() {\n    const UNINIT: ::std::mem::MaybeUninit<pfi_kif__bindgen_ty_2> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfi_kif__bindgen_ty_2>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pfi_kif__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfi_kif__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfi_kif__bindgen_ty_2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqh_first) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfi_kif__bindgen_ty_2),\n            \"::\",\n            stringify!(tqh_first)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqh_last) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfi_kif__bindgen_ty_2),\n            \"::\",\n            stringify!(tqh_last)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pfi_kif() {\n    const UNINIT: ::std::mem::MaybeUninit<pfi_kif> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfi_kif>(),\n        256usize,\n        concat!(\"Size of: \", stringify!(pfi_kif))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfi_kif>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfi_kif))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_name) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfi_kif), \"::\", stringify!(pfik_name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_tree) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pfi_kif), \"::\", stringify!(pfik_tree))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_packets) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(pfi_kif), \"::\", stringify!(pfik_packets))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_bytes) as usize - ptr as usize },\n        112usize,\n        concat!(\"Offset of field: \", stringify!(pfi_kif), \"::\", stringify!(pfik_bytes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_tzero) as usize - ptr as usize },\n        176usize,\n        concat!(\"Offset of field: \", stringify!(pfi_kif), \"::\", stringify!(pfik_tzero))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_flags) as usize - ptr as usize },\n        184usize,\n        concat!(\"Offset of field: \", stringify!(pfi_kif), \"::\", stringify!(pfik_flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_flags_new) as usize - ptr as usize },\n        188usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfi_kif),\n            \"::\",\n            stringify!(pfik_flags_new)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_ah_cookie) as usize - ptr as usize },\n        192usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfi_kif),\n            \"::\",\n            stringify!(pfik_ah_cookie)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_ifp) as usize - ptr as usize },\n        200usize,\n        concat!(\"Offset of field: \", stringify!(pfi_kif), \"::\", stringify!(pfik_ifp))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_group) as usize - ptr as usize },\n        208usize,\n        concat!(\"Offset of field: \", stringify!(pfi_kif), \"::\", stringify!(pfik_group))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_states) as usize - ptr as usize },\n        216usize,\n        concat!(\"Offset of field: \", stringify!(pfi_kif), \"::\", stringify!(pfik_states))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_rules) as usize - ptr as usize },\n        220usize,\n        concat!(\"Offset of field: \", stringify!(pfi_kif), \"::\", stringify!(pfik_rules))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_routes) as usize - ptr as usize },\n        224usize,\n        concat!(\"Offset of field: \", stringify!(pfi_kif), \"::\", stringify!(pfik_routes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_srcnodes) as usize - ptr as usize },\n        228usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfi_kif),\n            \"::\",\n            stringify!(pfik_srcnodes)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_flagrefs) as usize - ptr as usize },\n        232usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfi_kif),\n            \"::\",\n            stringify!(pfik_flagrefs)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfik_dynaddrs) as usize - ptr as usize },\n        240usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfi_kif),\n            \"::\",\n            stringify!(pfik_dynaddrs)\n        )\n    );\n}\npub const pfi_kif_refs_PFI_KIF_REF_NONE: pfi_kif_refs = 0;\npub const pfi_kif_refs_PFI_KIF_REF_STATE: pfi_kif_refs = 1;\npub const pfi_kif_refs_PFI_KIF_REF_RULE: pfi_kif_refs = 2;\npub const pfi_kif_refs_PFI_KIF_REF_ROUTE: pfi_kif_refs = 3;\npub const pfi_kif_refs_PFI_KIF_REF_SRCNODE: pfi_kif_refs = 4;\npub const pfi_kif_refs_PFI_KIF_REF_FLAG: pfi_kif_refs = 5;\npub type pfi_kif_refs = ::std::os::raw::c_uint;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_status {\n    pub counters: [u_int64_t; 17usize],\n    pub lcounters: [u_int64_t; 10usize],\n    pub fcounters: [u_int64_t; 3usize],\n    pub scounters: [u_int64_t; 3usize],\n    pub pcounters: [[[u_int64_t; 3usize]; 2usize]; 2usize],\n    pub bcounters: [[u_int64_t; 2usize]; 2usize],\n    pub stateid: u_int64_t,\n    pub syncookies_inflight: [u_int64_t; 2usize],\n    pub since: time_t,\n    pub running: u_int32_t,\n    pub states: u_int32_t,\n    pub states_halfopen: u_int32_t,\n    pub src_nodes: u_int32_t,\n    pub debug: u_int32_t,\n    pub hostid: u_int32_t,\n    pub reass: u_int32_t,\n    pub syncookies_active: u_int8_t,\n    pub syncookies_mode: u_int8_t,\n    pub pad: [u_int8_t; 2usize],\n    pub ifname: [::std::os::raw::c_char; 16usize],\n    pub pf_chksum: [u_int8_t; 16usize],\n}\n#[test]\nfn bindgen_test_layout_pf_status() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_status> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_status>(),\n        488usize,\n        concat!(\"Size of: \", stringify!(pf_status))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_status>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_status))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).counters) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(counters))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lcounters) as usize - ptr as usize },\n        136usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(lcounters))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fcounters) as usize - ptr as usize },\n        216usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(fcounters))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).scounters) as usize - ptr as usize },\n        240usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(scounters))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pcounters) as usize - ptr as usize },\n        264usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(pcounters))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).bcounters) as usize - ptr as usize },\n        360usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(bcounters))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).stateid) as usize - ptr as usize },\n        392usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(stateid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).syncookies_inflight) as usize - ptr as usize },\n        400usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_status),\n            \"::\",\n            stringify!(syncookies_inflight)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).since) as usize - ptr as usize },\n        416usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(since))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).running) as usize - ptr as usize },\n        424usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(running))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).states) as usize - ptr as usize },\n        428usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(states))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).states_halfopen) as usize - ptr as usize },\n        432usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_status),\n            \"::\",\n            stringify!(states_halfopen)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).src_nodes) as usize - ptr as usize },\n        436usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(src_nodes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).debug) as usize - ptr as usize },\n        440usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(debug))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).hostid) as usize - ptr as usize },\n        444usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(hostid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).reass) as usize - ptr as usize },\n        448usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(reass))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).syncookies_active) as usize - ptr as usize },\n        452usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_status),\n            \"::\",\n            stringify!(syncookies_active)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).syncookies_mode) as usize - ptr as usize },\n        453usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_status),\n            \"::\",\n            stringify!(syncookies_mode)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pad) as usize - ptr as usize },\n        454usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(pad))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifname) as usize - ptr as usize },\n        456usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(ifname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pf_chksum) as usize - ptr as usize },\n        472usize,\n        concat!(\"Offset of field: \", stringify!(pf_status), \"::\", stringify!(pf_chksum))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_queue_bwspec {\n    pub absolute: u_int,\n    pub percent: u_int,\n}\n#[test]\nfn bindgen_test_layout_pf_queue_bwspec() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_queue_bwspec> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_queue_bwspec>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pf_queue_bwspec))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_queue_bwspec>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_queue_bwspec))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).absolute) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_queue_bwspec),\n            \"::\",\n            stringify!(absolute)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).percent) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_queue_bwspec),\n            \"::\",\n            stringify!(percent)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_queue_scspec {\n    pub m1: pf_queue_bwspec,\n    pub m2: pf_queue_bwspec,\n    pub d: u_int,\n}\n#[test]\nfn bindgen_test_layout_pf_queue_scspec() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_queue_scspec> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_queue_scspec>(),\n        20usize,\n        concat!(\"Size of: \", stringify!(pf_queue_scspec))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_queue_scspec>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_queue_scspec))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).m1) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_queue_scspec), \"::\", stringify!(m1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).m2) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pf_queue_scspec), \"::\", stringify!(m2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).d) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pf_queue_scspec), \"::\", stringify!(d))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_queue_fqspec {\n    pub flows: u_int,\n    pub quantum: u_int,\n    pub target: u_int,\n    pub interval: u_int,\n}\n#[test]\nfn bindgen_test_layout_pf_queue_fqspec() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_queue_fqspec> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_queue_fqspec>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_queue_fqspec))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_queue_fqspec>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_queue_fqspec))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flows) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_queue_fqspec),\n            \"::\",\n            stringify!(flows)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).quantum) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_queue_fqspec),\n            \"::\",\n            stringify!(quantum)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).target) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_queue_fqspec),\n            \"::\",\n            stringify!(target)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).interval) as usize - ptr as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_queue_fqspec),\n            \"::\",\n            stringify!(interval)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_queuespec {\n    pub entries: pf_queuespec__bindgen_ty_1,\n    pub qname: [::std::os::raw::c_char; 64usize],\n    pub parent: [::std::os::raw::c_char; 64usize],\n    pub ifname: [::std::os::raw::c_char; 16usize],\n    pub realtime: pf_queue_scspec,\n    pub linkshare: pf_queue_scspec,\n    pub upperlimit: pf_queue_scspec,\n    pub flowqueue: pf_queue_fqspec,\n    pub kif: *mut pfi_kif,\n    pub flags: u_int,\n    pub qlimit: u_int,\n    pub qid: u_int32_t,\n    pub parent_qid: u_int32_t,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_queuespec__bindgen_ty_1 {\n    pub tqe_next: *mut pf_queuespec,\n    pub tqe_prev: *mut *mut pf_queuespec,\n}\n#[test]\nfn bindgen_test_layout_pf_queuespec__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_queuespec__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_queuespec__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_queuespec__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_queuespec__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_queuespec__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqe_next) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_queuespec__bindgen_ty_1),\n            \"::\",\n            stringify!(tqe_next)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqe_prev) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_queuespec__bindgen_ty_1),\n            \"::\",\n            stringify!(tqe_prev)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_queuespec() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_queuespec> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_queuespec>(),\n        264usize,\n        concat!(\"Size of: \", stringify!(pf_queuespec))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_queuespec>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_queuespec))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).entries) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_queuespec), \"::\", stringify!(entries))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).qname) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pf_queuespec), \"::\", stringify!(qname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).parent) as usize - ptr as usize },\n        80usize,\n        concat!(\"Offset of field: \", stringify!(pf_queuespec), \"::\", stringify!(parent))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifname) as usize - ptr as usize },\n        144usize,\n        concat!(\"Offset of field: \", stringify!(pf_queuespec), \"::\", stringify!(ifname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).realtime) as usize - ptr as usize },\n        160usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_queuespec),\n            \"::\",\n            stringify!(realtime)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).linkshare) as usize - ptr as usize },\n        180usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_queuespec),\n            \"::\",\n            stringify!(linkshare)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).upperlimit) as usize - ptr as usize },\n        200usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_queuespec),\n            \"::\",\n            stringify!(upperlimit)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flowqueue) as usize - ptr as usize },\n        220usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_queuespec),\n            \"::\",\n            stringify!(flowqueue)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).kif) as usize - ptr as usize },\n        240usize,\n        concat!(\"Offset of field: \", stringify!(pf_queuespec), \"::\", stringify!(kif))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flags) as usize - ptr as usize },\n        248usize,\n        concat!(\"Offset of field: \", stringify!(pf_queuespec), \"::\", stringify!(flags))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).qlimit) as usize - ptr as usize },\n        252usize,\n        concat!(\"Offset of field: \", stringify!(pf_queuespec), \"::\", stringify!(qlimit))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).qid) as usize - ptr as usize },\n        256usize,\n        concat!(\"Offset of field: \", stringify!(pf_queuespec), \"::\", stringify!(qid))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).parent_qid) as usize - ptr as usize },\n        260usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_queuespec),\n            \"::\",\n            stringify!(parent_qid)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct priq_opts {\n    pub flags: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_priq_opts() {\n    const UNINIT: ::std::mem::MaybeUninit<priq_opts> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<priq_opts>(),\n        4usize,\n        concat!(\"Size of: \", stringify!(priq_opts))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<priq_opts>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(priq_opts))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flags) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(priq_opts), \"::\", stringify!(flags))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct hfsc_opts {\n    pub rtsc_m1: u_int,\n    pub rtsc_d: u_int,\n    pub rtsc_m2: u_int,\n    pub lssc_m1: u_int,\n    pub lssc_d: u_int,\n    pub lssc_m2: u_int,\n    pub ulsc_m1: u_int,\n    pub ulsc_d: u_int,\n    pub ulsc_m2: u_int,\n    pub flags: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_hfsc_opts() {\n    const UNINIT: ::std::mem::MaybeUninit<hfsc_opts> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<hfsc_opts>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(hfsc_opts))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<hfsc_opts>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(hfsc_opts))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtsc_m1) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts), \"::\", stringify!(rtsc_m1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtsc_d) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts), \"::\", stringify!(rtsc_d))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rtsc_m2) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts), \"::\", stringify!(rtsc_m2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lssc_m1) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts), \"::\", stringify!(lssc_m1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lssc_d) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts), \"::\", stringify!(lssc_d))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lssc_m2) as usize - ptr as usize },\n        20usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts), \"::\", stringify!(lssc_m2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ulsc_m1) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts), \"::\", stringify!(ulsc_m1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ulsc_d) as usize - ptr as usize },\n        28usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts), \"::\", stringify!(ulsc_d))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ulsc_m2) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts), \"::\", stringify!(ulsc_m2))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).flags) as usize - ptr as usize },\n        36usize,\n        concat!(\"Offset of field: \", stringify!(hfsc_opts), \"::\", stringify!(flags))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfq_ops {\n    pub pfq_alloc: ::std::option::Option<unsafe extern \"C\" fn(arg1: *mut ifnet) -> *mut ::std::os::raw::c_void>,\n    pub pfq_addqueue: ::std::option::Option<\n        unsafe extern \"C\" fn(arg1: *mut ::std::os::raw::c_void, arg2: *mut pf_queuespec) -> ::std::os::raw::c_int,\n    >,\n    pub pfq_free: ::std::option::Option<unsafe extern \"C\" fn(arg1: *mut ::std::os::raw::c_void)>,\n    pub pfq_qstats: ::std::option::Option<\n        unsafe extern \"C\" fn(\n            arg1: *mut pf_queuespec,\n            arg2: *mut ::std::os::raw::c_void,\n            arg3: *mut ::std::os::raw::c_int,\n        ) -> ::std::os::raw::c_int,\n    >,\n    pub pfq_qlength:\n        ::std::option::Option<unsafe extern \"C\" fn(arg1: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_uint>,\n    pub pfq_enqueue:\n        ::std::option::Option<unsafe extern \"C\" fn(arg1: *mut ::std::os::raw::c_void, arg2: *mut mbuf) -> *mut mbuf>,\n    pub pfq_deq_begin: ::std::option::Option<\n        unsafe extern \"C\" fn(\n            arg1: *mut ::std::os::raw::c_void,\n            arg2: *mut *mut ::std::os::raw::c_void,\n            arg3: *mut mbuf_list,\n        ) -> *mut mbuf,\n    >,\n    pub pfq_deq_commit: ::std::option::Option<\n        unsafe extern \"C\" fn(arg1: *mut ::std::os::raw::c_void, arg2: *mut mbuf, arg3: *mut ::std::os::raw::c_void),\n    >,\n    pub pfq_purge: ::std::option::Option<unsafe extern \"C\" fn(arg1: *mut ::std::os::raw::c_void, arg2: *mut mbuf_list)>,\n}\n#[test]\nfn bindgen_test_layout_pfq_ops() {\n    const UNINIT: ::std::mem::MaybeUninit<pfq_ops> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfq_ops>(),\n        72usize,\n        concat!(\"Size of: \", stringify!(pfq_ops))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfq_ops>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfq_ops))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfq_alloc) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfq_ops), \"::\", stringify!(pfq_alloc))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfq_addqueue) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pfq_ops), \"::\", stringify!(pfq_addqueue))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfq_free) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pfq_ops), \"::\", stringify!(pfq_free))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfq_qstats) as usize - ptr as usize },\n        24usize,\n        concat!(\"Offset of field: \", stringify!(pfq_ops), \"::\", stringify!(pfq_qstats))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfq_qlength) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(pfq_ops), \"::\", stringify!(pfq_qlength))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfq_enqueue) as usize - ptr as usize },\n        40usize,\n        concat!(\"Offset of field: \", stringify!(pfq_ops), \"::\", stringify!(pfq_enqueue))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfq_deq_begin) as usize - ptr as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfq_ops),\n            \"::\",\n            stringify!(pfq_deq_begin)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfq_deq_commit) as usize - ptr as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfq_ops),\n            \"::\",\n            stringify!(pfq_deq_commit)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfq_purge) as usize - ptr as usize },\n        64usize,\n        concat!(\"Offset of field: \", stringify!(pfq_ops), \"::\", stringify!(pfq_purge))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_tagname {\n    pub entries: pf_tagname__bindgen_ty_1,\n    pub name: [::std::os::raw::c_char; 64usize],\n    pub tag: u_int16_t,\n    pub ref_: ::std::os::raw::c_int,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_tagname__bindgen_ty_1 {\n    pub tqe_next: *mut pf_tagname,\n    pub tqe_prev: *mut *mut pf_tagname,\n}\n#[test]\nfn bindgen_test_layout_pf_tagname__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_tagname__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_tagname__bindgen_ty_1>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pf_tagname__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_tagname__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_tagname__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqe_next) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_tagname__bindgen_ty_1),\n            \"::\",\n            stringify!(tqe_next)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tqe_prev) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pf_tagname__bindgen_ty_1),\n            \"::\",\n            stringify!(tqe_prev)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pf_tagname() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_tagname> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_tagname>(),\n        88usize,\n        concat!(\"Size of: \", stringify!(pf_tagname))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_tagname>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_tagname))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).entries) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_tagname), \"::\", stringify!(entries))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).name) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pf_tagname), \"::\", stringify!(name))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).tag) as usize - ptr as usize },\n        80usize,\n        concat!(\"Offset of field: \", stringify!(pf_tagname), \"::\", stringify!(tag))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ref_) as usize - ptr as usize },\n        84usize,\n        concat!(\"Offset of field: \", stringify!(pf_tagname), \"::\", stringify!(ref_))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pf_divert {\n    pub addr: pf_addr,\n    pub port: u_int16_t,\n    pub rdomain: u_int16_t,\n    pub type_: u_int8_t,\n}\n#[test]\nfn bindgen_test_layout_pf_divert() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_divert> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_divert>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(pf_divert))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_divert>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pf_divert))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_divert), \"::\", stringify!(addr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).port) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pf_divert), \"::\", stringify!(port))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rdomain) as usize - ptr as usize },\n        18usize,\n        concat!(\"Offset of field: \", stringify!(pf_divert), \"::\", stringify!(rdomain))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).type_) as usize - ptr as usize },\n        20usize,\n        concat!(\"Offset of field: \", stringify!(pf_divert), \"::\", stringify!(type_))\n    );\n}\npub const pf_divert_types_PF_DIVERT_NONE: pf_divert_types = 0;\npub const pf_divert_types_PF_DIVERT_TO: pf_divert_types = 1;\npub const pf_divert_types_PF_DIVERT_REPLY: pf_divert_types = 2;\npub const pf_divert_types_PF_DIVERT_PACKET: pf_divert_types = 3;\npub type pf_divert_types = ::std::os::raw::c_uint;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_pktdelay {\n    pub to: timeout,\n    pub m: *mut mbuf,\n    pub ifidx: u_int,\n}\n#[test]\nfn bindgen_test_layout_pf_pktdelay() {\n    const UNINIT: ::std::mem::MaybeUninit<pf_pktdelay> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pf_pktdelay>(),\n        88usize,\n        concat!(\"Size of: \", stringify!(pf_pktdelay))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pf_pktdelay>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pf_pktdelay))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).to) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pf_pktdelay), \"::\", stringify!(to))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).m) as usize - ptr as usize },\n        72usize,\n        concat!(\"Offset of field: \", stringify!(pf_pktdelay), \"::\", stringify!(m))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ifidx) as usize - ptr as usize },\n        80usize,\n        concat!(\"Offset of field: \", stringify!(pf_pktdelay), \"::\", stringify!(ifidx))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_rule {\n    pub action: u_int32_t,\n    pub ticket: u_int32_t,\n    pub nr: u_int32_t,\n    pub anchor: [::std::os::raw::c_char; 1024usize],\n    pub anchor_call: [::std::os::raw::c_char; 1024usize],\n    pub rule: pf_rule,\n}\n#[test]\nfn bindgen_test_layout_pfioc_rule() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_rule> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_rule>(),\n        3408usize,\n        concat!(\"Size of: \", stringify!(pfioc_rule))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_rule>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_rule))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).action) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_rule), \"::\", stringify!(action))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ticket) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_rule), \"::\", stringify!(ticket))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nr) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_rule), \"::\", stringify!(nr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor) as usize - ptr as usize },\n        12usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_rule), \"::\", stringify!(anchor))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor_call) as usize - ptr as usize },\n        1036usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_rule),\n            \"::\",\n            stringify!(anchor_call)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rule) as usize - ptr as usize },\n        2064usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_rule), \"::\", stringify!(rule))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_natlook {\n    pub saddr: pf_addr,\n    pub daddr: pf_addr,\n    pub rsaddr: pf_addr,\n    pub rdaddr: pf_addr,\n    pub rdomain: u_int16_t,\n    pub rrdomain: u_int16_t,\n    pub sport: u_int16_t,\n    pub dport: u_int16_t,\n    pub rsport: u_int16_t,\n    pub rdport: u_int16_t,\n    pub af: sa_family_t,\n    pub proto: u_int8_t,\n    pub direction: u_int8_t,\n}\n#[test]\nfn bindgen_test_layout_pfioc_natlook() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_natlook> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_natlook>(),\n        80usize,\n        concat!(\"Size of: \", stringify!(pfioc_natlook))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_natlook>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pfioc_natlook))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).saddr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_natlook), \"::\", stringify!(saddr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).daddr) as usize - ptr as usize },\n        16usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_natlook), \"::\", stringify!(daddr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rsaddr) as usize - ptr as usize },\n        32usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_natlook), \"::\", stringify!(rsaddr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rdaddr) as usize - ptr as usize },\n        48usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_natlook), \"::\", stringify!(rdaddr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rdomain) as usize - ptr as usize },\n        64usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_natlook),\n            \"::\",\n            stringify!(rdomain)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rrdomain) as usize - ptr as usize },\n        66usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_natlook),\n            \"::\",\n            stringify!(rrdomain)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).sport) as usize - ptr as usize },\n        68usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_natlook), \"::\", stringify!(sport))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).dport) as usize - ptr as usize },\n        70usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_natlook), \"::\", stringify!(dport))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rsport) as usize - ptr as usize },\n        72usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_natlook), \"::\", stringify!(rsport))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).rdport) as usize - ptr as usize },\n        74usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_natlook), \"::\", stringify!(rdport))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).af) as usize - ptr as usize },\n        76usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_natlook), \"::\", stringify!(af))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).proto) as usize - ptr as usize },\n        77usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_natlook), \"::\", stringify!(proto))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).direction) as usize - ptr as usize },\n        78usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_natlook),\n            \"::\",\n            stringify!(direction)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_state {\n    pub state: pfsync_state,\n}\n#[test]\nfn bindgen_test_layout_pfioc_state() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_state> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_state>(),\n        264usize,\n        concat!(\"Size of: \", stringify!(pfioc_state))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_state>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(pfioc_state))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).state) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_state), \"::\", stringify!(state))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_src_node_kill {\n    pub psnk_af: sa_family_t,\n    pub psnk_src: pf_rule_addr,\n    pub psnk_dst: pf_rule_addr,\n    pub psnk_killed: u_int,\n}\n#[test]\nfn bindgen_test_layout_pfioc_src_node_kill() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_src_node_kill> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_src_node_kill>(),\n        128usize,\n        concat!(\"Size of: \", stringify!(pfioc_src_node_kill))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_src_node_kill>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_src_node_kill))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psnk_af) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_src_node_kill),\n            \"::\",\n            stringify!(psnk_af)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psnk_src) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_src_node_kill),\n            \"::\",\n            stringify!(psnk_src)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psnk_dst) as usize - ptr as usize },\n        64usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_src_node_kill),\n            \"::\",\n            stringify!(psnk_dst)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psnk_killed) as usize - ptr as usize },\n        120usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_src_node_kill),\n            \"::\",\n            stringify!(psnk_killed)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_state_kill {\n    pub psk_pfcmp: pf_state_cmp,\n    pub psk_af: sa_family_t,\n    pub psk_proto: ::std::os::raw::c_int,\n    pub psk_src: pf_rule_addr,\n    pub psk_dst: pf_rule_addr,\n    pub psk_ifname: [::std::os::raw::c_char; 16usize],\n    pub psk_label: [::std::os::raw::c_char; 64usize],\n    pub psk_killed: u_int,\n    pub psk_rdomain: u_int16_t,\n}\n#[test]\nfn bindgen_test_layout_pfioc_state_kill() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_state_kill> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_state_kill>(),\n        224usize,\n        concat!(\"Size of: \", stringify!(pfioc_state_kill))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_state_kill>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_state_kill))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psk_pfcmp) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_kill),\n            \"::\",\n            stringify!(psk_pfcmp)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psk_af) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_kill),\n            \"::\",\n            stringify!(psk_af)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psk_proto) as usize - ptr as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_kill),\n            \"::\",\n            stringify!(psk_proto)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psk_src) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_kill),\n            \"::\",\n            stringify!(psk_src)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psk_dst) as usize - ptr as usize },\n        80usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_kill),\n            \"::\",\n            stringify!(psk_dst)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psk_ifname) as usize - ptr as usize },\n        136usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_kill),\n            \"::\",\n            stringify!(psk_ifname)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psk_label) as usize - ptr as usize },\n        152usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_kill),\n            \"::\",\n            stringify!(psk_label)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psk_killed) as usize - ptr as usize },\n        216usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_kill),\n            \"::\",\n            stringify!(psk_killed)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psk_rdomain) as usize - ptr as usize },\n        220usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_state_kill),\n            \"::\",\n            stringify!(psk_rdomain)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_states {\n    pub ps_len: usize,\n    pub ps_u: pfioc_states__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pfioc_states__bindgen_ty_1 {\n    pub psu_buf: caddr_t,\n    pub psu_states: *mut pfsync_state,\n}\n#[test]\nfn bindgen_test_layout_pfioc_states__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_states__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_states__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pfioc_states__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_states__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_states__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psu_buf) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_states__bindgen_ty_1),\n            \"::\",\n            stringify!(psu_buf)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psu_states) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_states__bindgen_ty_1),\n            \"::\",\n            stringify!(psu_states)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pfioc_states() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_states> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_states>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pfioc_states))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_states>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_states))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ps_len) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_states), \"::\", stringify!(ps_len))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ps_u) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_states), \"::\", stringify!(ps_u))\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct pfioc_src_nodes {\n    pub psn_len: usize,\n    pub psn_u: pfioc_src_nodes__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pfioc_src_nodes__bindgen_ty_1 {\n    pub psu_buf: caddr_t,\n    pub psu_src_nodes: *mut pf_src_node,\n}\n#[test]\nfn bindgen_test_layout_pfioc_src_nodes__bindgen_ty_1() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_src_nodes__bindgen_ty_1> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_src_nodes__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pfioc_src_nodes__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_src_nodes__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_src_nodes__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psu_buf) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_src_nodes__bindgen_ty_1),\n            \"::\",\n            stringify!(psu_buf)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psu_src_nodes) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_src_nodes__bindgen_ty_1),\n            \"::\",\n            stringify!(psu_src_nodes)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pfioc_src_nodes() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_src_nodes> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_src_nodes>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pfioc_src_nodes))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_src_nodes>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_src_nodes))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psn_len) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_src_nodes),\n            \"::\",\n            stringify!(psn_len)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).psn_u) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_src_nodes),\n            \"::\",\n            stringify!(psn_u)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_tm {\n    pub timeout: ::std::os::raw::c_int,\n    pub seconds: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_pfioc_tm() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_tm> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_tm>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pfioc_tm))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_tm>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pfioc_tm))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).timeout) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_tm), \"::\", stringify!(timeout))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).seconds) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_tm), \"::\", stringify!(seconds))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_limit {\n    pub index: ::std::os::raw::c_int,\n    pub limit: ::std::os::raw::c_uint,\n}\n#[test]\nfn bindgen_test_layout_pfioc_limit() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_limit> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_limit>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pfioc_limit))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_limit>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pfioc_limit))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).index) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_limit), \"::\", stringify!(index))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).limit) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_limit), \"::\", stringify!(limit))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_ruleset {\n    pub nr: u_int32_t,\n    pub path: [::std::os::raw::c_char; 1024usize],\n    pub name: [::std::os::raw::c_char; 64usize],\n}\n#[test]\nfn bindgen_test_layout_pfioc_ruleset() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_ruleset> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_ruleset>(),\n        1092usize,\n        concat!(\"Size of: \", stringify!(pfioc_ruleset))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_ruleset>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pfioc_ruleset))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nr) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_ruleset), \"::\", stringify!(nr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).path) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_ruleset), \"::\", stringify!(path))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).name) as usize - ptr as usize },\n        1028usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_ruleset), \"::\", stringify!(name))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_trans {\n    pub size: ::std::os::raw::c_int,\n    pub esize: ::std::os::raw::c_int,\n    pub array: *mut pfioc_trans_pfioc_trans_e,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_trans_pfioc_trans_e {\n    pub type_: ::std::os::raw::c_int,\n    pub anchor: [::std::os::raw::c_char; 1024usize],\n    pub ticket: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_pfioc_trans_pfioc_trans_e() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_trans_pfioc_trans_e> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_trans_pfioc_trans_e>(),\n        1032usize,\n        concat!(\"Size of: \", stringify!(pfioc_trans_pfioc_trans_e))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_trans_pfioc_trans_e>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pfioc_trans_pfioc_trans_e))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).type_) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_trans_pfioc_trans_e),\n            \"::\",\n            stringify!(type_)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).anchor) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_trans_pfioc_trans_e),\n            \"::\",\n            stringify!(anchor)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ticket) as usize - ptr as usize },\n        1028usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_trans_pfioc_trans_e),\n            \"::\",\n            stringify!(ticket)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pfioc_trans() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_trans> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_trans>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(pfioc_trans))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_trans>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_trans))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).size) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_trans), \"::\", stringify!(size))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).esize) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_trans), \"::\", stringify!(esize))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).array) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_trans), \"::\", stringify!(array))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_queue {\n    pub ticket: u_int32_t,\n    pub nr: u_int,\n    pub queue: pf_queuespec,\n}\n#[test]\nfn bindgen_test_layout_pfioc_queue() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_queue> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_queue>(),\n        272usize,\n        concat!(\"Size of: \", stringify!(pfioc_queue))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_queue>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_queue))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ticket) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_queue), \"::\", stringify!(ticket))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nr) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_queue), \"::\", stringify!(nr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).queue) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_queue), \"::\", stringify!(queue))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_qstats {\n    pub ticket: u_int32_t,\n    pub nr: u_int32_t,\n    pub queue: pf_queuespec,\n    pub buf: *mut ::std::os::raw::c_void,\n    pub nbytes: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_pfioc_qstats() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_qstats> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_qstats>(),\n        288usize,\n        concat!(\"Size of: \", stringify!(pfioc_qstats))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_qstats>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_qstats))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).ticket) as usize - ptr as usize },\n        0usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_qstats), \"::\", stringify!(ticket))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nr) as usize - ptr as usize },\n        4usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_qstats), \"::\", stringify!(nr))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).queue) as usize - ptr as usize },\n        8usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_qstats), \"::\", stringify!(queue))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).buf) as usize - ptr as usize },\n        272usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_qstats), \"::\", stringify!(buf))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).nbytes) as usize - ptr as usize },\n        280usize,\n        concat!(\"Offset of field: \", stringify!(pfioc_qstats), \"::\", stringify!(nbytes))\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_table {\n    pub pfrio_table: pfr_table,\n    pub pfrio_buffer: *mut ::std::os::raw::c_void,\n    pub pfrio_esize: ::std::os::raw::c_int,\n    pub pfrio_size: ::std::os::raw::c_int,\n    pub pfrio_size2: ::std::os::raw::c_int,\n    pub pfrio_nadd: ::std::os::raw::c_int,\n    pub pfrio_ndel: ::std::os::raw::c_int,\n    pub pfrio_nchange: ::std::os::raw::c_int,\n    pub pfrio_flags: ::std::os::raw::c_int,\n    pub pfrio_ticket: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_pfioc_table() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_table> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_table>(),\n        1104usize,\n        concat!(\"Size of: \", stringify!(pfioc_table))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_table>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_table))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_table) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_table)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_buffer) as usize - ptr as usize },\n        1064usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_buffer)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_esize) as usize - ptr as usize },\n        1072usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_esize)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_size) as usize - ptr as usize },\n        1076usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_size)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_size2) as usize - ptr as usize },\n        1080usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_size2)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_nadd) as usize - ptr as usize },\n        1084usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_nadd)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_ndel) as usize - ptr as usize },\n        1088usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_ndel)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_nchange) as usize - ptr as usize },\n        1092usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_nchange)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_flags) as usize - ptr as usize },\n        1096usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_flags)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfrio_ticket) as usize - ptr as usize },\n        1100usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_table),\n            \"::\",\n            stringify!(pfrio_ticket)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_iface {\n    pub pfiio_name: [::std::os::raw::c_char; 16usize],\n    pub pfiio_buffer: *mut ::std::os::raw::c_void,\n    pub pfiio_esize: ::std::os::raw::c_int,\n    pub pfiio_size: ::std::os::raw::c_int,\n    pub pfiio_nzero: ::std::os::raw::c_int,\n    pub pfiio_flags: ::std::os::raw::c_int,\n}\n#[test]\nfn bindgen_test_layout_pfioc_iface() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_iface> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_iface>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(pfioc_iface))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_iface>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pfioc_iface))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfiio_name) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_iface),\n            \"::\",\n            stringify!(pfiio_name)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfiio_buffer) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_iface),\n            \"::\",\n            stringify!(pfiio_buffer)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfiio_esize) as usize - ptr as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_iface),\n            \"::\",\n            stringify!(pfiio_esize)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfiio_size) as usize - ptr as usize },\n        28usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_iface),\n            \"::\",\n            stringify!(pfiio_size)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfiio_nzero) as usize - ptr as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_iface),\n            \"::\",\n            stringify!(pfiio_nzero)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).pfiio_flags) as usize - ptr as usize },\n        36usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_iface),\n            \"::\",\n            stringify!(pfiio_flags)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfioc_synflwats {\n    pub hiwat: u_int32_t,\n    pub lowat: u_int32_t,\n}\n#[test]\nfn bindgen_test_layout_pfioc_synflwats() {\n    const UNINIT: ::std::mem::MaybeUninit<pfioc_synflwats> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<pfioc_synflwats>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pfioc_synflwats))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<pfioc_synflwats>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pfioc_synflwats))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).hiwat) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_synflwats),\n            \"::\",\n            stringify!(hiwat)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).lowat) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pfioc_synflwats),\n            \"::\",\n            stringify!(lowat)\n        )\n    );\n}\nunsafe extern \"C\" {\n    pub static mut pf_anchors: pf_anchor_global;\n}\nunsafe extern \"C\" {\n    pub static mut pf_main_anchor: pf_anchor;\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct tcphdr {\n    _unused: [u8; 0],\n}\nunsafe extern \"C\" {\n    pub fn pf_init_ruleset(arg1: *mut pf_ruleset);\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_setup(\n        arg1: *mut pf_rule,\n        arg2: *const pf_ruleset,\n        arg3: *const ::std::os::raw::c_char,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_copyout(\n        arg1: *const pf_ruleset,\n        arg2: *const pf_rule,\n        arg3: *mut pfioc_rule,\n    ) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn pf_remove_anchor(arg1: *mut pf_rule);\n}\nunsafe extern \"C\" {\n    pub fn pf_remove_if_empty_ruleset(arg1: *mut pf_ruleset);\n}\nunsafe extern \"C\" {\n    pub fn pf_find_anchor(arg1: *const ::std::os::raw::c_char) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_find_ruleset(arg1: *const ::std::os::raw::c_char) -> *mut pf_ruleset;\n}\nunsafe extern \"C\" {\n    pub fn pf_get_leaf_ruleset(\n        arg1: *mut ::std::os::raw::c_char,\n        arg2: *mut *mut ::std::os::raw::c_char,\n    ) -> *mut pf_ruleset;\n}\nunsafe extern \"C\" {\n    pub fn pf_create_anchor(arg1: *mut pf_anchor, arg2: *const ::std::os::raw::c_char) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_find_or_create_ruleset(arg1: *const ::std::os::raw::c_char) -> *mut pf_ruleset;\n}\nunsafe extern \"C\" {\n    pub fn pf_rs_initialize();\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_rele(arg1: *mut pf_anchor);\n}\nunsafe extern \"C\" {\n    pub fn pf_anchor_take(arg1: *mut pf_anchor) -> *mut pf_anchor;\n}\nunsafe extern \"C\" {\n    pub fn pf_osfp_add(arg1: *mut pf_osfp_ioctl) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn pf_osfp_fingerprint_hdr(\n        arg1: *const ip,\n        arg2: *const ip6_hdr,\n        arg3: *const tcphdr,\n    ) -> *mut pf_os_fingerprint_pf_osfp_enlist;\n}\nunsafe extern \"C\" {\n    pub fn pf_osfp_flush();\n}\nunsafe extern \"C\" {\n    pub fn pf_osfp_get(arg1: *mut pf_osfp_ioctl) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn pf_osfp_initialize();\n}\nunsafe extern \"C\" {\n    pub fn pf_osfp_match(arg1: *mut pf_os_fingerprint_pf_osfp_enlist, arg2: pf_osfp_t) -> ::std::os::raw::c_int;\n}\nunsafe extern \"C\" {\n    pub fn pf_osfp_validate() -> *mut pf_os_fingerprint;\n}\npub type __builtin_va_list = [__va_list_tag; 1usize];\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __va_list_tag {\n    pub gp_offset: ::std::os::raw::c_uint,\n    pub fp_offset: ::std::os::raw::c_uint,\n    pub overflow_arg_area: *mut ::std::os::raw::c_void,\n    pub reg_save_area: *mut ::std::os::raw::c_void,\n}\n#[test]\nfn bindgen_test_layout___va_list_tag() {\n    const UNINIT: ::std::mem::MaybeUninit<__va_list_tag> = ::std::mem::MaybeUninit::uninit();\n    let ptr = UNINIT.as_ptr();\n    assert_eq!(\n        ::std::mem::size_of::<__va_list_tag>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(__va_list_tag))\n    );\n    assert_eq!(\n        ::std::mem::align_of::<__va_list_tag>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__va_list_tag))\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).gp_offset) as usize - ptr as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__va_list_tag),\n            \"::\",\n            stringify!(gp_offset)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).fp_offset) as usize - ptr as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__va_list_tag),\n            \"::\",\n            stringify!(fp_offset)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).overflow_arg_area) as usize - ptr as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__va_list_tag),\n            \"::\",\n            stringify!(overflow_arg_area)\n        )\n    );\n    assert_eq!(\n        unsafe { ::std::ptr::addr_of!((*ptr).reg_save_area) as usize - ptr as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__va_list_tag),\n            \"::\",\n            stringify!(reg_save_area)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct witness {\n    pub _address: u8,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct process {\n    pub _address: u8,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ifaddr {\n    pub _address: u8,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct rtentry {\n    pub _address: u8,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pfi_dynaddr {\n    pub _address: u8,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_state {\n    pub _address: u8,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pf_state_key {\n    pub _address: u8,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct mbuf {\n    _unused: [u8; 0],\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/redir/tcprelay/mod.rs",
    "content": "//! Shadowsocks TCP transparent proxy\n\nuse std::{\n    io,\n    net::{IpAddr, SocketAddr},\n    sync::Arc,\n    time::Duration,\n};\n\nuse log::{debug, error, info, trace};\nuse shadowsocks::{ServerAddr, lookup_then, net::TcpListener as ShadowTcpListener, relay::socks5::Address};\nuse tokio::{\n    net::{TcpListener, TcpStream},\n    time,\n};\n\nuse crate::{\n    config::RedirType,\n    local::{\n        context::ServiceContext,\n        loadbalancing::PingBalancer,\n        net::AutoProxyClientStream,\n        redir::redir_ext::{TcpListenerRedirExt, TcpStreamRedirExt},\n        utils::{establish_tcp_tunnel, establish_tcp_tunnel_bypassed},\n    },\n    net::utils::to_ipv4_mapped,\n};\n\n#[allow(unused_imports)]\nmod sys;\n\n/// Established Client Transparent Proxy\n///\n/// This method must be called after handshaking with client (for example, socks5 handshaking)\nasync fn establish_client_tcp_redir(\n    context: Arc<ServiceContext>,\n    balancer: PingBalancer,\n    mut stream: TcpStream,\n    peer_addr: SocketAddr,\n    addr: &Address,\n) -> io::Result<()> {\n    if balancer.is_empty() {\n        let mut remote = AutoProxyClientStream::connect_bypassed(context, addr).await?;\n        return establish_tcp_tunnel_bypassed(&mut stream, &mut remote, peer_addr, addr).await;\n    }\n\n    let server = balancer.best_tcp_server();\n    let svr_cfg = server.server_config();\n\n    let mut remote =\n        AutoProxyClientStream::connect_with_opts(context, &server, addr, server.connect_opts_ref()).await?;\n\n    establish_tcp_tunnel(svr_cfg, &mut stream, &mut remote, peer_addr, addr).await\n}\n\nasync fn handle_redir_client(\n    context: Arc<ServiceContext>,\n    balancer: PingBalancer,\n    s: TcpStream,\n    peer_addr: SocketAddr,\n    mut daddr: SocketAddr,\n) -> io::Result<()> {\n    // Get forward address from socket\n    //\n    // Try to convert IPv4 mapped IPv6 address for dual-stack mode.\n    if let SocketAddr::V6(ref a) = daddr\n        && let Some(v4) = to_ipv4_mapped(a.ip())\n    {\n        daddr = SocketAddr::new(IpAddr::from(v4), a.port());\n    }\n    let target_addr = Address::from(daddr);\n    establish_client_tcp_redir(context, balancer, s, peer_addr, &target_addr).await\n}\n\n/// Redir TCP server instance\npub struct RedirTcpServer {\n    context: Arc<ServiceContext>,\n    listener: TcpListener,\n    balancer: PingBalancer,\n    redir_ty: RedirType,\n}\n\nimpl RedirTcpServer {\n    pub(crate) async fn new(\n        context: Arc<ServiceContext>,\n        client_config: &ServerAddr,\n        balancer: PingBalancer,\n        redir_ty: RedirType,\n    ) -> io::Result<Self> {\n        let listener = match *client_config {\n            ServerAddr::SocketAddr(ref saddr) => {\n                TcpListener::bind_redir(redir_ty, *saddr, context.accept_opts()).await?\n            }\n            ServerAddr::DomainName(ref dname, port) => {\n                lookup_then!(context.context_ref(), dname, port, |addr| {\n                    TcpListener::bind_redir(redir_ty, addr, context.accept_opts()).await\n                })?\n                .1\n            }\n        };\n\n        Ok(Self {\n            context,\n            listener,\n            balancer,\n            redir_ty,\n        })\n    }\n\n    /// Get server local address\n    pub fn local_addr(&self) -> io::Result<SocketAddr> {\n        self.listener.local_addr()\n    }\n\n    /// Start serving\n    pub async fn run(self) -> io::Result<()> {\n        let listener = ShadowTcpListener::from_listener(self.listener, self.context.accept_opts())?;\n\n        let actual_local_addr = listener.local_addr().expect(\"determine port bound to\");\n\n        info!(\n            \"shadowsocks TCP redirect ({}) listening on {}\",\n            self.redir_ty, actual_local_addr\n        );\n\n        loop {\n            let (socket, peer_addr) = match listener.accept().await {\n                Ok(s) => s,\n                Err(err) => {\n                    error!(\"accept failed with error: {}\", err);\n                    time::sleep(Duration::from_secs(1)).await;\n                    continue;\n                }\n            };\n\n            trace!(\"got connection {}\", peer_addr);\n\n            let context = self.context.clone();\n            let balancer = self.balancer.clone();\n            let redir_ty = self.redir_ty;\n            tokio::spawn(async move {\n                let dst_addr = match socket.destination_addr(redir_ty) {\n                    Ok(d) => d,\n                    Err(err) => {\n                        error!(\n                            \"TCP redirect couldn't get destination, peer: {}, error: {}\",\n                            peer_addr, err\n                        );\n                        return;\n                    }\n                };\n\n                if let Err(err) = handle_redir_client(context, balancer, socket, peer_addr, dst_addr).await {\n                    debug!(\"TCP redirect client, error: {:?}\", err);\n                }\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/redir/tcprelay/sys/mod.rs",
    "content": "use cfg_if::cfg_if;\n\ncfg_if! {\n    if #[cfg(unix)] {\n        mod unix;\n        pub use self::unix::*;\n    } else if #[cfg(windows)] {\n        mod windows;\n        pub use self::windows::*;\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/redir/tcprelay/sys/unix/bsd.rs",
    "content": "use std::{\n    io::{self, Error, ErrorKind},\n    net::SocketAddr,\n};\n\nuse log::warn;\nuse shadowsocks::net::{AcceptOpts, is_dual_stack_addr, set_tcp_fastopen};\nuse socket2::Protocol;\nuse tokio::net::{TcpListener, TcpSocket, TcpStream};\n\nuse crate::{\n    config::RedirType,\n    local::redir::{\n        redir_ext::{TcpListenerRedirExt, TcpStreamRedirExt},\n        sys::set_ipv6_only,\n    },\n};\n\nimpl TcpListenerRedirExt for TcpListener {\n    async fn bind_redir(ty: RedirType, addr: SocketAddr, accept_opts: AcceptOpts) -> io::Result<TcpListener> {\n        match ty {\n            #[cfg(any(target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"macos\", target_os = \"ios\"))]\n            RedirType::PacketFilter => {}\n\n            #[cfg(any(target_os = \"freebsd\", target_os = \"macos\", target_os = \"ios\"))]\n            RedirType::IpFirewall => {}\n\n            _ => {\n                return Err(Error::new(\n                    ErrorKind::InvalidInput,\n                    \"not supported tcp transparent proxy type\",\n                ));\n            }\n        }\n\n        // BSD platform doesn't have any special logic\n        let socket = match addr {\n            SocketAddr::V4(..) => TcpSocket::new_v4()?,\n            SocketAddr::V6(..) => TcpSocket::new_v6()?,\n        };\n\n        // On platforms with Berkeley-derived sockets, this allows to quickly\n        // rebind a socket, without needing to wait for the OS to clean up the\n        // previous one.\n        //\n        // On Windows, this allows rebinding sockets which are actively in use,\n        // which allows “socket hijacking”, so we explicitly don't set it here.\n        // https://docs.microsoft.com/en-us/windows/win32/winsock/using-so-reuseaddr-and-so-exclusiveaddruse\n        #[cfg(unix)]\n        socket.set_reuseaddr(true)?;\n\n        let set_dual_stack = is_dual_stack_addr(&addr);\n        if set_dual_stack {\n            // Try to bind dual-stack address\n            match set_ipv6_only(&socket, false) {\n                Ok(..) => {\n                    // bind()\n                    if let Err(err) = socket.bind(addr) {\n                        warn!(\n                            \"bind() dual-stack address {} failed, error: {}, fallback to IPV6_V6ONLY=false\",\n                            addr, err\n                        );\n\n                        if let Err(err) = set_ipv6_only(&socket, true) {\n                            warn!(\n                                \"set IPV6_V6ONLY=true failed, error: {}, bind() to {} directly\",\n                                err, addr\n                            );\n                        }\n\n                        socket.bind(addr)?;\n                    }\n                }\n                Err(err) => {\n                    warn!(\n                        \"set IPV6_V6ONLY=false failed, error: {}, bind() to {} directly\",\n                        err, addr\n                    );\n                    socket.bind(addr)?;\n                }\n            }\n        } else {\n            socket.bind(addr)?;\n        }\n\n        // mio's default backlog is 1024\n        let listener = socket.listen(1024)?;\n\n        if accept_opts.tcp.fastopen {\n            set_tcp_fastopen(&listener)?;\n        }\n\n        Ok(listener)\n    }\n}\n\nimpl TcpStreamRedirExt for TcpStream {\n    fn destination_addr(&self, ty: RedirType) -> io::Result<SocketAddr> {\n        match ty {\n            #[cfg(any(target_os = \"freebsd\", target_os = \"macos\", target_os = \"ios\"))]\n            RedirType::PacketFilter => {\n                use crate::local::redir::sys::bsd_pf::PF;\n\n                let peer_addr = self.peer_addr()?;\n                let bind_addr = self.local_addr()?;\n\n                PF.natlook(&bind_addr, &peer_addr, Protocol::TCP)\n            }\n            #[cfg(target_os = \"openbsd\")] // in OpenBSD, we can get TCP destination address with getsockname()\n            RedirType::PacketFilter => self.local_addr(),\n            #[cfg(any(target_os = \"freebsd\", target_os = \"macos\", target_os = \"ios\"))]\n            RedirType::IpFirewall => {\n                // ## IPFW\n                //\n                // For IPFW, uses getsockname() to retrieve destination address\n                //\n                // FreeBSD: https://www.freebsd.org/doc/handbook/firewalls-ipfw.html\n                self.local_addr()\n            }\n            _ => unreachable!(\"not supported tcp transparent proxy type\"),\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/redir/tcprelay/sys/unix/linux.rs",
    "content": "use std::{\n    io::{self, Error, ErrorKind},\n    mem,\n    net::SocketAddr,\n    os::unix::io::AsRawFd,\n};\n\nuse log::warn;\nuse shadowsocks::net::{AcceptOpts, is_dual_stack_addr, set_tcp_fastopen};\nuse socket2::SockAddr;\nuse tokio::net::{TcpListener, TcpSocket, TcpStream};\n\nuse crate::{\n    config::RedirType,\n    local::redir::{\n        redir_ext::{TcpListenerRedirExt, TcpStreamRedirExt},\n        sys::set_ipv6_only,\n    },\n};\n\nimpl TcpListenerRedirExt for TcpListener {\n    async fn bind_redir(ty: RedirType, addr: SocketAddr, accept_opts: AcceptOpts) -> io::Result<Self> {\n        match ty {\n            RedirType::Redirect => {\n                // REDIRECT rule doesn't need to set IP_TRANSPARENT\n\n                let socket = match addr {\n                    SocketAddr::V4(..) => TcpSocket::new_v4()?,\n                    SocketAddr::V6(..) => TcpSocket::new_v6()?,\n                };\n\n                // On platforms with Berkeley-derived sockets, this allows to quickly\n                // rebind a socket, without needing to wait for the OS to clean up the\n                // previous one.\n                //\n                // On Windows, this allows rebinding sockets which are actively in use,\n                // which allows “socket hijacking”, so we explicitly don't set it here.\n                // https://docs.microsoft.com/en-us/windows/win32/winsock/using-so-reuseaddr-and-so-exclusiveaddruse\n                #[cfg(unix)]\n                socket.set_reuseaddr(true)?;\n\n                let set_dual_stack = is_dual_stack_addr(&addr);\n                if set_dual_stack {\n                    // Try to bind dual-stack address\n                    match set_ipv6_only(&socket, false) {\n                        Ok(..) => {\n                            // bind()\n                            if let Err(err) = socket.bind(addr) {\n                                warn!(\n                                    \"bind() dual-stack address {} failed, error: {}, fallback to IPV6_V6ONLY=true\",\n                                    addr, err\n                                );\n\n                                if let Err(err) = set_ipv6_only(&socket, true) {\n                                    warn!(\n                                        \"set IPV6_V6ONLY=true failed, error: {}, bind() to {} directly\",\n                                        err, addr\n                                    );\n                                }\n\n                                socket.bind(addr)?;\n                            }\n                        }\n                        Err(err) => {\n                            warn!(\n                                \"set IPV6_V6ONLY=false failed, error: {}, bind() to {} directly\",\n                                err, addr\n                            );\n                            socket.bind(addr)?;\n                        }\n                    }\n                } else {\n                    // bind, listen as original\n                    socket.bind(addr)?;\n                }\n\n                // mio's default backlog is 1024\n                let listener = socket.listen(1024)?;\n\n                if accept_opts.tcp.fastopen {\n                    set_tcp_fastopen(&listener)?;\n                }\n\n                Ok(listener)\n            }\n            RedirType::TProxy => {\n                // TPROXY rule requires IP_TRANSPARENT\n                create_redir_listener(addr, accept_opts).await\n            }\n            _ => Err(Error::new(\n                ErrorKind::InvalidInput,\n                \"not supported tcp transparent proxy type\",\n            )),\n        }\n    }\n}\n\nimpl TcpStreamRedirExt for TcpStream {\n    fn destination_addr(&self, ty: RedirType) -> io::Result<SocketAddr> {\n        match ty {\n            RedirType::Redirect => get_original_destination_addr(self),\n            RedirType::TProxy => {\n                // For TPROXY, uses getsockname() to retrieve original destination address\n                self.local_addr()\n            }\n            _ => unreachable!(\"not supported tcp transparent proxy type\"),\n        }\n    }\n}\n\nfn get_original_destination_addr(s: &TcpStream) -> io::Result<SocketAddr> {\n    let fd = s.as_raw_fd();\n\n    unsafe {\n        let (_, target_addr) = SockAddr::try_init(|target_addr, target_addr_len| {\n            // No sufficient method to know whether the destination IPv4 or IPv6.\n            // Follow the method in shadowsocks-libev.\n\n            let ret = libc::getsockopt(\n                fd,\n                libc::SOL_IPV6,\n                libc::IP6T_SO_ORIGINAL_DST,\n                target_addr as *mut _,\n                target_addr_len, // libc::socklen_t\n            );\n\n            if ret == 0 {\n                return Ok(());\n            } else {\n                let err = Error::last_os_error();\n                match err.raw_os_error() {\n                    None => return Err(err),\n                    // ENOPROTOOPT, EOPNOTSUPP (ENOTSUP): IP6T_SO_ORIGINAL_DST doesn't exist\n                    // ENOENT: Destination address is not IPv6\n                    #[allow(unreachable_patterns)]\n                    Some(libc::ENOPROTOOPT) | Some(libc::ENOENT) | Some(libc::EOPNOTSUPP) | Some(libc::ENOTSUP) => {}\n                    Some(..) => return Err(err),\n                }\n            }\n\n            let ret = libc::getsockopt(\n                fd,\n                libc::SOL_IP,\n                libc::SO_ORIGINAL_DST,\n                target_addr as *mut _,\n                target_addr_len, // libc::socklen_t\n            );\n\n            if ret != 0 {\n                let err = Error::last_os_error();\n                return Err(err);\n            }\n\n            Ok(())\n        })?;\n\n        // Convert sockaddr_storage to SocketAddr\n        Ok(target_addr.as_socket().expect(\"SocketAddr\"))\n    }\n}\n\nfn set_ip_transparent(level: libc::c_int, socket: &TcpSocket) -> io::Result<()> {\n    let fd = socket.as_raw_fd();\n\n    let opt = match level {\n        libc::IPPROTO_IP => libc::IP_TRANSPARENT,\n        libc::IPPROTO_IPV6 => libc::IPV6_TRANSPARENT,\n        _ => unreachable!(\"level can only be IPPROTO_IP and IPPROTO_IPV6\"),\n    };\n\n    let enable: libc::c_int = 1;\n\n    unsafe {\n        let ret = libc::setsockopt(\n            fd,\n            level,\n            opt,\n            &enable as *const _ as *const _,\n            mem::size_of_val(&enable) as libc::socklen_t,\n        );\n\n        if ret != 0 {\n            return Err(Error::last_os_error());\n        }\n    }\n\n    Ok(())\n}\n\nasync fn create_redir_listener(addr: SocketAddr, accept_opts: AcceptOpts) -> io::Result<TcpListener> {\n    let socket = match addr {\n        SocketAddr::V4(..) => TcpSocket::new_v4()?,\n        SocketAddr::V6(..) => TcpSocket::new_v6()?,\n    };\n\n    // For Linux 2.4+ TPROXY\n    // Sockets have to set IP_TRANSPARENT, IPV6_TRANSPARENT for retrieving original destination by getsockname()\n    let level = match addr {\n        SocketAddr::V4(..) => libc::IPPROTO_IP,\n        SocketAddr::V6(..) => libc::IPPROTO_IPV6,\n    };\n\n    set_ip_transparent(level, &socket)?;\n\n    // On platforms with Berkeley-derived sockets, this allows to quickly\n    // rebind a socket, without needing to wait for the OS to clean up the\n    // previous one.\n    //\n    // On Windows, this allows rebinding sockets which are actively in use,\n    // which allows “socket hijacking”, so we explicitly don't set it here.\n    // https://docs.microsoft.com/en-us/windows/win32/winsock/using-so-reuseaddr-and-so-exclusiveaddruse\n    #[cfg(unix)]\n    socket.set_reuseaddr(true)?;\n\n    let set_dual_stack = is_dual_stack_addr(&addr);\n    if set_dual_stack {\n        // set IP_TRANSPARENT before bind()\n        set_ip_transparent(libc::IPPROTO_IP, &socket)?;\n\n        // Try to bind dual-stack address\n        match set_ipv6_only(&socket, false) {\n            Ok(..) => {\n                // bind()\n                if let Err(err) = socket.bind(addr) {\n                    warn!(\n                        \"bind() dual-stack address {} failed, error: {}, fallback to IPV6_V6ONLY=true\",\n                        addr, err\n                    );\n\n                    if let Err(err) = set_ipv6_only(&socket, true) {\n                        warn!(\n                            \"set IPV6_V6ONLY=true failed, error: {}, bind() to {} directly\",\n                            err, addr\n                        );\n                    }\n\n                    socket.bind(addr)?;\n                }\n            }\n            Err(err) => {\n                warn!(\n                    \"set IPV6_V6ONLY=false failed, error: {}, bind() to {} directly\",\n                    err, addr\n                );\n                socket.bind(addr)?;\n            }\n        }\n    } else {\n        // bind, listen as original\n        socket.bind(addr)?;\n    }\n\n    // listen backlogs = 1024 as mio's default\n    let listener = socket.listen(1024)?;\n\n    if accept_opts.tcp.fastopen {\n        set_tcp_fastopen(&listener)?;\n    }\n\n    Ok(listener)\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/redir/tcprelay/sys/unix/mod.rs",
    "content": "use cfg_if::cfg_if;\n\ncfg_if! {\n    if #[cfg(any(target_os = \"linux\", target_os = \"android\"))] {\n        mod linux;\n        pub use self::linux::*;\n    } else if #[cfg(any(target_os = \"macos\",\n                        target_os = \"ios\",\n                        target_os = \"freebsd\",\n                        target_os = \"openbsd\"))] {\n        mod bsd;\n        pub use self::bsd::*;\n    } else {\n        mod not_supported;\n        pub use self::not_supported::*;\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/redir/tcprelay/sys/unix/not_supported.rs",
    "content": "use std::{io, net::SocketAddr};\n\nuse shadowsocks::net::AcceptOpts;\nuse tokio::net::{TcpListener, TcpStream};\n\nuse crate::{\n    config::RedirType,\n    local::redir::redir_ext::{TcpListenerRedirExt, TcpStreamRedirExt},\n};\n\nimpl TcpListenerRedirExt for TcpListener {\n    async fn bind_redir(_ty: RedirType, _addr: SocketAddr, _accept_opts: AcceptOpts) -> io::Result<TcpListener> {\n        unimplemented!(\"TCP transparent proxy is not supported on this platform\")\n    }\n}\n\nimpl TcpStreamRedirExt for TcpStream {\n    fn destination_addr(&self, _ty: RedirType) -> io::Result<SocketAddr> {\n        unimplemented!(\"TCP transparent proxy is not supported on this platform\")\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/redir/tcprelay/sys/windows/mod.rs",
    "content": "use std::{\n    io::{self, Error, ErrorKind},\n    net::SocketAddr,\n};\n\nuse shadowsocks::net::AcceptOpts;\nuse tokio::net::{TcpListener, TcpStream};\n\nuse crate::{\n    config::RedirType,\n    local::redir::redir_ext::{TcpListenerRedirExt, TcpStreamRedirExt},\n};\n\nimpl TcpListenerRedirExt for TcpListener {\n    async fn bind_redir(_ty: RedirType, _addr: SocketAddr, _accept_opts: AcceptOpts) -> io::Result<TcpListener> {\n        let err = Error::new(\n            ErrorKind::InvalidInput,\n            \"not supported tcp transparent proxy on Windows\",\n        );\n        Err(err)\n    }\n}\n\nimpl TcpStreamRedirExt for TcpStream {\n    fn destination_addr(&self, _ty: RedirType) -> io::Result<SocketAddr> {\n        unreachable!(\"not supported tcp transparent on Windows\")\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/redir/udprelay/mod.rs",
    "content": "//! UDP transparent proxy\n\nuse std::{\n    io::{self, ErrorKind},\n    net::{IpAddr, SocketAddr},\n    sync::Arc,\n    time::Duration,\n};\n\nuse log::{debug, error, info, trace, warn};\nuse lru_time_cache::LruCache;\nuse shadowsocks::{\n    ServerAddr, lookup_then,\n    net::{ConnectOpts, get_ip_stack_capabilities},\n    relay::{socks5::Address, udprelay::MAXIMUM_UDP_PAYLOAD_SIZE},\n};\nuse tokio::{sync::Mutex, task::JoinHandle, time};\n\nuse crate::{\n    config::RedirType,\n    local::{\n        context::ServiceContext,\n        loadbalancing::PingBalancer,\n        net::{UdpAssociationManager, UdpInboundWrite},\n        redir::redir_ext::{RedirSocketOpts, UdpSocketRedirExt},\n    },\n    net::utils::to_ipv4_mapped,\n};\n\nuse self::sys::UdpRedirSocket;\n\nmod sys;\n\nconst INBOUND_SOCKET_CACHE_EXPIRATION: Duration = Duration::from_secs(60);\nconst INBOUND_SOCKET_CACHE_CAPACITY: usize = 256;\n\nstruct UdpRedirInboundCache {\n    cache: Arc<Mutex<LruCache<SocketAddr, Arc<UdpRedirSocket>>>>,\n    watcher: JoinHandle<()>,\n}\n\nimpl Drop for UdpRedirInboundCache {\n    fn drop(&mut self) {\n        self.watcher.abort();\n    }\n}\n\nimpl UdpRedirInboundCache {\n    fn new() -> Self {\n        let cache = Arc::new(Mutex::new(LruCache::with_expiry_duration_and_capacity(\n            INBOUND_SOCKET_CACHE_EXPIRATION,\n            INBOUND_SOCKET_CACHE_CAPACITY,\n        )));\n\n        let watcher = {\n            let cache = cache.clone();\n            tokio::spawn(async move {\n                loop {\n                    tokio::time::sleep(INBOUND_SOCKET_CACHE_EXPIRATION).await;\n                    let _ = cache.lock().await.iter();\n                }\n            })\n        };\n\n        Self { cache, watcher }\n    }\n}\n\n#[derive(Clone)]\nstruct UdpRedirInboundWriter {\n    redir_ty: RedirType,\n    socket_opts: RedirSocketOpts,\n    inbound_cache: Arc<UdpRedirInboundCache>,\n}\n\nimpl UdpRedirInboundWriter {\n    #[allow(unused_variables, clippy::needless_update)]\n    fn new(redir_ty: RedirType, opts: &ConnectOpts) -> Self {\n        Self {\n            redir_ty,\n            socket_opts: RedirSocketOpts {\n                #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n                fwmark: opts.fwmark,\n\n                ..Default::default()\n            },\n            inbound_cache: Arc::new(UdpRedirInboundCache::new()),\n        }\n    }\n}\n\nimpl UdpInboundWrite for UdpRedirInboundWriter {\n    async fn send_to(&self, mut peer_addr: SocketAddr, remote_addr: &Address, data: &[u8]) -> io::Result<()> {\n        // If IPv6 Transparent Proxy is supported on the current platform,\n        // then we should always use IPv6 sockets for sending IPv4 packets.\n        let ip_stack_caps = get_ip_stack_capabilities();\n\n        let addr = match *remote_addr {\n            Address::SocketAddress(sa) => {\n                match sa {\n                    SocketAddr::V4(ref v4) => {\n                        // If IPv4-mapped-IPv6 is supported.\n                        // Converts IPv4 address to IPv4-mapped-IPv6\n                        // All sockets will be created in IPv6 (nearly all modern OS supports IPv6 sockets)\n                        if ip_stack_caps.support_ipv4_mapped_ipv6 {\n                            SocketAddr::new(v4.ip().to_ipv6_mapped().into(), v4.port())\n                        } else {\n                            sa\n                        }\n                    }\n                    SocketAddr::V6(ref v6) => {\n                        // If IPv6 is not supported. Try to map it back to IPv4.\n                        if !ip_stack_caps.support_ipv6 || !ip_stack_caps.support_ipv4_mapped_ipv6 {\n                            match v6.ip().to_ipv4_mapped() {\n                                Some(v4) => SocketAddr::new(v4.into(), v6.port()),\n                                None => sa,\n                            }\n                        } else {\n                            sa\n                        }\n                    }\n                }\n            }\n            Address::DomainNameAddress(..) => {\n                let err = io::Error::new(\n                    ErrorKind::InvalidInput,\n                    \"redir destination must not be an domain name address\",\n                );\n                return Err(err);\n            }\n        };\n\n        let inbound = {\n            let mut cache = self.inbound_cache.cache.lock().await;\n            match cache.get(&addr) {\n                Some(socket) => socket.clone(),\n                _ => {\n                    // Create a socket binds to destination addr\n                    // This only works for systems that supports binding to non-local addresses\n                    //\n                    // This socket has to set SO_REUSEADDR and SO_REUSEPORT.\n                    // Outbound addresses could be connected from different source addresses.\n                    let inbound = UdpRedirSocket::bind_nonlocal(self.redir_ty, addr, &self.socket_opts)?;\n\n                    // UDP socket could be shared between threads and is safe to be manipulated by multiple threads\n                    let inbound = Arc::new(inbound);\n                    cache.insert(addr, inbound.clone());\n\n                    inbound\n                }\n            }\n        };\n\n        // Convert peer_addr (client)'s address family to match remote_addr (target)\n        match (addr, peer_addr) {\n            (SocketAddr::V4(..), SocketAddr::V4(..)) | (SocketAddr::V6(..), SocketAddr::V6(..)) => {}\n            (SocketAddr::V4(..), SocketAddr::V6(v6_peer_addr)) => {\n                if let Some(v4_ip) = v6_peer_addr.ip().to_ipv4_mapped() {\n                    peer_addr = SocketAddr::new(v4_ip.into(), v6_peer_addr.port());\n                } else {\n                    warn!(\n                        \"udp redir send back {} bytes, remote: {}, peer: {}, protocol not match\",\n                        data.len(),\n                        addr,\n                        peer_addr\n                    );\n                }\n            }\n            (SocketAddr::V6(..), SocketAddr::V4(v4_peer_addr)) => {\n                peer_addr = SocketAddr::new(v4_peer_addr.ip().to_ipv6_mapped().into(), v4_peer_addr.port());\n            }\n        }\n\n        match inbound.send_to(data, peer_addr).await {\n            Ok(n) => {\n                if n < data.len() {\n                    warn!(\n                        \"udp redir send back data (actual: {} bytes, sent: {} bytes), remote: {}, peer: {}\",\n                        n,\n                        data.len(),\n                        remote_addr,\n                        peer_addr\n                    );\n                }\n\n                trace!(\n                    \"udp redir send back data {} bytes, remote: {}, peer: {}, socket_opts: {:?}\",\n                    n, remote_addr, peer_addr, self.socket_opts\n                );\n\n                Ok(())\n            }\n            Err(err) => Err(err),\n        }\n    }\n}\n\npub struct RedirUdpServer {\n    context: Arc<ServiceContext>,\n    redir_ty: RedirType,\n    time_to_live: Option<Duration>,\n    capacity: Option<usize>,\n    listener: UdpRedirSocket,\n    balancer: PingBalancer,\n}\n\nimpl RedirUdpServer {\n    pub(crate) async fn new(\n        context: Arc<ServiceContext>,\n        redir_ty: RedirType,\n        client_config: &ServerAddr,\n        time_to_live: Option<Duration>,\n        capacity: Option<usize>,\n        balancer: PingBalancer,\n    ) -> io::Result<Self> {\n        let listener = match *client_config {\n            ServerAddr::SocketAddr(ref saddr) => UdpRedirSocket::listen(redir_ty, *saddr)?,\n            ServerAddr::DomainName(ref dname, port) => {\n                lookup_then!(context.context_ref(), dname, port, |addr| {\n                    UdpRedirSocket::listen(redir_ty, addr)\n                })?\n                .1\n            }\n        };\n\n        Ok(Self {\n            context,\n            redir_ty,\n            time_to_live,\n            capacity,\n            listener,\n            balancer,\n        })\n    }\n\n    pub async fn run(self) -> io::Result<()> {\n        let local_addr = self.listener.local_addr().expect(\"determine port bound to\");\n        info!(\n            \"shadowsocks UDP redirect ({}) listening on {}\",\n            self.redir_ty, local_addr\n        );\n\n        #[allow(clippy::needless_update)]\n        let (mut manager, cleanup_interval, mut keepalive_rx) = UdpAssociationManager::new(\n            self.context.clone(),\n            UdpRedirInboundWriter::new(self.redir_ty, self.context.connect_opts_ref()),\n            self.time_to_live,\n            self.capacity,\n            self.balancer,\n        );\n\n        let mut pkt_buf = [0u8; MAXIMUM_UDP_PAYLOAD_SIZE];\n        let mut cleanup_timer = time::interval(cleanup_interval);\n\n        loop {\n            tokio::select! {\n                _ = cleanup_timer.tick() => {\n                    // cleanup expired associations. iter() will remove expired elements\n                    manager.cleanup_expired().await;\n                }\n\n                peer_addr_opt = keepalive_rx.recv() => {\n                    let peer_addr = peer_addr_opt.expect(\"keep-alive channel closed unexpectedly\");\n                    manager.keep_alive(&peer_addr).await;\n                }\n\n                recv_result = self.listener.recv_dest_from(&mut pkt_buf) => {\n                    let (recv_len, src, mut dst) = match recv_result {\n                        Ok(o) => o,\n                        Err(err) => {\n                            error!(\"recv_dest_from failed with err: {}\", err);\n                            continue;\n                        }\n                    };\n\n                    // Packet length is limited by MAXIMUM_UDP_PAYLOAD_SIZE, excess bytes will be discarded.\n                    // Copy bytes, because udp_associate runs in another tokio Task\n                    let pkt = &pkt_buf[..recv_len];\n\n                    trace!(\n                        \"received UDP packet from {}, destination {}, length {} bytes\",\n                        src,\n                        dst,\n                        recv_len\n                    );\n\n                    if recv_len == 0 {\n                        // For windows, it will generate a ICMP Port Unreachable Message\n                        // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-recvfrom\n                        // Which will result in recv_from return 0.\n                        //\n                        // It cannot be solved here, because `WSAGetLastError` is already set.\n                        //\n                        // See `relay::udprelay::utils::create_socket` for more detail.\n                        continue;\n                    }\n\n                    // Try to convert IPv4 mapped IPv6 address for dual-stack mode.\n                    if let SocketAddr::V6(ref a) = dst\n                        && let Some(v4) = to_ipv4_mapped(a.ip()) {\n                            dst = SocketAddr::new(IpAddr::from(v4), a.port());\n                        }\n\n                    if let Err(err) = manager.send_to(src, Address::from(dst), pkt).await {\n                        debug!(\n                            \"udp packet relay {} -> {} with {} bytes failed, error: {}\",\n                            src,\n                            dst,\n                            pkt.len(),\n                            err\n                        );\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/redir/udprelay/sys/mod.rs",
    "content": "use cfg_if::cfg_if;\n\ncfg_if! {\n    if #[cfg(unix)] {\n        mod unix;\n        pub use self::unix::*;\n    } else if #[cfg(windows)] {\n        mod windows;\n        pub use self::windows::*;\n    } else {\n        compile_error!(\"UDP Relay is not supported in current platform\");\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/redir/udprelay/sys/unix/freebsd.rs",
    "content": "use std::{\n    io::{self, Error, ErrorKind},\n    mem,\n    net::{SocketAddr, UdpSocket},\n    os::unix::io::AsRawFd,\n    ptr,\n    task::{Context, Poll},\n};\n\nuse futures::{future::poll_fn, ready};\nuse log::{error, trace, warn};\nuse shadowsocks::net::is_dual_stack_addr;\nuse socket2::{Domain, Protocol, SockAddr, Socket, Type};\nuse tokio::io::unix::AsyncFd;\n\nuse crate::{\n    config::RedirType,\n    local::redir::{\n        redir_ext::{RedirSocketOpts, UdpSocketRedir},\n        sys::set_ipv6_only,\n    },\n};\n\npub struct UdpRedirSocket {\n    io: AsyncFd<UdpSocket>,\n}\n\nimpl UdpRedirSocket {\n    /// Create a new UDP socket binded to `addr`\n    ///\n    /// This will allow listening to `addr` that is not in local host\n    pub fn listen(ty: RedirType, addr: SocketAddr) -> io::Result<UdpRedirSocket> {\n        UdpRedirSocket::bind(ty, addr, false)\n    }\n\n    /// Create a new UDP socket binded to `addr`\n    ///\n    /// This will allow binding to `addr` that is not in local host\n    pub fn bind_nonlocal(ty: RedirType, addr: SocketAddr, _: &RedirSocketOpts) -> io::Result<UdpRedirSocket> {\n        UdpRedirSocket::bind(ty, addr, true)\n    }\n\n    fn bind(ty: RedirType, addr: SocketAddr, reuse_port: bool) -> io::Result<UdpRedirSocket> {\n        if ty == RedirType::NotSupported {\n            return Err(Error::new(\n                ErrorKind::InvalidInput,\n                \"not supported udp transparent proxy type\",\n            ));\n        }\n\n        let socket = Socket::new(Domain::for_address(addr), Type::DGRAM, Some(Protocol::UDP))?;\n        set_socket_before_bind(&addr, &socket)?;\n\n        socket.set_nonblocking(true)?;\n        socket.set_reuse_address(true)?;\n        if reuse_port {\n            if let Err(err) = socket.set_reuse_port(true) {\n                if let Some(libc::ENOPROTOOPT) = err.raw_os_error() {\n                    trace!(\"failed to set SO_REUSEPORT, error: {}\", err);\n                } else {\n                    error!(\"failed to set SO_REUSEPORT, error: {}\", err);\n                    return Err(err);\n                }\n            }\n        }\n\n        let sock_addr = SockAddr::from(addr);\n\n        if is_dual_stack_addr(&addr) {\n            // set IP_ORIGDSTADDR before bind()\n\n            // NOTE: FreeBSD doesn't allow setting IPPROTO_IP level on an IPv6 socket\n            //\n            // set_ip_origdstaddr(libc::IPPROTO_IP, &socket)?;\n            // set_disable_ip_fragmentation(libc::IPPROTO_IP, &socket)?;\n\n            match set_ipv6_only(&socket, false) {\n                Ok(..) => {\n                    if let Err(err) = socket.bind(&sock_addr) {\n                        warn!(\n                            \"bind() dual-stack address {} failed, error: {}, fallback to IPV6_V6ONLY=true\",\n                            addr, err\n                        );\n\n                        if let Err(err) = set_ipv6_only(&socket, true) {\n                            warn!(\n                                \"set IPV6_V6ONLY=true failed, error: {}, bind() to {} directly\",\n                                err, addr\n                            );\n                        }\n\n                        socket.bind(&sock_addr)?;\n                    }\n                }\n                Err(err) => {\n                    warn!(\n                        \"set IPV6_V6ONLY=false failed, error: {}, bind() to {} directly\",\n                        err, addr\n                    );\n                    socket.bind(&sock_addr)?;\n                }\n            }\n        } else {\n            socket.bind(&sock_addr)?;\n        }\n\n        let io = AsyncFd::new(socket.into())?;\n        Ok(UdpRedirSocket { io })\n    }\n\n    /// Send data to the socket to the given target address\n    pub async fn send_to(&self, buf: &[u8], target: SocketAddr) -> io::Result<usize> {\n        poll_fn(|cx| self.poll_send_to(cx, buf, target)).await\n    }\n\n    fn poll_send_to(&self, cx: &mut Context<'_>, buf: &[u8], target: SocketAddr) -> Poll<io::Result<usize>> {\n        loop {\n            let mut write_guard = ready!(self.io.poll_write_ready(cx))?;\n\n            match self.io.get_ref().send_to(buf, target) {\n                Err(ref e) if e.kind() == ErrorKind::WouldBlock => {\n                    write_guard.clear_ready();\n                }\n                x => return Poll::Ready(x),\n            }\n        }\n    }\n\n    /// Returns the local address that this socket is bound to.\n    pub fn local_addr(&self) -> io::Result<SocketAddr> {\n        self.io.get_ref().local_addr()\n    }\n}\n\nimpl UdpSocketRedir for UdpRedirSocket {\n    fn poll_recv_dest_from(\n        &self,\n        cx: &mut Context<'_>,\n        buf: &mut [u8],\n    ) -> Poll<io::Result<(usize, SocketAddr, SocketAddr)>> {\n        loop {\n            let mut read_guard = ready!(self.io.poll_read_ready(cx))?;\n\n            match recv_dest_from(self.io.get_ref(), buf) {\n                Err(ref e) if e.kind() == ErrorKind::WouldBlock => {\n                    read_guard.clear_ready();\n                }\n                x => return Poll::Ready(x),\n            }\n        }\n    }\n}\n\nfn set_bindany(level: libc::c_int, socket: &Socket) -> io::Result<()> {\n    let fd = socket.as_raw_fd();\n\n    let enable: libc::c_int = 1;\n\n    // https://www.freebsd.org/cgi/man.cgi?query=ip&sektion=4&manpath=FreeBSD+9.0-RELEASE\n    let opt = match level {\n        libc::IPPROTO_IP => libc::IP_BINDANY,\n        libc::IPPROTO_IPV6 => libc::IPV6_BINDANY,\n        _ => unreachable!(\"level can only be IPPROTO_IP or IPPROTO_IPV6\"),\n    };\n\n    unsafe {\n        let ret = libc::setsockopt(\n            fd,\n            level,\n            opt,\n            &enable as *const _ as *const _,\n            mem::size_of_val(&enable) as libc::socklen_t,\n        );\n        if ret != 0 {\n            return Err(Error::last_os_error());\n        }\n    }\n\n    Ok(())\n}\n\nfn set_ip_origdstaddr(level: libc::c_int, socket: &Socket) -> io::Result<()> {\n    // https://www.freebsd.org/cgi/man.cgi?query=ip&sektion=4&manpath=FreeBSD+9.0-RELEASE\n\n    let fd = socket.as_raw_fd();\n\n    let enable: libc::c_int = 1;\n\n    let opt = match level {\n        libc::IPPROTO_IP => libc::IP_RECVORIGDSTADDR,\n        libc::IPPROTO_IPV6 => libc::IPV6_RECVORIGDSTADDR,\n        _ => unreachable!(\"level can only be IPPROTO_IP or IPPROTO_IPV6\"),\n    };\n\n    unsafe {\n        let ret = libc::setsockopt(\n            fd,\n            level,\n            opt,\n            &enable as *const _ as *const _,\n            mem::size_of_val(&enable) as libc::socklen_t,\n        );\n        if ret != 0 {\n            return Err(Error::last_os_error());\n        }\n    }\n\n    Ok(())\n}\n\nfn set_disable_ip_fragmentation(level: libc::c_int, socket: &Socket) -> io::Result<()> {\n    // https://www.freebsd.org/cgi/man.cgi?query=ip&sektion=4&manpath=FreeBSD+9.0-RELEASE\n\n    // sys/netinet/in.h\n    // const IP_DONTFRAG: libc::c_int = 67; // don't fragment packet\n    //\n    // sys/netinet6/in6.h\n    // const IPV6_DONTFRAG: libc::c_int = 62; // bool; disable IPv6 fragmentation\n\n    let enable: libc::c_int = 1;\n\n    let opt = match level {\n        libc::IPPROTO_IP => libc::IP_DONTFRAG,\n        libc::IPPROTO_IPV6 => libc::IPV6_DONTFRAG,\n        _ => unreachable!(\"level can only be IPPROTO_IP or IPPROTO_IPV6\"),\n    };\n\n    unsafe {\n        let ret = libc::setsockopt(\n            socket.as_raw_fd(),\n            level,\n            opt,\n            &enable as *const _ as *const _,\n            mem::size_of_val(&enable) as libc::socklen_t,\n        );\n\n        if ret < 0 {\n            return Err(io::Error::last_os_error());\n        }\n    }\n\n    Ok(())\n}\n\nfn set_socket_before_bind(addr: &SocketAddr, socket: &Socket) -> io::Result<()> {\n    // https://www.freebsd.org/cgi/man.cgi?query=ip&sektion=4&manpath=FreeBSD+9.0-RELEASE\n    let level = match *addr {\n        SocketAddr::V4(..) => libc::IPPROTO_IP,\n        SocketAddr::V6(..) => libc::IPPROTO_IPV6,\n    };\n\n    // 1. BINDANY\n    set_bindany(level, socket)?;\n\n    // 2. set ORIGDSTADDR for retrieving original destination address\n    set_ip_origdstaddr(level, socket)?;\n\n    // 3. disable IP fragmentation\n    set_disable_ip_fragmentation(level, socket)?;\n\n    Ok(())\n}\n\nfn get_destination_addr(msg: &libc::msghdr) -> io::Result<SocketAddr> {\n    // https://www.freebsd.org/cgi/man.cgi?ip(4)\n    //\n    // Called `recvmsg` with `IP_ORIGDSTADDR` set\n\n    unsafe {\n        let (_, addr) = SockAddr::try_init(|dst_addr, dst_addr_len| {\n            let mut cmsg: *mut libc::cmsghdr = libc::CMSG_FIRSTHDR(msg);\n            while !cmsg.is_null() {\n                let rcmsg = &*cmsg;\n                match (rcmsg.cmsg_level, rcmsg.cmsg_type) {\n                    (libc::IPPROTO_IP, libc::IP_ORIGDSTADDR) => {\n                        ptr::copy_nonoverlapping(\n                            libc::CMSG_DATA(cmsg),\n                            dst_addr as *mut _,\n                            mem::size_of::<libc::sockaddr_in>(),\n                        );\n                        *dst_addr_len = mem::size_of::<libc::sockaddr_in>() as libc::socklen_t;\n\n                        return Ok(());\n                    }\n                    (libc::IPPROTO_IPV6, libc::IPV6_ORIGDSTADDR) => {\n                        ptr::copy_nonoverlapping(\n                            libc::CMSG_DATA(cmsg),\n                            dst_addr as *mut _,\n                            mem::size_of::<libc::sockaddr_in6>(),\n                        );\n                        *dst_addr_len = mem::size_of::<libc::sockaddr_in6>() as libc::socklen_t;\n\n                        return Ok(());\n                    }\n                    _ => {}\n                }\n                cmsg = libc::CMSG_NXTHDR(msg, cmsg);\n            }\n\n            let err = Error::new(ErrorKind::InvalidData, \"missing destination address in msghdr\");\n            Err(err)\n        })?;\n\n        Ok(addr.as_socket().expect(\"SocketAddr\"))\n    }\n}\n\nfn recv_dest_from(socket: &UdpSocket, buf: &mut [u8]) -> io::Result<(usize, SocketAddr, SocketAddr)> {\n    unsafe {\n        let mut control_buf = [0u8; 64];\n        let mut src_addr: libc::sockaddr_storage = mem::zeroed();\n\n        let mut msg: libc::msghdr = mem::zeroed();\n        msg.msg_name = &mut src_addr as *mut _ as *mut _;\n        msg.msg_namelen = mem::size_of_val(&src_addr) as libc::socklen_t;\n\n        let mut iov = libc::iovec {\n            iov_base: buf.as_mut_ptr() as *mut _,\n            iov_len: buf.len() as libc::size_t,\n        };\n        msg.msg_iov = &mut iov;\n        msg.msg_iovlen = 1;\n\n        msg.msg_control = control_buf.as_mut_ptr() as *mut _;\n        msg.msg_controllen = control_buf.len() as libc::socklen_t;\n\n        let fd = socket.as_raw_fd();\n        let ret = libc::recvmsg(fd, &mut msg, 0);\n        if ret < 0 {\n            return Err(Error::last_os_error());\n        }\n\n        let (_, src_saddr) = SockAddr::try_init(|a, l| {\n            ptr::copy_nonoverlapping(msg.msg_name, a as *mut _, msg.msg_namelen as usize);\n            *l = msg.msg_namelen;\n            Ok(())\n        })?;\n\n        Ok((\n            ret as usize,\n            src_saddr.as_socket().expect(\"SocketAddr\"),\n            get_destination_addr(&msg)?,\n        ))\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/redir/udprelay/sys/unix/linux.rs",
    "content": "use std::{\n    io::{self, Error, ErrorKind},\n    mem,\n    net::{SocketAddr, UdpSocket},\n    os::unix::io::{AsRawFd, RawFd},\n    ptr,\n    task::{Context, Poll},\n};\n\nuse cfg_if::cfg_if;\nuse futures::{future::poll_fn, ready};\nuse log::{error, trace, warn};\nuse shadowsocks::net::is_dual_stack_addr;\nuse socket2::{Domain, Protocol, SockAddr, Socket, Type};\nuse tokio::io::unix::AsyncFd;\n\nuse crate::{\n    config::RedirType,\n    local::redir::{\n        redir_ext::{RedirSocketOpts, UdpSocketRedir},\n        sys::set_ipv6_only,\n    },\n};\n\npub struct UdpRedirSocket {\n    io: AsyncFd<UdpSocket>,\n}\n\nimpl UdpRedirSocket {\n    /// Create a new UDP socket binded to `addr`\n    ///\n    /// This will allow listening to `addr` that is not in local host\n    pub fn listen(ty: RedirType, addr: SocketAddr) -> io::Result<Self> {\n        Self::bind(ty, addr, false)\n    }\n\n    /// Create a new UDP socket binded to `addr`\n    ///\n    /// This will allow binding to `addr` that is not in local host\n    pub fn bind_nonlocal(ty: RedirType, addr: SocketAddr, redir_opts: &RedirSocketOpts) -> io::Result<Self> {\n        let socket = Self::bind(ty, addr, true)?;\n\n        if let Some(mark) = redir_opts.fwmark {\n            let ret = unsafe {\n                libc::setsockopt(\n                    socket.as_raw_fd(),\n                    libc::SOL_SOCKET,\n                    libc::SO_MARK,\n                    &mark as *const _ as *const _,\n                    mem::size_of_val(&mark) as libc::socklen_t,\n                )\n            };\n            if ret != 0 {\n                return Err(Error::last_os_error());\n            }\n        }\n\n        Ok(socket)\n    }\n\n    fn bind(ty: RedirType, addr: SocketAddr, reuse_port: bool) -> io::Result<Self> {\n        if ty != RedirType::TProxy {\n            return Err(Error::new(\n                ErrorKind::InvalidInput,\n                \"not supported udp transparent proxy type\",\n            ));\n        }\n\n        let socket = Socket::new(Domain::for_address(addr), Type::DGRAM, Some(Protocol::UDP))?;\n        set_socket_before_bind(&addr, &socket)?;\n\n        socket.set_nonblocking(true)?;\n        socket.set_reuse_address(true)?;\n        if reuse_port && let Err(err) = socket.set_reuse_port(true) {\n            if let Some(libc::ENOPROTOOPT) = err.raw_os_error() {\n                // SO_REUSEPORT is supported after 3.9\n                trace!(\"failed to set SO_REUSEPORT, error: {}\", err);\n            } else {\n                error!(\"failed to set SO_REUSEPORT, error: {}\", err);\n                return Err(err);\n            }\n        }\n\n        let sock_addr = SockAddr::from(addr);\n\n        if is_dual_stack_addr(&addr) {\n            // set IP_TRANSPARENT & IP_RECVORIGDSTADDR before bind()\n\n            set_ip_transparent(libc::SOL_IP, &socket)?;\n            set_ip_recvorigdstaddr(libc::SOL_IP, &socket)?;\n            set_ip_mtu_discover(libc::IPPROTO_IP, &socket)?;\n\n            match set_ipv6_only(&socket, false) {\n                Ok(..) => {\n                    if let Err(err) = socket.bind(&sock_addr) {\n                        warn!(\n                            \"bind() dual-stack address {} failed, error: {}, fallback to IPV6_V6ONLY=true\",\n                            addr, err\n                        );\n\n                        if let Err(err) = set_ipv6_only(&socket, true) {\n                            warn!(\n                                \"set IPV6_V6ONLY=true failed, error: {}, bind() to {} directly\",\n                                err, addr\n                            );\n                        }\n\n                        socket.bind(&sock_addr)?;\n                    }\n                }\n                Err(err) => {\n                    warn!(\n                        \"set IPV6_V6ONLY=false failed, error: {}, bind() to {} directly\",\n                        err, addr\n                    );\n                    socket.bind(&sock_addr)?;\n                }\n            }\n        } else {\n            socket.bind(&sock_addr)?;\n        }\n\n        let io = AsyncFd::new(socket.into())?;\n        Ok(Self { io })\n    }\n\n    /// Send data to the socket to the given target address\n    pub async fn send_to(&self, buf: &[u8], target: SocketAddr) -> io::Result<usize> {\n        poll_fn(|cx| self.poll_send_to(cx, buf, target)).await\n    }\n\n    fn poll_send_to(&self, cx: &mut Context<'_>, buf: &[u8], target: SocketAddr) -> Poll<io::Result<usize>> {\n        loop {\n            let mut write_guard = ready!(self.io.poll_write_ready(cx))?;\n\n            match self.io.get_ref().send_to(buf, target) {\n                Err(ref e) if e.kind() == ErrorKind::WouldBlock => {\n                    write_guard.clear_ready();\n                }\n                x => return Poll::Ready(x),\n            }\n        }\n    }\n\n    /// Returns the local address that this socket is bound to.\n    pub fn local_addr(&self) -> io::Result<SocketAddr> {\n        self.io.get_ref().local_addr()\n    }\n}\n\nimpl UdpSocketRedir for UdpRedirSocket {\n    fn poll_recv_dest_from(\n        &self,\n        cx: &mut Context<'_>,\n        buf: &mut [u8],\n    ) -> Poll<io::Result<(usize, SocketAddr, SocketAddr)>> {\n        loop {\n            let mut read_guard = ready!(self.io.poll_read_ready(cx))?;\n\n            match recv_dest_from(self.io.get_ref(), buf) {\n                Err(ref e) if e.kind() == ErrorKind::WouldBlock => {\n                    read_guard.clear_ready();\n                }\n                x => return Poll::Ready(x),\n            }\n        }\n    }\n}\n\nimpl AsRawFd for UdpRedirSocket {\n    fn as_raw_fd(&self) -> RawFd {\n        self.io.as_raw_fd()\n    }\n}\n\nfn set_ip_transparent(level: libc::c_int, socket: &Socket) -> io::Result<()> {\n    let fd = socket.as_raw_fd();\n\n    let opt = match level {\n        libc::SOL_IP => libc::IP_TRANSPARENT,\n        libc::SOL_IPV6 => libc::IPV6_TRANSPARENT,\n        _ => unreachable!(\"invalid sockopt level {}\", level),\n    };\n\n    let enable: libc::c_int = 1;\n\n    unsafe {\n        let ret = libc::setsockopt(\n            fd,\n            level,\n            opt,\n            &enable as *const _ as *const _,\n            mem::size_of_val(&enable) as libc::socklen_t,\n        );\n\n        if ret != 0 {\n            return Err(Error::last_os_error());\n        }\n    }\n\n    Ok(())\n}\n\nfn set_ip_recvorigdstaddr(level: libc::c_int, socket: &Socket) -> io::Result<()> {\n    let fd = socket.as_raw_fd();\n\n    let opt = match level {\n        libc::SOL_IP => libc::IP_RECVORIGDSTADDR,\n        libc::SOL_IPV6 => libc::IPV6_RECVORIGDSTADDR,\n        _ => unreachable!(\"invalid sockopt level {}\", level),\n    };\n\n    let enable: libc::c_int = 1;\n\n    unsafe {\n        let ret = libc::setsockopt(\n            fd,\n            level,\n            opt,\n            &enable as *const _ as *const _,\n            mem::size_of_val(&enable) as libc::socklen_t,\n        );\n\n        if ret != 0 {\n            return Err(Error::last_os_error());\n        }\n    }\n\n    Ok(())\n}\n\nfn set_ip_mtu_discover(level: libc::c_int, socket: &Socket) -> io::Result<()> {\n    let fd = socket.as_raw_fd();\n\n    let opt = match level {\n        libc::IPPROTO_IP => libc::IP_MTU_DISCOVER,\n        libc::IPPROTO_IPV6 => libc::IPV6_MTU_DISCOVER,\n        _ => unreachable!(\"invalid sockopt level {}\", level),\n    };\n\n    let value: libc::c_int = libc::IP_PMTUDISC_DO;\n    unsafe {\n        let ret = libc::setsockopt(\n            fd,\n            level,\n            opt,\n            &value as *const _ as *const _,\n            mem::size_of_val(&value) as libc::socklen_t,\n        );\n\n        if ret < 0 {\n            return Err(io::Error::last_os_error());\n        }\n    }\n\n    Ok(())\n}\n\nfn set_socket_before_bind(addr: &SocketAddr, socket: &Socket) -> io::Result<()> {\n    // Set IP_TRANSPARENT, IPV6_TRANSPARENT to allow binding to non-local addresses\n\n    let level = match *addr {\n        SocketAddr::V4(..) => libc::SOL_IP,\n        SocketAddr::V6(..) => libc::SOL_IPV6,\n    };\n\n    set_ip_transparent(level, socket)?;\n    set_ip_recvorigdstaddr(level, socket)?;\n    set_ip_mtu_discover(level, socket)?;\n\n    Ok(())\n}\n\nfn get_destination_addr(msg: &libc::msghdr) -> io::Result<SocketAddr> {\n    unsafe {\n        let (_, addr) = SockAddr::try_init(|dst_addr, dst_addr_len| {\n            let mut cmsg: *mut libc::cmsghdr = libc::CMSG_FIRSTHDR(msg);\n            while !cmsg.is_null() {\n                let rcmsg = &*cmsg;\n                match (rcmsg.cmsg_level, rcmsg.cmsg_type) {\n                    (libc::SOL_IP, libc::IP_RECVORIGDSTADDR) => {\n                        ptr::copy(\n                            libc::CMSG_DATA(cmsg),\n                            dst_addr as *mut _,\n                            mem::size_of::<libc::sockaddr_in>(),\n                        );\n                        *dst_addr_len = mem::size_of::<libc::sockaddr_in>() as libc::socklen_t;\n\n                        return Ok(());\n                    }\n                    (libc::SOL_IPV6, libc::IPV6_RECVORIGDSTADDR) => {\n                        ptr::copy(\n                            libc::CMSG_DATA(cmsg),\n                            dst_addr as *mut _,\n                            mem::size_of::<libc::sockaddr_in6>(),\n                        );\n                        *dst_addr_len = mem::size_of::<libc::sockaddr_in6>() as libc::socklen_t;\n\n                        return Ok(());\n                    }\n                    _ => {}\n                }\n                cmsg = libc::CMSG_NXTHDR(msg, cmsg);\n            }\n\n            let err = Error::new(ErrorKind::InvalidData, \"missing destination address in msghdr\");\n            Err(err)\n        })?;\n\n        Ok(addr.as_socket().expect(\"SocketAddr\"))\n    }\n}\n\nfn recv_dest_from(socket: &UdpSocket, buf: &mut [u8]) -> io::Result<(usize, SocketAddr, SocketAddr)> {\n    unsafe {\n        let mut control_buf = [0u8; 64];\n        let mut src_addr: libc::sockaddr_storage = mem::zeroed();\n\n        let mut msg: libc::msghdr = mem::zeroed();\n        msg.msg_name = &mut src_addr as *mut _ as *mut _;\n        msg.msg_namelen = mem::size_of_val(&src_addr) as libc::socklen_t;\n\n        let mut iov = libc::iovec {\n            iov_base: buf.as_mut_ptr() as *mut _,\n            iov_len: buf.len() as libc::size_t,\n        };\n        msg.msg_iov = &mut iov;\n        msg.msg_iovlen = 1;\n\n        msg.msg_control = control_buf.as_mut_ptr() as *mut _;\n        cfg_if! {\n            if #[cfg(any(target_env = \"musl\", all(target_env = \"uclibc\", target_arch = \"arm\")))] {\n                msg.msg_controllen = control_buf.len() as libc::socklen_t;\n            } else {\n                msg.msg_controllen = control_buf.len() as libc::size_t;\n            }\n        }\n\n        let fd = socket.as_raw_fd();\n        let ret = libc::recvmsg(fd, &mut msg, 0);\n        if ret < 0 {\n            return Err(Error::last_os_error());\n        }\n\n        let (_, src_saddr) = SockAddr::try_init(|a, l| {\n            ptr::copy_nonoverlapping(msg.msg_name, a as *mut _, msg.msg_namelen as usize);\n            *l = msg.msg_namelen;\n            Ok(())\n        })?;\n\n        Ok((\n            ret as usize,\n            src_saddr.as_socket().expect(\"SocketAddr\"),\n            get_destination_addr(&msg)?,\n        ))\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/redir/udprelay/sys/unix/macos.rs",
    "content": "use std::{\n    io::{self, Error, ErrorKind},\n    mem,\n    net::{SocketAddr, UdpSocket},\n    os::unix::io::AsRawFd,\n    task::{Context, Poll},\n};\n\nuse futures::{future::poll_fn, ready};\nuse log::{error, trace, warn};\nuse shadowsocks::net::is_dual_stack_addr;\nuse socket2::{Domain, Protocol, SockAddr, Socket, Type};\nuse tokio::io::unix::AsyncFd;\n\nuse crate::{\n    config::RedirType,\n    local::redir::{\n        redir_ext::{RedirSocketOpts, UdpSocketRedir},\n        sys::{bsd_pf::PF, set_ipv6_only},\n    },\n};\n\npub struct UdpRedirSocket {\n    io: AsyncFd<UdpSocket>,\n}\n\nimpl UdpRedirSocket {\n    /// Create a new UDP socket binded to `addr`\n    ///\n    /// This will allow listening to `addr` that is not in local host\n    pub fn listen(ty: RedirType, addr: SocketAddr) -> io::Result<UdpRedirSocket> {\n        UdpRedirSocket::bind(ty, addr, false)\n    }\n\n    /// Create a new UDP socket binded to `addr`\n    ///\n    /// This will allow binding to `addr` that is not in local host\n    pub fn bind_nonlocal(ty: RedirType, addr: SocketAddr, _: &RedirSocketOpts) -> io::Result<UdpRedirSocket> {\n        UdpRedirSocket::bind(ty, addr, true)\n    }\n\n    fn bind(ty: RedirType, addr: SocketAddr, reuse_port: bool) -> io::Result<UdpRedirSocket> {\n        if ty == RedirType::NotSupported {\n            return Err(Error::new(\n                ErrorKind::InvalidInput,\n                \"not supported udp transparent proxy type\",\n            ));\n        }\n\n        let socket = Socket::new(Domain::for_address(addr), Type::DGRAM, Some(Protocol::UDP))?;\n        set_socket_before_bind(&addr, &socket)?;\n\n        socket.set_nonblocking(true)?;\n        socket.set_reuse_address(true)?;\n        if reuse_port && let Err(err) = socket.set_reuse_port(true) {\n            if let Some(libc::ENOPROTOOPT) = err.raw_os_error() {\n                trace!(\"failed to set SO_REUSEPORT, error: {}\", err);\n            } else {\n                error!(\"failed to set SO_REUSEPORT, error: {}\", err);\n                return Err(err);\n            }\n        }\n\n        let sock_addr = SockAddr::from(addr);\n\n        if is_dual_stack_addr(&addr) {\n            // set IP_ORIGDSTADDR before bind()\n\n            match set_ipv6_only(&socket, false) {\n                Ok(..) => {\n                    if let Err(err) = socket.bind(&sock_addr) {\n                        warn!(\n                            \"bind() dual-stack address {} failed, error: {}, fallback to IPV6_V6ONLY=true\",\n                            addr, err\n                        );\n\n                        if let Err(err) = set_ipv6_only(&socket, true) {\n                            warn!(\n                                \"set IPV6_V6ONLY=true failed, error: {}, bind() to {} directly\",\n                                err, addr\n                            );\n                        }\n\n                        socket.bind(&sock_addr)?;\n                    }\n                }\n                Err(err) => {\n                    warn!(\n                        \"set IPV6_V6ONLY=false failed, error: {}, bind() to {} directly\",\n                        err, addr\n                    );\n                    socket.bind(&sock_addr)?;\n                }\n            }\n        } else {\n            socket.bind(&sock_addr)?;\n        }\n\n        let io = AsyncFd::new(socket.into())?;\n        Ok(UdpRedirSocket { io })\n    }\n\n    /// Send data to the socket to the given target address\n    pub async fn send_to(&self, buf: &[u8], target: SocketAddr) -> io::Result<usize> {\n        poll_fn(|cx| self.poll_send_to(cx, buf, target)).await\n    }\n\n    fn poll_send_to(&self, cx: &mut Context<'_>, buf: &[u8], target: SocketAddr) -> Poll<io::Result<usize>> {\n        loop {\n            let mut write_guard = ready!(self.io.poll_write_ready(cx))?;\n\n            match self.io.get_ref().send_to(buf, target) {\n                Err(ref e) if e.kind() == ErrorKind::WouldBlock => {\n                    write_guard.clear_ready();\n                }\n                x => return Poll::Ready(x),\n            }\n        }\n    }\n\n    /// Returns the local address that this socket is bound to.\n    pub fn local_addr(&self) -> io::Result<SocketAddr> {\n        self.io.get_ref().local_addr()\n    }\n}\n\nimpl UdpSocketRedir for UdpRedirSocket {\n    fn poll_recv_dest_from(\n        &self,\n        cx: &mut Context<'_>,\n        buf: &mut [u8],\n    ) -> Poll<io::Result<(usize, SocketAddr, SocketAddr)>> {\n        loop {\n            let mut read_guard = ready!(self.io.poll_read_ready(cx))?;\n\n            let (n, peer_addr) = match self.io.get_ref().recv_from(buf) {\n                Err(ref e) if e.kind() == ErrorKind::WouldBlock => {\n                    read_guard.clear_ready();\n                    continue;\n                }\n                Err(e) => return Err(e).into(),\n                Ok(x) => x,\n            };\n\n            let bind_addr = self.local_addr()?;\n            let actual_addr = PF.natlook(&bind_addr, &peer_addr, Protocol::UDP)?;\n\n            return Ok((n, peer_addr, actual_addr)).into();\n        }\n    }\n}\n\nfn set_disable_ip_fragmentation(level: libc::c_int, socket: &Socket) -> io::Result<()> {\n    // https://www.freebsd.org/cgi/man.cgi?query=ip&sektion=4&manpath=FreeBSD+9.0-RELEASE\n\n    // sys/netinet/in.h\n    // const IP_DONTFRAG: libc::c_int = 67; // don't fragment packet\n    //\n    // sys/netinet6/in6.h\n    // const IPV6_DONTFRAG: libc::c_int = 62; // bool; disable IPv6 fragmentation\n\n    let enable: libc::c_int = 1;\n\n    let opt = match level {\n        libc::IPPROTO_IP => libc::IP_DONTFRAG,\n        libc::IPPROTO_IPV6 => libc::IPV6_DONTFRAG,\n        _ => unreachable!(\"level can only be IPPROTO_IP or IPPROTO_IPV6\"),\n    };\n\n    unsafe {\n        let ret = libc::setsockopt(\n            socket.as_raw_fd(),\n            level,\n            opt,\n            &enable as *const _ as *const _,\n            mem::size_of_val(&enable) as libc::socklen_t,\n        );\n\n        if ret < 0 {\n            return Err(io::Error::last_os_error());\n        }\n    }\n\n    Ok(())\n}\n\nfn set_socket_before_bind(addr: &SocketAddr, socket: &Socket) -> io::Result<()> {\n    // https://www.freebsd.org/cgi/man.cgi?query=ip&sektion=4&manpath=FreeBSD+9.0-RELEASE\n    let level = match *addr {\n        SocketAddr::V4(..) => libc::IPPROTO_IP,\n        SocketAddr::V6(..) => libc::IPPROTO_IPV6,\n    };\n\n    // 1. disable IP fragmentation\n    set_disable_ip_fragmentation(level, socket)?;\n\n    Ok(())\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/redir/udprelay/sys/unix/mod.rs",
    "content": "use cfg_if::cfg_if;\n\ncfg_if! {\n    if #[cfg(any(target_os = \"linux\", target_os = \"android\"))] {\n        mod linux;\n        pub use self::linux::*;\n    } else if #[cfg(target_os = \"macos\")] {\n        mod macos;\n        pub use self::macos::*;\n    } else if #[cfg(any(target_os = \"freebsd\"))] {\n        mod freebsd;\n        pub use self::freebsd::*;\n    } else if #[cfg(target_os = \"openbsd\")] {\n        mod openbsd;\n        pub use self::openbsd::*;\n    } else {\n        mod not_supported;\n        pub use self::not_supported::*;\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/redir/udprelay/sys/unix/not_supported.rs",
    "content": "use std::{\n    io,\n    net::SocketAddr,\n    task::{Context, Poll},\n};\n\nuse crate::{\n    config::RedirType,\n    local::redir::redir_ext::{RedirSocketOpts, UdpSocketRedir},\n};\n\npub struct UdpRedirSocket;\n\nimpl UdpRedirSocket {\n    /// Create a new UDP socket binded to `addr`\n    ///\n    /// This will allow listening to `addr` that is not in local host\n    pub fn listen(_ty: RedirType, _addr: SocketAddr) -> io::Result<UdpRedirSocket> {\n        unimplemented!(\"UDP transparent proxy is not supported on this platform\")\n    }\n\n    /// Create a new UDP socket binded to `addr`\n    ///\n    /// This will allow binding to `addr` that is not in local host\n    pub fn bind_nonlocal(\n        _ty: RedirType,\n        _addr: SocketAddr,\n        _redir_opts: &RedirSocketOpts,\n    ) -> io::Result<UdpRedirSocket> {\n        unimplemented!(\"UDP transparent proxy is not supported on this platform\")\n    }\n\n    /// Send data to the socket to the given target address\n    pub async fn send_to(&self, _buf: &[u8], _target: SocketAddr) -> io::Result<usize> {\n        unimplemented!(\"UDP transparent proxy is not supported on this platform\")\n    }\n\n    /// Returns the local address that this socket is bound to.\n    pub fn local_addr(&self) -> io::Result<SocketAddr> {\n        unimplemented!(\"UDP transparent proxy is not supported on this platform\")\n    }\n}\n\nimpl UdpSocketRedir for UdpRedirSocket {\n    fn poll_recv_dest_from(\n        &self,\n        _cx: &mut Context<'_>,\n        _buf: &mut [u8],\n    ) -> Poll<io::Result<(usize, SocketAddr, SocketAddr)>> {\n        unimplemented!(\"UDP transparent proxy is not supported on this platform\")\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/redir/udprelay/sys/unix/openbsd.rs",
    "content": "use std::{\n    io::{self, Error, ErrorKind},\n    mem,\n    net::{SocketAddr, UdpSocket},\n    os::unix::io::AsRawFd,\n    ptr,\n    task::{Context, Poll},\n};\n\nuse futures::{future::poll_fn, ready};\nuse log::{error, trace, warn};\nuse shadowsocks::net::is_dual_stack_addr;\nuse socket2::{Domain, Protocol, SockAddr, Socket, Type};\nuse tokio::io::unix::AsyncFd;\n\nuse crate::{\n    config::RedirType,\n    local::redir::{\n        redir_ext::{RedirSocketOpts, UdpSocketRedir},\n        sys::set_ipv6_only,\n    },\n};\nconst IP_RECVDSTPORT: i32 = 33; // Temporary workaround until libc supports this\nconst IPV6_RECVDSTPORT: i32 = 64; // Temporary workaround until libc supports this\n\npub struct UdpRedirSocket {\n    io: AsyncFd<UdpSocket>,\n}\n\nimpl UdpRedirSocket {\n    /// Create a new UDP socket binded to `addr`\n    ///\n    /// This will allow listening to `addr` that is not in local host\n    pub fn listen(ty: RedirType, addr: SocketAddr) -> io::Result<UdpRedirSocket> {\n        UdpRedirSocket::bind(ty, addr, false)\n    }\n\n    /// Create a new UDP socket binded to `addr`\n    ///\n    /// This will allow binding to `addr` that is not in local host\n    pub fn bind_nonlocal(ty: RedirType, addr: SocketAddr, _: &RedirSocketOpts) -> io::Result<UdpRedirSocket> {\n        UdpRedirSocket::bind(ty, addr, true)\n    }\n\n    fn bind(ty: RedirType, addr: SocketAddr, reuse_port: bool) -> io::Result<UdpRedirSocket> {\n        if ty == RedirType::NotSupported {\n            return Err(Error::new(\n                ErrorKind::InvalidInput,\n                \"not supported udp transparent proxy type\",\n            ));\n        }\n\n        let socket = Socket::new(Domain::for_address(addr), Type::DGRAM, Some(Protocol::UDP))?;\n        set_socket_before_bind(&addr, &socket)?;\n\n        socket.set_nonblocking(true)?;\n        socket.set_reuse_address(true)?;\n        if reuse_port {\n            if let Err(err) = socket.set_reuse_port(true) {\n                if let Some(libc::ENOPROTOOPT) = err.raw_os_error() {\n                    trace!(\"failed to set SO_REUSEPORT, error: {}\", err);\n                } else {\n                    error!(\"failed to set SO_REUSEPORT, error: {}\", err);\n                    return Err(err);\n                }\n            }\n        }\n\n        let sock_addr = SockAddr::from(addr);\n\n        if is_dual_stack_addr(&addr) {\n            // set IP_ORIGDSTADDR before bind()\n\n            // NOTE: FreeBSD doesn't allow setting IPPROTO_IP level on an IPv6 socket\n            //\n            // set_ip_origdstaddr(libc::IPPROTO_IP, &socket)?;\n            // set_disable_ip_fragmentation(libc::IPPROTO_IP, &socket)?;\n\n            match set_ipv6_only(&socket, false) {\n                Ok(..) => {\n                    if let Err(err) = socket.bind(&sock_addr) {\n                        warn!(\n                            \"bind() dual-stack address {} failed, error: {}, fallback to IPV6_V6ONLY=true\",\n                            addr, err\n                        );\n\n                        if let Err(err) = set_ipv6_only(&socket, true) {\n                            warn!(\n                                \"set IPV6_V6ONLY=true failed, error: {}, bind() to {} directly\",\n                                err, addr\n                            );\n                        }\n\n                        socket.bind(&sock_addr)?;\n                    }\n                }\n                Err(err) => {\n                    warn!(\n                        \"set IPV6_V6ONLY=false failed, error: {}, bind() to {} directly\",\n                        err, addr\n                    );\n                    socket.bind(&sock_addr)?;\n                }\n            }\n        } else {\n            socket.bind(&sock_addr)?;\n        }\n\n        let io = AsyncFd::new(socket.into())?;\n        Ok(UdpRedirSocket { io })\n    }\n\n    /// Send data to the socket to the given target address\n    pub async fn send_to(&self, buf: &[u8], target: SocketAddr) -> io::Result<usize> {\n        poll_fn(|cx| self.poll_send_to(cx, buf, target)).await\n    }\n\n    fn poll_send_to(&self, cx: &mut Context<'_>, buf: &[u8], target: SocketAddr) -> Poll<io::Result<usize>> {\n        loop {\n            let mut write_guard = ready!(self.io.poll_write_ready(cx))?;\n\n            match self.io.get_ref().send_to(buf, target) {\n                Err(ref e) if e.kind() == ErrorKind::WouldBlock => {\n                    write_guard.clear_ready();\n                }\n                x => return Poll::Ready(x),\n            }\n        }\n    }\n\n    /// Returns the local address that this socket is bound to.\n    pub fn local_addr(&self) -> io::Result<SocketAddr> {\n        self.io.get_ref().local_addr()\n    }\n}\n\nimpl UdpSocketRedir for UdpRedirSocket {\n    fn poll_recv_dest_from(\n        &self,\n        cx: &mut Context<'_>,\n        buf: &mut [u8],\n    ) -> Poll<io::Result<(usize, SocketAddr, SocketAddr)>> {\n        loop {\n            let mut read_guard = ready!(self.io.poll_read_ready(cx))?;\n\n            match recv_dest_from(self.io.get_ref(), buf) {\n                Err(ref e) if e.kind() == ErrorKind::WouldBlock => {\n                    read_guard.clear_ready();\n                }\n                x => return Poll::Ready(x),\n            }\n        }\n    }\n}\n\nfn set_bindany(_level: libc::c_int, socket: &Socket) -> io::Result<()> {\n    let fd = socket.as_raw_fd();\n\n    let enable: libc::c_int = 1;\n\n    // https://man.openbsd.org/getsockopt.2\n    unsafe {\n        let ret = libc::setsockopt(\n            fd,\n            libc::SOL_SOCKET,\n            libc::SO_BINDANY,\n            &enable as *const _ as *const _,\n            mem::size_of_val(&enable) as libc::socklen_t,\n        );\n        if ret != 0 {\n            return Err(Error::last_os_error());\n        }\n    }\n\n    Ok(())\n}\n\nfn set_ip_origdstaddr(level: libc::c_int, socket: &Socket) -> io::Result<()> {\n    // https://man.openbsd.org/pf.conf\n    let fd = socket.as_raw_fd();\n\n    let enable: libc::c_int = 1;\n\n    let opt = match level {\n        libc::IPPROTO_IP => libc::IP_RECVDSTADDR,\n        libc::IPPROTO_IPV6 => libc::IPV6_RECVPKTINFO,\n        _ => unreachable!(\"level can only be IPPROTO_IP or IPPROTO_IPV6\"),\n    };\n\n    unsafe {\n        let ret = libc::setsockopt(\n            fd,\n            level,\n            opt,\n            &enable as *const _ as *const _,\n            mem::size_of_val(&enable) as libc::socklen_t,\n        );\n        if ret != 0 {\n            return Err(Error::last_os_error());\n        }\n    }\n\n    let opt2 = match level {\n        libc::IPPROTO_IP => IP_RECVDSTPORT,\n        libc::IPPROTO_IPV6 => IPV6_RECVDSTPORT,\n        _ => unreachable!(\"level can only be IPPROTO_IP or IPPROTO_IPV6\"),\n    };\n    unsafe {\n        let ret = libc::setsockopt(\n            fd,\n            level,\n            opt2,\n            &enable as *const _ as *const _,\n            mem::size_of_val(&enable) as libc::socklen_t,\n        );\n        if ret != 0 {\n            return Err(Error::last_os_error());\n        }\n    }\n    Ok(())\n}\n\nfn set_socket_before_bind(addr: &SocketAddr, socket: &Socket) -> io::Result<()> {\n    // https://www.freebsd.org/cgi/man.cgi?query=ip&sektion=4&manpath=FreeBSD+9.0-RELEASE\n    let level = match *addr {\n        SocketAddr::V4(..) => libc::IPPROTO_IP,\n        SocketAddr::V6(..) => libc::IPPROTO_IPV6,\n    };\n\n    // 1. BINDANY\n    set_bindany(level, socket)?;\n\n    // 2. set ORIGDSTADDR for retrieving original destination address\n    set_ip_origdstaddr(level, socket)?;\n\n    Ok(())\n}\n\nfn get_destination_addr(msg: &libc::msghdr) -> io::Result<SocketAddr> {\n    unsafe {\n        let (_, addr) = SockAddr::try_init(|dst_addr, dst_addr_len| {\n            let mut cmsg: *mut libc::cmsghdr = libc::CMSG_FIRSTHDR(msg);\n            let mut addr_or_port_received = false; // The address should come first and then the port, but we use a flag just in case. https://github.com/openbsd/src/blob/3d310523b415eeee9db46a5b67eecf8f9fdd5c8f/sys/netinet/udp_usrreq.c#L662-L687\n            while !cmsg.is_null() {\n                let rcmsg = &*cmsg;\n                match (rcmsg.cmsg_level, rcmsg.cmsg_type) {\n                    (libc::IPPROTO_IP, libc::IP_RECVDSTADDR) => {\n                        let toaddr_in = &mut *(dst_addr as *mut libc::sockaddr_in);\n                        ptr::copy_nonoverlapping(\n                            libc::CMSG_DATA(cmsg),\n                            &(*toaddr_in).sin_addr as *const _ as *mut _,\n                            mem::size_of::<libc::in_addr>(),\n                        );\n                        toaddr_in.sin_family = libc::AF_INET as u8;\n                        *dst_addr_len = mem::size_of::<libc::sockaddr_in>() as libc::socklen_t;\n                        if addr_or_port_received {\n                            return Ok(());\n                        } else {\n                            addr_or_port_received = true\n                        }\n                    }\n                    (libc::IPPROTO_IP, IP_RECVDSTPORT) => {\n                        let toaddr_in = &mut *(dst_addr as *mut libc::sockaddr_in);\n                        ptr::copy_nonoverlapping(\n                            libc::CMSG_DATA(cmsg),\n                            &(*toaddr_in).sin_port as *const _ as *mut _,\n                            mem::size_of::<libc::in_port_t>(),\n                        );\n                        if addr_or_port_received {\n                            return Ok(());\n                        } else {\n                            addr_or_port_received = true\n                        }\n                    }\n                    (libc::IPPROTO_IPV6, libc::IPV6_PKTINFO) => {\n                        let toaddr_in = &mut *(dst_addr as *mut libc::sockaddr_in6);\n                        ptr::copy_nonoverlapping(\n                            libc::CMSG_DATA(cmsg),\n                            &(*toaddr_in).sin6_addr as *const _ as *mut _,\n                            mem::size_of::<libc::in6_addr>(),\n                        );\n                        toaddr_in.sin6_family = libc::AF_INET6 as u8;\n                        *dst_addr_len = mem::size_of::<libc::sockaddr_in6>() as libc::socklen_t;\n                        if addr_or_port_received {\n                            return Ok(());\n                        } else {\n                            addr_or_port_received = true\n                        }\n                    }\n                    (libc::IPPROTO_IPV6, IPV6_RECVDSTPORT) => {\n                        let toaddr_in = &mut *(dst_addr as *mut libc::sockaddr_in6);\n                        ptr::copy_nonoverlapping(\n                            libc::CMSG_DATA(cmsg),\n                            &(*toaddr_in).sin6_port as *const _ as *mut _,\n                            mem::size_of::<libc::in_port_t>(),\n                        );\n                        if addr_or_port_received {\n                            return Ok(());\n                        } else {\n                            addr_or_port_received = true\n                        }\n                    }\n                    _ => {}\n                }\n                cmsg = libc::CMSG_NXTHDR(msg, cmsg);\n            }\n            let err = Error::new(ErrorKind::InvalidData, \"missing destination address in msghdr\");\n            Err(err)\n        })?;\n\n        Ok(addr.as_socket().expect(\"SocketAddr\"))\n    }\n}\n\nfn recv_dest_from(socket: &UdpSocket, buf: &mut [u8]) -> io::Result<(usize, SocketAddr, SocketAddr)> {\n    unsafe {\n        let mut control_buf = [0u8; 64];\n        let mut src_addr: libc::sockaddr_storage = mem::zeroed();\n\n        let mut msg: libc::msghdr = mem::zeroed();\n        msg.msg_name = &mut src_addr as *mut _ as *mut _;\n        msg.msg_namelen = mem::size_of_val(&src_addr) as libc::socklen_t;\n\n        let mut iov = libc::iovec {\n            iov_base: buf.as_mut_ptr() as *mut _,\n            iov_len: buf.len() as libc::size_t,\n        };\n        msg.msg_iov = &mut iov;\n        msg.msg_iovlen = 1;\n\n        msg.msg_control = control_buf.as_mut_ptr() as *mut _;\n        msg.msg_controllen = control_buf.len() as libc::socklen_t;\n\n        let fd = socket.as_raw_fd();\n        let ret = libc::recvmsg(fd, &mut msg, 0);\n        if ret < 0 {\n            return Err(Error::last_os_error());\n        }\n\n        let (_, src_saddr) = SockAddr::try_init(|a, l| {\n            ptr::copy_nonoverlapping(msg.msg_name, a as *mut _, msg.msg_namelen as usize);\n            *l = msg.msg_namelen;\n            Ok(())\n        })?;\n\n        Ok((\n            ret as usize,\n            src_saddr.as_socket().expect(\"SocketAddr\"),\n            get_destination_addr(&msg)?,\n        ))\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/redir/udprelay/sys/windows/mod.rs",
    "content": "use std::{\n    io,\n    net::SocketAddr,\n    task::{Context, Poll},\n};\n\nuse crate::{\n    config::RedirType,\n    local::redir::redir_ext::{RedirSocketOpts, UdpSocketRedir},\n};\n\npub struct UdpRedirSocket;\n\nimpl UdpRedirSocket {\n    /// Create a new UDP socket binded to `addr`\n    ///\n    /// This will allow listening to `addr` that is not in local host\n    pub fn listen(ty: RedirType, addr: SocketAddr) -> io::Result<UdpRedirSocket> {\n        UdpRedirSocket::bind(ty, addr, false)\n    }\n\n    /// Create a new UDP socket binded to `addr`\n    ///\n    /// This will allow binding to `addr` that is not in local host\n    pub fn bind_nonlocal(ty: RedirType, addr: SocketAddr, _redir_opts: &RedirSocketOpts) -> io::Result<UdpRedirSocket> {\n        UdpRedirSocket::bind(ty, addr, true)\n    }\n\n    fn bind(_ty: RedirType, _addr: SocketAddr, _reuse_port: bool) -> io::Result<UdpRedirSocket> {\n        unimplemented!(\"UDP transparent proxy is not supported on Windows\")\n    }\n\n    /// Send data to the socket to the given target address\n    pub async fn send_to(&self, _buf: &[u8], _target: SocketAddr) -> io::Result<usize> {\n        unimplemented!(\"UDP transparent proxy is not supported on Windows\")\n    }\n\n    /// Returns the local address that this socket is bound to.\n    pub fn local_addr(&self) -> io::Result<SocketAddr> {\n        unimplemented!(\"UDP transparent proxy is not supported on Windows\")\n    }\n}\n\nimpl UdpSocketRedir for UdpRedirSocket {\n    fn poll_recv_dest_from(\n        &self,\n        _cx: &mut Context<'_>,\n        _buf: &mut [u8],\n    ) -> Poll<io::Result<(usize, SocketAddr, SocketAddr)>> {\n        unimplemented!(\"UDP transparent proxy is not supported on Windows\")\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/socks/client/mod.rs",
    "content": "//! SOCKS clients\n\n#[cfg(feature = \"local-socks4\")]\npub use self::socks4::Socks4TcpClient;\npub use self::socks5::{Socks5TcpClient, Socks5UdpClient};\n\n#[cfg(feature = \"local-socks4\")]\npub mod socks4;\npub mod socks5;\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/socks/client/socks4/mod.rs",
    "content": "//! SOCKS 4/4a clients\n\npub use self::tcp_client::Socks4TcpClient;\n\nmod tcp_client;\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/socks/client/socks4/tcp_client.rs",
    "content": "//! SOCKS 4/4a client implementation\n\nuse std::{\n    io,\n    pin::Pin,\n    task::{self, Poll},\n};\n\nuse log::trace;\nuse pin_project::pin_project;\nuse tokio::{\n    io::{AsyncRead, AsyncWrite, ReadBuf},\n    net::{TcpStream, ToSocketAddrs},\n};\n\nuse crate::local::socks::socks4::{Address, Command, Error, HandshakeRequest, HandshakeResponse, ResultCode};\n\n/// Socks4/4a proxy client\n#[pin_project]\npub struct Socks4TcpClient {\n    #[pin]\n    stream: TcpStream,\n}\n\nimpl Socks4TcpClient {\n    /// Connects to `addr` via `proxy`\n    pub async fn connect<A, P, U>(addr: A, proxy: P, user_id: U) -> Result<Self, Error>\n    where\n        A: Into<Address>,\n        P: ToSocketAddrs,\n        U: Into<Vec<u8>>,\n    {\n        let mut s = TcpStream::connect(proxy).await?;\n\n        // 1. handshake\n\n        let hs = HandshakeRequest {\n            cd: Command::Connect,\n            dst: addr.into(),\n            user_id: user_id.into(),\n        };\n        trace!(\"client connected, going to send handshake: {:?}\", hs);\n\n        hs.write_to(&mut s).await?;\n\n        let hsp = HandshakeResponse::read_from(&mut s).await?;\n\n        trace!(\"got handshake response: {:?}\", hsp);\n\n        if hsp.cd != ResultCode::RequestGranted {\n            return Err(Error::Result(hsp.cd));\n        }\n\n        Ok(Self { stream: s })\n    }\n}\n\nimpl AsyncRead for Socks4TcpClient {\n    fn poll_read(\n        self: Pin<&mut Self>,\n        cx: &mut task::Context<'_>,\n        buf: &mut ReadBuf<'_>,\n    ) -> Poll<Result<(), io::Error>> {\n        self.project().stream.poll_read(cx, buf)\n    }\n}\n\nimpl AsyncWrite for Socks4TcpClient {\n    fn poll_write(self: Pin<&mut Self>, cx: &mut task::Context<'_>, buf: &[u8]) -> Poll<Result<usize, io::Error>> {\n        self.project().stream.poll_write(cx, buf)\n    }\n\n    fn poll_flush(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Result<(), io::Error>> {\n        self.project().stream.poll_flush(cx)\n    }\n\n    fn poll_shutdown(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Result<(), io::Error>> {\n        self.project().stream.poll_shutdown(cx)\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/socks/client/socks5/mod.rs",
    "content": "//! SOCKS5 clients\n\npub use self::{tcp_client::Socks5TcpClient, udp_client::Socks5UdpClient};\n\npub mod tcp_client;\npub mod udp_client;\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/socks/client/socks5/tcp_client.rs",
    "content": "//! TCP relay client implementation\n\nuse std::{\n    io,\n    pin::Pin,\n    task::{self, Poll},\n};\n\nuse log::trace;\nuse pin_project::pin_project;\nuse shadowsocks::relay::socks5::{\n    self, Address, Command, Error, HandshakeRequest, HandshakeResponse, Reply, TcpRequestHeader, TcpResponseHeader,\n};\nuse tokio::{\n    io::{AsyncRead, AsyncWrite, ReadBuf},\n    net::{TcpStream, ToSocketAddrs},\n};\n\n/// Socks5 proxy client\n#[pin_project]\npub struct Socks5TcpClient {\n    #[pin]\n    stream: TcpStream,\n}\n\nimpl Socks5TcpClient {\n    /// Connects to `addr` via `proxy`\n    pub async fn connect<A, P>(addr: A, proxy: P) -> Result<Self, Error>\n    where\n        A: Into<Address>,\n        P: ToSocketAddrs,\n    {\n        let mut s = TcpStream::connect(proxy).await?;\n\n        // 1. Handshake\n        let hs = HandshakeRequest::new(vec![socks5::SOCKS5_AUTH_METHOD_NONE]);\n        trace!(\"client connected, going to send handshake: {:?}\", hs);\n\n        hs.write_to(&mut s).await?;\n\n        let hsp = HandshakeResponse::read_from(&mut s).await?;\n\n        trace!(\"got handshake response: {:?}\", hsp);\n        assert_eq!(hsp.chosen_method, socks5::SOCKS5_AUTH_METHOD_NONE);\n\n        // 2. Send request header\n        let h = TcpRequestHeader::new(Command::TcpConnect, addr.into());\n        trace!(\"going to connect, req: {:?}\", h);\n        h.write_to(&mut s).await?;\n\n        let hp = TcpResponseHeader::read_from(&mut s).await?;\n\n        trace!(\"got response: {:?}\", hp);\n        match hp.reply {\n            Reply::Succeeded => (),\n            r => return Err(Error::Reply(r)),\n        }\n\n        Ok(Self { stream: s })\n    }\n\n    /// UDP Associate `addr` via `proxy`\n    ///\n    /// According to RFC, `addr` is the address that your UDP socket binds to\n    pub async fn udp_associate<A, P>(addr: A, proxy: P) -> Result<(Self, Address), Error>\n    where\n        A: Into<Address>,\n        P: ToSocketAddrs,\n    {\n        let mut s = TcpStream::connect(proxy).await?;\n\n        // 1. Handshake\n        let hs = HandshakeRequest::new(vec![socks5::SOCKS5_AUTH_METHOD_NONE]);\n        trace!(\"client connected, going to send handshake: {:?}\", hs);\n\n        hs.write_to(&mut s).await?;\n\n        let hsp = HandshakeResponse::read_from(&mut s).await?;\n\n        trace!(\"got handshake response: {:?}\", hsp);\n        assert_eq!(hsp.chosen_method, socks5::SOCKS5_AUTH_METHOD_NONE);\n\n        // 2. Send request header\n        let h = TcpRequestHeader::new(Command::UdpAssociate, addr.into());\n        trace!(\"going to connect, req: {:?}\", h);\n\n        h.write_to(&mut s).await?;\n        let hp = TcpResponseHeader::read_from(&mut s).await?;\n\n        trace!(\"got response: {:?}\", hp);\n        match hp.reply {\n            Reply::Succeeded => (),\n            r => return Err(Error::Reply(r)),\n        }\n\n        Ok((Self { stream: s }, hp.address))\n    }\n}\n\nimpl AsyncRead for Socks5TcpClient {\n    fn poll_read(\n        self: Pin<&mut Self>,\n        cx: &mut task::Context<'_>,\n        buf: &mut ReadBuf<'_>,\n    ) -> Poll<Result<(), io::Error>> {\n        self.project().stream.poll_read(cx, buf)\n    }\n}\n\nimpl AsyncWrite for Socks5TcpClient {\n    fn poll_write(self: Pin<&mut Self>, cx: &mut task::Context<'_>, buf: &[u8]) -> Poll<Result<usize, io::Error>> {\n        self.project().stream.poll_write(cx, buf)\n    }\n\n    fn poll_flush(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Result<(), io::Error>> {\n        self.project().stream.poll_flush(cx)\n    }\n\n    fn poll_shutdown(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Result<(), io::Error>> {\n        self.project().stream.poll_shutdown(cx)\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/socks/client/socks5/udp_client.rs",
    "content": "//! UDP relay client\n\nuse std::io::{self, Cursor};\n\nuse bytes::{BufMut, BytesMut};\nuse tokio::net::{ToSocketAddrs, UdpSocket};\n\nuse shadowsocks::relay::socks5::{Address, Error, UdpAssociateHeader};\n\nuse super::tcp_client::Socks5TcpClient;\n\n/// Socks5 proxy client\npub struct Socks5UdpClient {\n    socket: UdpSocket,\n    // Socks5 protocol requires to keep this TCP connection alive\n    // Theoretically if this connection is broken, the association is broken too, but the UDP Socks5 server in this crate doesn't behave like that\n    #[allow(dead_code)]\n    assoc_client: Option<Socks5TcpClient>,\n}\n\nimpl Socks5UdpClient {\n    /// Create a new UDP associate client binds to a specific address\n    pub async fn bind<A>(addrs: A) -> io::Result<Self>\n    where\n        A: ToSocketAddrs,\n    {\n        Ok(Self {\n            socket: UdpSocket::bind(addrs).await?,\n            assoc_client: None,\n        })\n    }\n\n    /// Create a new UDP associate to `proxy`\n    pub async fn associate<P>(&mut self, proxy: P) -> Result<(), Error>\n    where\n        P: ToSocketAddrs,\n    {\n        if self.assoc_client.is_some() {\n            let err = io::Error::other(\"udp is associated\");\n            return Err(err.into());\n        }\n\n        // The actual bind address, tell the proxy that I am going to send packets from this address\n        let local_addr = self.socket.local_addr()?;\n\n        let (assoc_client, proxy_addr) = Socks5TcpClient::udp_associate(local_addr, proxy).await?;\n        match proxy_addr {\n            Address::SocketAddress(sa) => self.socket.connect(sa).await?,\n            // FIXME: `connect` will use tokio's builtin DNS resolver.\n            // But if we want to use `hickory-dns`, we have to initialize a `Context` instance (for the global `AsyncResolver` instance)\n            Address::DomainNameAddress(ref dname, port) => self.socket.connect((dname.as_str(), port)).await?,\n        }\n\n        self.assoc_client = Some(assoc_client);\n\n        Ok(())\n    }\n\n    /// Returns a future that sends data on the socket to the given address.\n    pub async fn send_to<A>(&self, frag: u8, buf: &[u8], target: A) -> Result<usize, Error>\n    where\n        A: Into<Address>,\n    {\n        self.check_associated()?;\n\n        let header = UdpAssociateHeader::new(frag, target.into());\n        let header_len = header.serialized_len();\n        let mut send_buf = BytesMut::with_capacity(header.serialized_len() + buf.len());\n        header.write_to_buf(&mut send_buf);\n        send_buf.put_slice(buf);\n\n        let n = self.socket.send(&send_buf).await?;\n        Ok(n.saturating_sub(header_len))\n    }\n\n    /// Returns a future that receives a single datagram on the socket. On success, the future resolves to the number of bytes read and the origin.\n    ///\n    /// The function must be called with valid byte array buf of sufficient size to hold the message bytes.\n    /// If a message is too long to fit in the supplied buffer, excess bytes may be discarded.\n    pub async fn recv_from(&self, recv_buf: &mut [u8]) -> Result<(usize, u8, Address), Error> {\n        self.check_associated()?;\n\n        let n = self.socket.recv(recv_buf).await?;\n\n        // Address + Payload\n        let mut cur = Cursor::new(&recv_buf[..n]);\n\n        let header = UdpAssociateHeader::read_from(&mut cur).await?;\n        let pos = cur.position() as usize;\n\n        recv_buf.copy_within(pos.., 0);\n\n        Ok((n - pos, header.frag, header.address))\n    }\n\n    fn check_associated(&self) -> io::Result<()> {\n        if self.assoc_client.is_none() {\n            let err = io::Error::other(\"udp not associated\");\n            return Err(err);\n        }\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/socks/config.rs",
    "content": "//! SOCK protocol configuration\n\nuse std::{\n    collections::HashMap,\n    fs::OpenOptions,\n    io::{self, Read},\n    path::Path,\n};\n\nuse log::trace;\nuse serde::Deserialize;\n\n#[derive(Deserialize, Debug)]\nstruct SSSocks5AuthPasswordUserConfig {\n    user_name: String,\n    password: String,\n}\n\n#[derive(Deserialize, Debug)]\nstruct SSSocks5AuthPasswordConfig {\n    users: Vec<SSSocks5AuthPasswordUserConfig>,\n}\n\n#[derive(Deserialize, Debug)]\nstruct SSSocks5AuthConfig {\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    password: Option<SSSocks5AuthPasswordConfig>,\n}\n\n/// SOCKS5 Authentication method\n#[derive(Debug, Clone)]\npub struct Socks5AuthConfig {\n    pub passwd: Socks5AuthPasswdConfig,\n}\n\nimpl Socks5AuthConfig {\n    /// Create a new SOCKS5 Authentication configuration\n    pub fn new() -> Self {\n        Self {\n            passwd: Socks5AuthPasswdConfig::new(),\n        }\n    }\n\n    /// Load from configuration file\n    ///\n    /// ```json\n    /// {\n    ///     \"password\": {\n    ///         \"users\": [\n    ///             {\n    ///                 \"user_name\": \"USER_NAME\",\n    ///                 \"password\": \"PASSWORD\"\n    ///             }\n    ///         ]\n    ///      }\n    /// }\n    pub fn load_from_file<P: AsRef<Path> + ?Sized>(filename: &P) -> io::Result<Self> {\n        let filename = filename.as_ref();\n\n        trace!(\n            \"loading socks5 authentication configuration from {}\",\n            filename.display()\n        );\n\n        let mut reader = OpenOptions::new().read(true).open(filename)?;\n        let mut content = String::new();\n        reader.read_to_string(&mut content)?;\n\n        let jconf: SSSocks5AuthConfig = match json5::from_str(&content) {\n            Ok(c) => c,\n            Err(err) => return Err(io::Error::other(err)),\n        };\n\n        let mut passwd = Socks5AuthPasswdConfig::new();\n        if let Some(p) = jconf.password {\n            for user in p.users {\n                passwd.add_user(user.user_name, user.password);\n            }\n        }\n\n        Ok(Self { passwd })\n    }\n\n    /// Check if authentication is required\n    pub fn auth_required(&self) -> bool {\n        self.passwd.total_users() > 0\n    }\n}\n\nimpl Default for Socks5AuthConfig {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\n/// SOCKS5 server User/Password Authentication configuration\n///\n/// RFC1929 https://datatracker.ietf.org/doc/html/rfc1929\n#[derive(Debug, Clone)]\npub struct Socks5AuthPasswdConfig {\n    passwd: HashMap<String, String>,\n}\n\nimpl Socks5AuthPasswdConfig {\n    /// Create an empty `Passwd` configuration\n    pub fn new() -> Self {\n        Self { passwd: HashMap::new() }\n    }\n\n    /// Add a user with password\n    pub fn add_user<U, P>(&mut self, user_name: U, password: P)\n    where\n        U: Into<String>,\n        P: Into<String>,\n    {\n        self.passwd.insert(user_name.into(), password.into());\n    }\n\n    /// Check if `user_name` exists and validate `password`\n    pub fn check_user<U, P>(&self, user_name: U, password: P) -> bool\n    where\n        U: AsRef<str>,\n        P: AsRef<str>,\n    {\n        match self.passwd.get(user_name.as_ref()) {\n            Some(pwd) => pwd == password.as_ref(),\n            None => false,\n        }\n    }\n\n    /// Total users\n    pub fn total_users(&self) -> usize {\n        self.passwd.len()\n    }\n}\n\nimpl Default for Socks5AuthPasswdConfig {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/socks/mod.rs",
    "content": "//! Shadowsocks SOCKS (4/4a, 5) Local Server\n\npub use self::server::{Socks, SocksBuilder};\n\npub mod client;\npub mod config;\npub mod server;\n#[cfg(feature = \"local-socks4\")]\npub mod socks4;\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/socks/server/mod.rs",
    "content": "//! Shadowsocks SOCKS Local Server\n\nuse std::{io, sync::Arc, time::Duration};\n\nuse futures::{FutureExt, future};\nuse shadowsocks::{ServerAddr, config::Mode};\n\nuse crate::local::{context::ServiceContext, loadbalancing::PingBalancer};\n\npub use self::server::{SocksTcpServer, SocksTcpServerBuilder, SocksUdpServer};\nuse self::socks5::Socks5UdpServerBuilder;\n\nuse super::config::Socks5AuthConfig;\n#[cfg(feature = \"local-http\")]\nuse crate::local::http::config::HttpAuthConfig;\n\n#[allow(clippy::module_inception)]\nmod server;\n#[cfg(feature = \"local-socks4\")]\nmod socks4;\nmod socks5;\n\n/// SOCKS4/4a, SOCKS5 Local Server builder\npub struct SocksBuilder {\n    context: Arc<ServiceContext>,\n    mode: Mode,\n    udp_expiry_duration: Option<Duration>,\n    udp_capacity: Option<usize>,\n    udp_bind_addr: Option<ServerAddr>,\n    udp_associate_addr: Option<ServerAddr>,\n    socks5_auth: Socks5AuthConfig,\n    client_config: ServerAddr,\n    balancer: PingBalancer,\n    #[cfg(target_os = \"macos\")]\n    launchd_tcp_socket_name: Option<String>,\n    #[cfg(target_os = \"macos\")]\n    launchd_udp_socket_name: Option<String>,\n    #[cfg(feature = \"local-http\")]\n    http_auth: HttpAuthConfig,\n}\n\nimpl SocksBuilder {\n    /// Create a new SOCKS server with default configuration\n    pub fn new(client_config: ServerAddr, balancer: PingBalancer) -> Self {\n        let context = ServiceContext::new();\n        Self::with_context(Arc::new(context), client_config, balancer)\n    }\n\n    /// Create a new SOCKS server with context\n    pub fn with_context(context: Arc<ServiceContext>, client_config: ServerAddr, balancer: PingBalancer) -> Self {\n        Self {\n            context,\n            mode: Mode::TcpOnly,\n            udp_expiry_duration: None,\n            udp_capacity: None,\n            udp_bind_addr: None,\n            udp_associate_addr: None,\n            socks5_auth: Socks5AuthConfig::default(),\n            client_config,\n            balancer,\n            #[cfg(target_os = \"macos\")]\n            launchd_tcp_socket_name: None,\n            #[cfg(target_os = \"macos\")]\n            launchd_udp_socket_name: None,\n            #[cfg(feature = \"local-http\")]\n            http_auth: HttpAuthConfig::default(),\n        }\n    }\n\n    /// Set server mode\n    pub fn set_mode(&mut self, mode: Mode) {\n        self.mode = mode;\n    }\n\n    /// Set UDP association's expiry duration\n    pub fn set_udp_expiry_duration(&mut self, d: Duration) {\n        self.udp_expiry_duration = Some(d);\n    }\n\n    /// Set total UDP association to be kept simultaneously in server\n    pub fn set_udp_capacity(&mut self, c: usize) {\n        self.udp_capacity = Some(c);\n    }\n\n    /// UDP server's bind address\n    ///\n    /// * If `mode` is `tcp_only`, then it will still return this address for `UDP_ASSOCIATE` command\n    /// * Otherwise, UDP relay will bind to this address\n    pub fn set_udp_bind_addr(&mut self, a: ServerAddr) {\n        self.udp_bind_addr = Some(a);\n    }\n\n    pub fn set_udp_associate_addr(&mut self, a: ServerAddr) {\n        self.udp_associate_addr = Some(a);\n    }\n\n    /// Set SOCKS5 Username/Password Authentication configuration\n    pub fn set_socks5_auth(&mut self, p: Socks5AuthConfig) {\n        self.socks5_auth = p;\n    }\n\n    /// Set HTTP Authentication configuration\n    #[cfg(feature = \"local-http\")]\n    pub fn set_http_auth(&mut self, p: HttpAuthConfig) {\n        self.http_auth = p;\n    }\n\n    /// macOS launchd activate socket\n    #[cfg(target_os = \"macos\")]\n    pub fn set_launchd_tcp_socket_name(&mut self, n: String) {\n        self.launchd_tcp_socket_name = Some(n);\n    }\n\n    /// macOS launchd activate socket\n    #[cfg(target_os = \"macos\")]\n    pub fn set_launchd_udp_socket_name(&mut self, n: String) {\n        self.launchd_udp_socket_name = Some(n);\n    }\n\n    pub async fn build(self) -> io::Result<Socks> {\n        let udp_bind_addr = self.udp_bind_addr.clone().unwrap_or_else(|| self.client_config.clone());\n        let udp_associate_addr: ServerAddr = self\n            .udp_associate_addr\n            .as_ref()\n            .or(self.udp_bind_addr.as_ref())\n            .unwrap_or(&self.client_config)\n            .clone();\n\n        let mut udp_server = None;\n        if self.mode.enable_udp() {\n            #[allow(unused_mut)]\n            let mut builder = Socks5UdpServerBuilder::new(\n                self.context.clone(),\n                udp_bind_addr,\n                self.udp_expiry_duration,\n                self.udp_capacity,\n                self.balancer.clone(),\n            );\n\n            #[cfg(target_os = \"macos\")]\n            if let Some(s) = self.launchd_udp_socket_name {\n                builder.set_launchd_socket_name(s);\n            }\n\n            let server = builder.build().await?;\n            udp_server = Some(server);\n        }\n\n        let mut tcp_server = None;\n        if self.mode.enable_tcp() {\n            #[allow(unused_mut)]\n            let mut builder = SocksTcpServerBuilder::new(\n                self.context.clone(),\n                self.client_config,\n                udp_associate_addr,\n                self.balancer.clone(),\n                self.mode,\n                self.socks5_auth,\n                #[cfg(feature = \"local-http\")]\n                self.http_auth,\n            );\n\n            #[cfg(target_os = \"macos\")]\n            if let Some(s) = self.launchd_tcp_socket_name {\n                builder.set_launchd_socket_name(s);\n            }\n\n            let server = builder.build().await?;\n            tcp_server = Some(server);\n        }\n\n        Ok(Socks { tcp_server, udp_server })\n    }\n}\n\n/// SOCKS4/4a, SOCKS5 Local Server\npub struct Socks {\n    tcp_server: Option<SocksTcpServer>,\n    udp_server: Option<SocksUdpServer>,\n}\n\nimpl Socks {\n    /// TCP server instance\n    pub fn tcp_server(&self) -> Option<&SocksTcpServer> {\n        self.tcp_server.as_ref()\n    }\n\n    /// UDP server instance\n    pub fn udp_server(&self) -> Option<&SocksUdpServer> {\n        self.udp_server.as_ref()\n    }\n\n    /// Start serving\n    pub async fn run(self) -> io::Result<()> {\n        let mut vfut = Vec::new();\n\n        if let Some(tcp_server) = self.tcp_server {\n            vfut.push(tcp_server.run().boxed());\n        }\n\n        if let Some(udp_server) = self.udp_server {\n            // NOTE: SOCKS 5 RFC requires TCP handshake for UDP ASSOCIATE command\n            // But here we can start a standalone UDP SOCKS 5 relay server, for special use cases\n            vfut.push(udp_server.run().boxed());\n        }\n\n        let (res, ..) = future::select_all(vfut).await;\n        res\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/socks/server/server.rs",
    "content": "use std::{io, net::SocketAddr, sync::Arc, time::Duration};\n\nuse log::{error, info};\nuse shadowsocks::{ServerAddr, config::Mode, net::TcpListener as ShadowTcpListener};\nuse tokio::{net::TcpStream, time};\n\n#[cfg(feature = \"local-http\")]\nuse crate::local::http::{HttpConnectionHandler, config::HttpAuthConfig};\nuse crate::local::{\n    context::ServiceContext, loadbalancing::PingBalancer, net::tcp::listener::create_standard_tcp_listener,\n    socks::config::Socks5AuthConfig,\n};\n\n#[cfg(feature = \"local-socks4\")]\nuse super::socks4::Socks4TcpHandler;\nuse super::socks5::{Socks5TcpHandler, Socks5UdpServer};\n\npub struct SocksTcpServerBuilder {\n    context: Arc<ServiceContext>,\n    client_config: ServerAddr,\n    udp_associate_addr: ServerAddr,\n    balancer: PingBalancer,\n    mode: Mode,\n    socks5_auth: Arc<Socks5AuthConfig>,\n    #[cfg(target_os = \"macos\")]\n    launchd_socket_name: Option<String>,\n    #[cfg(feature = \"local-http\")]\n    http_auth: Arc<HttpAuthConfig>,\n}\n\nimpl SocksTcpServerBuilder {\n    pub(crate) fn new(\n        context: Arc<ServiceContext>,\n        client_config: ServerAddr,\n        udp_associate_addr: ServerAddr,\n        balancer: PingBalancer,\n        mode: Mode,\n        socks5_auth: Socks5AuthConfig,\n        #[cfg(feature = \"local-http\")] http_auth: HttpAuthConfig,\n    ) -> Self {\n        Self {\n            context,\n            client_config,\n            udp_associate_addr,\n            balancer,\n            mode,\n            socks5_auth: Arc::new(socks5_auth),\n            #[cfg(target_os = \"macos\")]\n            launchd_socket_name: None,\n            #[cfg(feature = \"local-http\")]\n            http_auth: Arc::new(http_auth),\n        }\n    }\n\n    /// macOS launchd activate socket\n    #[cfg(target_os = \"macos\")]\n    pub fn set_launchd_socket_name(&mut self, n: String) {\n        self.launchd_socket_name = Some(n);\n    }\n\n    pub async fn build(self) -> io::Result<SocksTcpServer> {\n        cfg_if::cfg_if! {\n            if #[cfg(target_os = \"macos\")] {\n                let listener = match self.launchd_socket_name {\n                    Some(launchd_socket_name) => {\n                        use tokio::net::TcpListener as TokioTcpListener;\n                        use crate::net::launch_activate_socket::get_launch_activate_tcp_listener;\n\n                        let std_listener = get_launch_activate_tcp_listener(&launchd_socket_name, true)?;\n                        let tokio_listener = TokioTcpListener::from_std(std_listener)?;\n                        ShadowTcpListener::from_listener(tokio_listener, self.context.accept_opts())?\n                    } _ => {\n                        create_standard_tcp_listener(&self.context, &self.client_config).await?\n                    }\n                };\n            } else {\n                let listener = create_standard_tcp_listener(&self.context, &self.client_config).await?;\n            }\n        }\n\n        Ok(SocksTcpServer {\n            context: self.context,\n            listener,\n            udp_associate_addr: self.udp_associate_addr,\n            balancer: self.balancer,\n            mode: self.mode,\n            socks5_auth: self.socks5_auth,\n            #[cfg(feature = \"local-http\")]\n            http_auth: self.http_auth,\n        })\n    }\n}\n\n/// SOCKS TCP server instance\npub struct SocksTcpServer {\n    context: Arc<ServiceContext>,\n    listener: ShadowTcpListener,\n    udp_associate_addr: ServerAddr,\n    balancer: PingBalancer,\n    mode: Mode,\n    socks5_auth: Arc<Socks5AuthConfig>,\n    #[cfg(feature = \"local-http\")]\n    http_auth: Arc<HttpAuthConfig>,\n}\n\nimpl SocksTcpServer {\n    /// Get TCP server local addr\n    pub fn local_addr(&self) -> io::Result<SocketAddr> {\n        self.listener.local_addr()\n    }\n\n    /// Start TCP accept loop\n    pub async fn run(self) -> io::Result<()> {\n        info!(\"shadowsocks socks TCP listening on {}\", self.listener.local_addr()?);\n\n        // If UDP is enabled, SOCK5 UDP_ASSOCIATE command will let client to send requests to this address\n        let udp_associate_addr = Arc::new(self.udp_associate_addr);\n        #[cfg(feature = \"local-http\")]\n        let http_handler =\n            HttpConnectionHandler::new(self.context.clone(), self.balancer.clone(), self.http_auth.clone());\n\n        loop {\n            let (stream, peer_addr) = match self.listener.accept().await {\n                Ok(s) => s,\n                Err(err) => {\n                    error!(\"accept failed with error: {}\", err);\n                    time::sleep(Duration::from_secs(1)).await;\n                    continue;\n                }\n            };\n\n            let handler = SocksTcpHandler {\n                context: self.context.clone(),\n                udp_associate_addr: udp_associate_addr.clone(),\n                stream,\n                balancer: self.balancer.clone(),\n                peer_addr,\n                mode: self.mode,\n                socks5_auth: self.socks5_auth.clone(),\n                #[cfg(feature = \"local-http\")]\n                http_handler: http_handler.clone(),\n            };\n\n            tokio::spawn(async move {\n                if let Err(err) = handler.handle_tcp_client().await {\n                    error!(\"socks5 tcp client handler error: {}\", err);\n                }\n            });\n        }\n    }\n}\n\nstruct SocksTcpHandler {\n    context: Arc<ServiceContext>,\n    udp_associate_addr: Arc<ServerAddr>,\n    stream: TcpStream,\n    balancer: PingBalancer,\n    peer_addr: SocketAddr,\n    mode: Mode,\n    socks5_auth: Arc<Socks5AuthConfig>,\n    #[cfg(feature = \"local-http\")]\n    http_handler: HttpConnectionHandler,\n}\n\nimpl SocksTcpHandler {\n    #[cfg(not(any(feature = \"local-socks4\", feature = \"local-http\")))]\n    async fn handle_tcp_client(self) -> io::Result<()> {\n        let handler = Socks5TcpHandler::new(\n            self.context,\n            self.udp_associate_addr,\n            self.balancer,\n            self.mode,\n            self.socks5_auth,\n        );\n        handler.handle_socks5_client(self.stream, self.peer_addr).await\n    }\n\n    #[cfg(any(feature = \"local-socks4\", feature = \"local-http\"))]\n    async fn handle_tcp_client(self) -> io::Result<()> {\n        use std::io::ErrorKind;\n\n        let mut version_buffer = [0u8; 1];\n        let n = self.stream.peek(&mut version_buffer).await?;\n        if n == 0 {\n            return Err(ErrorKind::UnexpectedEof.into());\n        }\n\n        match version_buffer[0] {\n            #[cfg(feature = \"local-socks4\")]\n            0x04 => {\n                if self.socks5_auth.auth_required() {\n                    error!(\"SOCKS4 disabled when authentication is configured\");\n                    Err(io::Error::other(\"SOCKS4 unsupported\"))\n                } else {\n                    let handler = Socks4TcpHandler::new(self.context, self.balancer, self.mode);\n                    handler.handle_socks4_client(self.stream, self.peer_addr).await\n                }\n            }\n\n            0x05 => {\n                let handler = Socks5TcpHandler::new(\n                    self.context,\n                    self.udp_associate_addr,\n                    self.balancer,\n                    self.mode,\n                    self.socks5_auth,\n                );\n                handler.handle_socks5_client(self.stream, self.peer_addr).await\n            }\n\n            #[cfg(feature = \"local-http\")]\n            b'G' | b'g' | b'H' | b'h' | b'P' | b'p' | b'D' | b'd' | b'C' | b'c' | b'O' | b'o' | b'T' | b't' => {\n                if self.socks5_auth.auth_required() {\n                    error!(\"HTTP disabled when authentication is configured\");\n                    Err(io::Error::other(\"HTTP unsupported\"))\n                } else {\n                    // GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH\n                    match self.http_handler.serve_connection(self.stream, self.peer_addr).await {\n                        Ok(..) => Ok(()),\n                        Err(err) => {\n                            error!(\"HTTP connection {} handler failed with error: {}\", self.peer_addr, err);\n                            Err(io::Error::other(err))\n                        }\n                    }\n                }\n            }\n\n            version => {\n                error!(\"unsupported socks version {:x}\", version);\n                let err = io::Error::other(\"unsupported socks version\");\n                Err(err)\n            }\n        }\n    }\n}\n\n/// SOCKS UDP server\npub type SocksUdpServer = Socks5UdpServer;\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/socks/server/socks4/mod.rs",
    "content": "//! SOCKS4/4a Local Server\n\npub use self::tcprelay::Socks4TcpHandler;\n\nmod tcprelay;\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/socks/server/socks4/tcprelay.rs",
    "content": "//! Shadowsocks SOCKS4/4a Local Server\n\nuse std::{\n    io::{self, ErrorKind},\n    net::SocketAddr,\n    sync::Arc,\n};\n\nuse log::{debug, error, trace, warn};\nuse shadowsocks::config::Mode;\nuse tokio::{\n    io::{AsyncWriteExt, BufReader},\n    net::TcpStream,\n};\n\nuse crate::local::{\n    context::ServiceContext,\n    loadbalancing::PingBalancer,\n    net::AutoProxyClientStream,\n    utils::{establish_tcp_tunnel, establish_tcp_tunnel_bypassed},\n};\n\nuse crate::local::socks::socks4::{\n    Address, Command, Error as Socks4Error, HandshakeRequest, HandshakeResponse, ResultCode,\n};\n\npub struct Socks4TcpHandler {\n    context: Arc<ServiceContext>,\n    balancer: PingBalancer,\n    mode: Mode,\n}\n\nimpl Socks4TcpHandler {\n    pub fn new(context: Arc<ServiceContext>, balancer: PingBalancer, mode: Mode) -> Self {\n        Self {\n            context,\n            balancer,\n            mode,\n        }\n    }\n\n    pub async fn handle_socks4_client(self, stream: TcpStream, peer_addr: SocketAddr) -> io::Result<()> {\n        // 1. Handshake\n\n        // NOTE: Wraps it with BufReader for reading NULL terminated information in HandshakeRequest\n        let mut s = BufReader::new(stream);\n        let handshake_req = match HandshakeRequest::read_from(&mut s).await {\n            Ok(r) => r,\n            Err(Socks4Error::IoError(ref err)) if err.kind() == ErrorKind::UnexpectedEof => {\n                trace!(\"socks4 handshake early eof. peer: {}\", peer_addr);\n                return Ok(());\n            }\n            Err(err) => {\n                error!(\"socks4 handshake error: {}\", err);\n                return Err(err.into());\n            }\n        };\n\n        trace!(\"socks4 {:?} peer: {}\", handshake_req, peer_addr);\n\n        match handshake_req.cd {\n            Command::Connect => {\n                debug!(\"CONNECT {}\", handshake_req.dst);\n\n                self.handle_socks4_connect(s, peer_addr, handshake_req.dst).await\n            }\n            Command::Bind => {\n                warn!(\"BIND is not supported\");\n\n                let handshake_rsp = HandshakeResponse::new(ResultCode::RequestRejectedOrFailed);\n                handshake_rsp.write_to(&mut s).await?;\n\n                Ok(())\n            }\n        }\n    }\n\n    async fn handle_socks4_connect(\n        self,\n        mut stream: BufReader<TcpStream>,\n        peer_addr: SocketAddr,\n        target_addr: Address,\n    ) -> io::Result<()> {\n        if !self.mode.enable_tcp() {\n            warn!(\"TCP CONNECT is disabled\");\n\n            let handshake_rsp = HandshakeResponse::new(ResultCode::RequestRejectedOrFailed);\n            handshake_rsp.write_to(&mut stream).await?;\n\n            return Ok(());\n        }\n\n        let target_addr = target_addr.into();\n        let mut server_opt = None;\n        let server_result = if self.balancer.is_empty() {\n            AutoProxyClientStream::connect_bypassed(self.context, &target_addr).await\n        } else {\n            let server = self.balancer.best_tcp_server();\n\n            let r = AutoProxyClientStream::connect_with_opts(\n                self.context,\n                &server,\n                &target_addr,\n                server.connect_opts_ref(),\n            )\n            .await;\n            server_opt = Some(server);\n\n            r\n        };\n\n        let mut remote = match server_result {\n            Ok(remote) => {\n                // Tell the client that we are ready\n                let handshake_rsp = HandshakeResponse::new(ResultCode::RequestGranted);\n                handshake_rsp.write_to(&mut stream).await?;\n\n                trace!(\"sent header: {:?}\", handshake_rsp);\n\n                remote\n            }\n            Err(err) => {\n                let result_code = match err.kind() {\n                    ErrorKind::ConnectionRefused => ResultCode::RequestRejectedCannotConnect,\n                    ErrorKind::ConnectionAborted => ResultCode::RequestRejectedCannotConnect,\n                    _ => ResultCode::RequestRejectedOrFailed,\n                };\n\n                let handshake_rsp = HandshakeResponse::new(result_code);\n                handshake_rsp.write_to(&mut stream).await?;\n\n                return Err(err);\n            }\n        };\n\n        // NOTE: Transfer all buffered data before unwrap, or these data will be lost\n        let buffer = stream.buffer();\n        if !buffer.is_empty() {\n            remote.write_all(buffer).await?;\n        }\n\n        // UNWRAP.\n        let mut stream = stream.into_inner();\n\n        match server_opt {\n            Some(server) => {\n                let svr_cfg = server.server_config();\n                establish_tcp_tunnel(svr_cfg, &mut stream, &mut remote, peer_addr, &target_addr).await\n            }\n            None => establish_tcp_tunnel_bypassed(&mut stream, &mut remote, peer_addr, &target_addr).await,\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/socks/server/socks5/mod.rs",
    "content": "//! SOCKS5 Local Server\n\npub use self::{\n    tcprelay::Socks5TcpHandler,\n    udprelay::{Socks5UdpServer, Socks5UdpServerBuilder},\n};\n\nmod tcprelay;\nmod udprelay;\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/socks/server/socks5/tcprelay.rs",
    "content": "//! SOCKS5 TCP Server\n\nuse std::{\n    io::{self, ErrorKind},\n    net::{Ipv4Addr, SocketAddr},\n    str,\n    sync::Arc,\n};\n\nuse log::{debug, error, trace, warn};\nuse shadowsocks::{\n    ServerAddr,\n    config::Mode,\n    relay::socks5::{\n        self, Address, Command, Error as Socks5Error, HandshakeRequest, HandshakeResponse, PasswdAuthRequest,\n        PasswdAuthResponse, Reply, TcpRequestHeader, TcpResponseHeader,\n    },\n};\nuse tokio::net::TcpStream;\n\nuse crate::{\n    local::{\n        context::ServiceContext,\n        loadbalancing::PingBalancer,\n        net::AutoProxyClientStream,\n        socks::config::Socks5AuthConfig,\n        utils::{establish_tcp_tunnel, establish_tcp_tunnel_bypassed},\n    },\n    net::utils::ignore_until_end,\n};\n\npub struct Socks5TcpHandler {\n    context: Arc<ServiceContext>,\n    udp_associate_addr: Arc<ServerAddr>,\n    balancer: PingBalancer,\n    mode: Mode,\n    auth: Arc<Socks5AuthConfig>,\n}\n\nimpl Socks5TcpHandler {\n    pub fn new(\n        context: Arc<ServiceContext>,\n        udp_associate_addr: Arc<ServerAddr>,\n        balancer: PingBalancer,\n        mode: Mode,\n        auth: Arc<Socks5AuthConfig>,\n    ) -> Self {\n        Self {\n            context,\n            udp_associate_addr,\n            balancer,\n            mode,\n            auth,\n        }\n    }\n\n    async fn check_auth(&self, stream: &mut TcpStream, handshake_req: &HandshakeRequest) -> io::Result<()> {\n        use std::io::Error;\n\n        let allow_none = !self.auth.auth_required();\n\n        for method in handshake_req.methods.iter() {\n            match *method {\n                socks5::SOCKS5_AUTH_METHOD_PASSWORD => {\n                    let resp = HandshakeResponse::new(socks5::SOCKS5_AUTH_METHOD_PASSWORD);\n                    trace!(\"reply handshake {:?}\", resp);\n                    resp.write_to(stream).await?;\n\n                    return self.check_auth_password(stream).await;\n                }\n                socks5::SOCKS5_AUTH_METHOD_NONE => {\n                    if !allow_none {\n                        trace!(\"none authentication method is not allowed\");\n                    } else {\n                        let resp = HandshakeResponse::new(socks5::SOCKS5_AUTH_METHOD_NONE);\n                        trace!(\"reply handshake {:?}\", resp);\n                        resp.write_to(stream).await?;\n\n                        return Ok(());\n                    }\n                }\n                _ => {\n                    trace!(\"unsupported authentication method {}\", method);\n                }\n            }\n        }\n\n        let resp = HandshakeResponse::new(socks5::SOCKS5_AUTH_METHOD_NOT_ACCEPTABLE);\n        resp.write_to(stream).await?;\n\n        trace!(\"reply handshake {:?}\", resp);\n\n        Err(Error::other(\n            \"currently shadowsocks-rust does not support authentication\",\n        ))\n    }\n\n    async fn check_auth_password(&self, stream: &mut TcpStream) -> io::Result<()> {\n        use std::io::Error;\n\n        const PASSWORD_AUTH_STATUS_FAILURE: u8 = 255;\n\n        // Read initiation negotiation\n\n        let req = match PasswdAuthRequest::read_from(stream).await {\n            Ok(i) => i,\n            Err(err) => {\n                let rsp = PasswdAuthResponse::new(err.as_reply().as_u8());\n                let _ = rsp.write_to(stream).await;\n\n                return Err(Error::other(format!(\n                    \"Username/Password Authentication Initial request failed: {err}\"\n                )));\n            }\n        };\n\n        let user_name = match str::from_utf8(&req.uname) {\n            Ok(u) => u,\n            Err(..) => {\n                let rsp = PasswdAuthResponse::new(PASSWORD_AUTH_STATUS_FAILURE);\n                let _ = rsp.write_to(stream).await;\n\n                return Err(Error::other(\n                    \"Username/Password Authentication Initial request uname contains invalid characters\",\n                ));\n            }\n        };\n\n        let password = match str::from_utf8(&req.passwd) {\n            Ok(u) => u,\n            Err(..) => {\n                let rsp = PasswdAuthResponse::new(PASSWORD_AUTH_STATUS_FAILURE);\n                let _ = rsp.write_to(stream).await;\n\n                return Err(Error::other(\n                    \"Username/Password Authentication Initial request passwd contains invalid characters\",\n                ));\n            }\n        };\n\n        if self.auth.passwd.check_user(user_name, password) {\n            trace!(\n                \"socks5 authenticated with Username/Password method, user: {}, password: {}\",\n                user_name, password\n            );\n\n            let rsp = PasswdAuthResponse::new(0);\n            rsp.write_to(stream).await?;\n\n            Ok(())\n        } else {\n            let rsp = PasswdAuthResponse::new(PASSWORD_AUTH_STATUS_FAILURE);\n            rsp.write_to(stream).await?;\n\n            error!(\n                \"socks5 rejected Username/Password user: {}, password: {}\",\n                user_name, password\n            );\n\n            Err(Error::other(format!(\n                \"Username/Password Authentication failed, user: {user_name}, password: {password}\"\n            )))\n        }\n    }\n\n    pub async fn handle_socks5_client(self, mut stream: TcpStream, peer_addr: SocketAddr) -> io::Result<()> {\n        // 1. Handshake\n\n        let handshake_req = match HandshakeRequest::read_from(&mut stream).await {\n            Ok(r) => r,\n            Err(Socks5Error::IoError(ref err)) if err.kind() == ErrorKind::UnexpectedEof => {\n                trace!(\"socks5 handshake early eof. peer: {}\", peer_addr);\n                return Ok(());\n            }\n            Err(err) => {\n                error!(\"socks5 handshake error: {}\", err);\n                return Err(err.into());\n            }\n        };\n\n        trace!(\"socks5 {:?}\", handshake_req);\n        self.check_auth(&mut stream, &handshake_req).await?;\n\n        // 2. Fetch headers\n        let header = match TcpRequestHeader::read_from(&mut stream).await {\n            Ok(h) => h,\n            Err(err) => {\n                error!(\"failed to get TcpRequestHeader: {}, peer: {}\", err, peer_addr);\n                let rh = TcpResponseHeader::new(err.as_reply(), Address::SocketAddress(peer_addr));\n                rh.write_to(&mut stream).await?;\n                return Err(err.into());\n            }\n        };\n\n        trace!(\"socks5 {:?} peer: {}\", header, peer_addr);\n\n        let addr = header.address;\n\n        // 3. Handle Command\n        match header.command {\n            Command::TcpConnect => {\n                debug!(\"CONNECT {}\", addr);\n\n                self.handle_tcp_connect(stream, peer_addr, addr).await\n            }\n            Command::UdpAssociate => {\n                debug!(\"UDP ASSOCIATE from {}\", addr);\n\n                self.handle_udp_associate(stream, addr).await\n            }\n            Command::TcpBind => {\n                warn!(\"BIND is not supported\");\n                let rh = TcpResponseHeader::new(socks5::Reply::CommandNotSupported, addr);\n                rh.write_to(&mut stream).await?;\n\n                Ok(())\n            }\n        }\n    }\n\n    async fn handle_tcp_connect(\n        self,\n        mut stream: TcpStream,\n        peer_addr: SocketAddr,\n        target_addr: Address,\n    ) -> io::Result<()> {\n        if !self.mode.enable_tcp() {\n            warn!(\"TCP CONNECT is disabled\");\n\n            let rh = TcpResponseHeader::new(socks5::Reply::CommandNotSupported, target_addr);\n            rh.write_to(&mut stream).await?;\n\n            return Ok(());\n        }\n\n        let mut server_opt = None;\n        let remote_result = if self.balancer.is_empty() {\n            AutoProxyClientStream::connect_bypassed(self.context.clone(), &target_addr).await\n        } else {\n            let server = self.balancer.best_tcp_server();\n\n            let r = AutoProxyClientStream::connect_with_opts(\n                self.context,\n                &server,\n                &target_addr,\n                server.connect_opts_ref(),\n            )\n            .await;\n            server_opt = Some(server);\n\n            r\n        };\n\n        let mut remote = match remote_result {\n            Ok(remote) => {\n                // Tell the client that we are ready\n                let header =\n                    TcpResponseHeader::new(socks5::Reply::Succeeded, Address::SocketAddress(remote.local_addr()?));\n                header.write_to(&mut stream).await?;\n\n                trace!(\"sent header: {:?}\", header);\n\n                remote\n            }\n            Err(err) => {\n                let reply = match err.kind() {\n                    ErrorKind::ConnectionRefused => Reply::ConnectionRefused,\n                    ErrorKind::ConnectionAborted => Reply::HostUnreachable,\n                    _ => Reply::NetworkUnreachable,\n                };\n\n                let dummy_address = SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), 0);\n                let header = TcpResponseHeader::new(reply, Address::SocketAddress(dummy_address));\n                header.write_to(&mut stream).await?;\n\n                return Err(err);\n            }\n        };\n\n        match server_opt {\n            Some(server) => {\n                let svr_cfg = server.server_config();\n                establish_tcp_tunnel(svr_cfg, &mut stream, &mut remote, peer_addr, &target_addr).await\n            }\n            None => establish_tcp_tunnel_bypassed(&mut stream, &mut remote, peer_addr, &target_addr).await,\n        }\n    }\n\n    async fn handle_udp_associate(self, mut stream: TcpStream, client_addr: Address) -> io::Result<()> {\n        if !self.mode.enable_udp() {\n            warn!(\"socks5 udp is disabled\");\n\n            let rh = TcpResponseHeader::new(socks5::Reply::CommandNotSupported, client_addr);\n            rh.write_to(&mut stream).await?;\n\n            return Ok(());\n        }\n\n        // shadowsocks accepts both TCP and UDP from the same address\n\n        let rh = TcpResponseHeader::new(socks5::Reply::Succeeded, self.udp_associate_addr.as_ref().into());\n        rh.write_to(&mut stream).await?;\n\n        // Hold connection until EOF.\n        let _ = ignore_until_end(&mut stream).await;\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/socks/server/socks5/udprelay.rs",
    "content": "//! UDP Tunnel server\n\nuse std::{\n    io::{self, Cursor},\n    net::{IpAddr, SocketAddr},\n    sync::Arc,\n    time::Duration,\n};\n\nuse byte_string::ByteStr;\nuse bytes::{BufMut, BytesMut};\nuse log::{debug, error, info, trace};\nuse shadowsocks::{\n    ServerAddr,\n    relay::{\n        socks5::{Address, UdpAssociateHeader},\n        udprelay::MAXIMUM_UDP_PAYLOAD_SIZE,\n    },\n};\nuse tokio::{net::UdpSocket, time};\n\nuse crate::{\n    local::{\n        context::ServiceContext,\n        loadbalancing::PingBalancer,\n        net::{UdpAssociationManager, UdpInboundWrite, udp::listener::create_standard_udp_listener},\n    },\n    net::utils::to_ipv4_mapped,\n};\n\npub struct Socks5UdpServerBuilder {\n    context: Arc<ServiceContext>,\n    client_config: ServerAddr,\n    time_to_live: Option<Duration>,\n    capacity: Option<usize>,\n    balancer: PingBalancer,\n    #[cfg(target_os = \"macos\")]\n    launchd_socket_name: Option<String>,\n}\n\nimpl Socks5UdpServerBuilder {\n    pub(crate) fn new(\n        context: Arc<ServiceContext>,\n        client_config: ServerAddr,\n        time_to_live: Option<Duration>,\n        capacity: Option<usize>,\n        balancer: PingBalancer,\n    ) -> Self {\n        Self {\n            context,\n            client_config,\n            time_to_live,\n            capacity,\n            balancer,\n            #[cfg(target_os = \"macos\")]\n            launchd_socket_name: None,\n        }\n    }\n\n    /// macOS launchd activate socket\n    #[cfg(target_os = \"macos\")]\n    pub fn set_launchd_socket_name(&mut self, n: String) {\n        self.launchd_socket_name = Some(n);\n    }\n\n    pub async fn build(self) -> io::Result<Socks5UdpServer> {\n        cfg_if::cfg_if! {\n            if #[cfg(target_os = \"macos\")] {\n                let socket = match self.launchd_socket_name {\n                    Some(launchd_socket_name) => {\n                        use tokio::net::UdpSocket as TokioUdpSocket;\n                        use crate::net::launch_activate_socket::get_launch_activate_udp_socket;\n\n                        let std_socket = get_launch_activate_udp_socket(&launchd_socket_name, true)?;\n                        TokioUdpSocket::from_std(std_socket)?\n                    } _ => {\n                        create_standard_udp_listener(&self.context, &self.client_config).await?.into()\n                    }\n                };\n            } else {\n                let socket = create_standard_udp_listener(&self.context, &self.client_config).await?.into();\n            }\n        }\n\n        Ok(Socks5UdpServer {\n            context: self.context,\n            time_to_live: self.time_to_live,\n            capacity: self.capacity,\n            listener: Arc::new(socket),\n            balancer: self.balancer,\n        })\n    }\n}\n\n#[derive(Clone)]\nstruct Socks5UdpInboundWriter {\n    inbound: Arc<UdpSocket>,\n}\n\nimpl UdpInboundWrite for Socks5UdpInboundWriter {\n    async fn send_to(&self, peer_addr: SocketAddr, remote_addr: &Address, data: &[u8]) -> io::Result<()> {\n        let remote_addr = match remote_addr {\n            Address::SocketAddress(sa) => {\n                // Try to convert IPv4 mapped IPv6 address if server is running on dual-stack mode\n                let saddr = match *sa {\n                    SocketAddr::V4(..) => *sa,\n                    SocketAddr::V6(ref v6) => match to_ipv4_mapped(v6.ip()) {\n                        Some(v4) => SocketAddr::new(IpAddr::from(v4), v6.port()),\n                        None => *sa,\n                    },\n                };\n\n                Address::SocketAddress(saddr)\n            }\n            daddr => daddr.clone(),\n        };\n\n        // Reassemble packet\n        let mut payload_buffer = BytesMut::new();\n        let header = UdpAssociateHeader::new(0, remote_addr.clone());\n        payload_buffer.reserve(header.serialized_len() + data.len());\n\n        header.write_to_buf(&mut payload_buffer);\n        payload_buffer.put_slice(data);\n\n        self.inbound.send_to(&payload_buffer, peer_addr).await.map(|_| ())\n    }\n}\n\n/// SOCKS5 UDP server instance\npub struct Socks5UdpServer {\n    context: Arc<ServiceContext>,\n    time_to_live: Option<Duration>,\n    capacity: Option<usize>,\n    listener: Arc<UdpSocket>,\n    balancer: PingBalancer,\n}\n\nimpl Socks5UdpServer {\n    /// Server's listen address\n    pub fn local_addr(&self) -> io::Result<SocketAddr> {\n        self.listener.local_addr()\n    }\n\n    /// Run server accept loop\n    pub async fn run(self) -> io::Result<()> {\n        info!(\"shadowsocks socks5 UDP listening on {}\", self.listener.local_addr()?);\n\n        let (mut manager, cleanup_interval, mut keepalive_rx) = UdpAssociationManager::new(\n            self.context.clone(),\n            Socks5UdpInboundWriter {\n                inbound: self.listener.clone(),\n            },\n            self.time_to_live,\n            self.capacity,\n            self.balancer,\n        );\n\n        let mut buffer = [0u8; MAXIMUM_UDP_PAYLOAD_SIZE];\n        let mut cleanup_timer = time::interval(cleanup_interval);\n\n        loop {\n            tokio::select! {\n                _ = cleanup_timer.tick() => {\n                    // cleanup expired associations. iter() will remove expired elements\n                    manager.cleanup_expired().await;\n                }\n\n                peer_addr_opt = keepalive_rx.recv() => {\n                    let peer_addr = peer_addr_opt.expect(\"keep-alive channel closed unexpectedly\");\n                    manager.keep_alive(&peer_addr).await;\n                }\n\n                recv_result = self.listener.recv_from(&mut buffer) => {\n                    let (n, peer_addr) = match recv_result {\n                        Ok(s) => s,\n                        Err(err) => {\n                            error!(\"udp server recv_from failed with error: {}\", err);\n                            time::sleep(Duration::from_secs(1)).await;\n                            continue;\n                        }\n                    };\n\n                    let data = &buffer[..n];\n\n                    // PKT = UdpAssociateHeader + PAYLOAD\n                    let mut cur = Cursor::new(data);\n                    let header = match UdpAssociateHeader::read_from(&mut cur).await {\n                        Ok(h) => h,\n                        Err(..) => {\n                            error!(\"received invalid UDP associate packet: {:?}\", ByteStr::new(data));\n                            continue;\n                        }\n                    };\n\n                    if header.frag != 0 {\n                        error!(\"received UDP associate with frag != 0, which is not supported by shadowsocks\");\n                        continue;\n                    }\n\n                    let pos = cur.position() as usize;\n                    let payload = &data[pos..];\n\n                    trace!(\n                        \"UDP ASSOCIATE {} -> {}, {} bytes\",\n                        peer_addr,\n                        header.address,\n                        payload.len()\n                    );\n\n                    if let Err(err) = manager.send_to(peer_addr, header.address, payload).await {\n                        debug!(\n                            \"udp packet from {} relay {} bytes failed, error: {}\",\n                            peer_addr,\n                            data.len(),\n                            err\n                        );\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/socks/socks4.rs",
    "content": "//! Socks4a Protocol Definition\n//!\n//! <http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol>\n\n#![allow(dead_code)]\n\nuse std::{\n    fmt,\n    io::{self, ErrorKind},\n    net::{Ipv4Addr, SocketAddr, SocketAddrV4},\n};\n\nuse byteorder::{BigEndian, ByteOrder};\nuse bytes::{BufMut, BytesMut};\nuse thiserror::Error;\nuse tokio::io::{AsyncBufRead, AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};\n\nuse shadowsocks::relay::socks5;\n\n#[rustfmt::skip]\nmod consts {\n    pub const SOCKS4_VERSION:                                   u8 = 4;\n\n    pub const SOCKS4_COMMAND_CONNECT:                           u8 = 1;\n    pub const SOCKS4_COMMAND_BIND:                              u8 = 2;\n\n    pub const SOCKS4_RESULT_REQUEST_GRANTED:                    u8 = 90;\n    pub const SOCKS4_RESULT_REQUEST_REJECTED_OR_FAILED:         u8 = 91;\n    pub const SOCKS4_RESULT_REQUEST_REJECTED_CANNOT_CONNECT:    u8 = 92;\n    pub const SOCKS4_RESULT_REQUEST_REJECTED_DIFFERENT_USER_ID: u8 = 93;\n}\n\n/// SOCKS4 Command\n#[derive(Clone, Debug, Copy)]\npub enum Command {\n    /// CONNECT command\n    Connect,\n    /// BIND command\n    Bind,\n}\n\nimpl Command {\n    #[inline]\n    fn as_u8(self) -> u8 {\n        match self {\n            Self::Connect => consts::SOCKS4_COMMAND_CONNECT,\n            Self::Bind => consts::SOCKS4_COMMAND_BIND,\n        }\n    }\n\n    #[inline]\n    fn from_u8(code: u8) -> Option<Self> {\n        match code {\n            consts::SOCKS4_COMMAND_CONNECT => Some(Self::Connect),\n            consts::SOCKS4_COMMAND_BIND => Some(Self::Bind),\n            _ => None,\n        }\n    }\n}\n\n/// SOCKS4 Result Code\n#[derive(Clone, Debug, Copy, Eq, PartialEq)]\npub enum ResultCode {\n    /// 90: request granted\n    RequestGranted,\n    /// 91: request rejected or failed\n    RequestRejectedOrFailed,\n    /// 92: request rejected because SOCKS server cannot connect to identd on the client\n    RequestRejectedCannotConnect,\n    /// 93: request rejected because the client program and identd report different user-ids\n    RequestRejectedDifferentUserId,\n    /// Other replies\n    Other(u8),\n}\n\nimpl ResultCode {\n    #[inline]\n    fn as_u8(self) -> u8 {\n        match self {\n            Self::RequestGranted => consts::SOCKS4_RESULT_REQUEST_GRANTED,\n            Self::RequestRejectedOrFailed => consts::SOCKS4_RESULT_REQUEST_REJECTED_OR_FAILED,\n            Self::RequestRejectedCannotConnect => consts::SOCKS4_RESULT_REQUEST_REJECTED_CANNOT_CONNECT,\n            Self::RequestRejectedDifferentUserId => consts::SOCKS4_RESULT_REQUEST_REJECTED_DIFFERENT_USER_ID,\n            Self::Other(c) => c,\n        }\n    }\n\n    #[inline]\n    fn from_u8(code: u8) -> Self {\n        match code {\n            consts::SOCKS4_RESULT_REQUEST_GRANTED => Self::RequestGranted,\n            consts::SOCKS4_RESULT_REQUEST_REJECTED_OR_FAILED => Self::RequestRejectedOrFailed,\n            consts::SOCKS4_RESULT_REQUEST_REJECTED_CANNOT_CONNECT => Self::RequestRejectedCannotConnect,\n            consts::SOCKS4_RESULT_REQUEST_REJECTED_DIFFERENT_USER_ID => Self::RequestRejectedDifferentUserId,\n            code => Self::Other(code),\n        }\n    }\n}\n\nimpl fmt::Display for ResultCode {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match *self {\n            Self::RequestGranted => f.write_str(\"request granted\"),\n            Self::RequestRejectedOrFailed => f.write_str(\"request rejected or failed\"),\n            Self::RequestRejectedCannotConnect => {\n                f.write_str(\"request rejected because SOCKS server cannot connect to identd on the client\")\n            }\n            Self::RequestRejectedDifferentUserId => {\n                f.write_str(\"request rejected because the client program and identd report different user-ids\")\n            }\n            Self::Other(code) => write!(f, \"other result code {code}\"),\n        }\n    }\n}\n\n/// SOCKS4 Address type\n#[derive(Clone, PartialEq, Eq, Hash)]\npub enum Address {\n    /// Socket address (IP Address)\n    SocketAddress(SocketAddrV4),\n    /// Domain name address (SOCKS4a)\n    DomainNameAddress(String, u16),\n}\n\nimpl fmt::Debug for Address {\n    #[inline]\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        match *self {\n            Self::SocketAddress(ref addr) => write!(f, \"{addr}\"),\n            Self::DomainNameAddress(ref addr, ref port) => write!(f, \"{addr}:{port}\"),\n        }\n    }\n}\n\nimpl fmt::Display for Address {\n    #[inline]\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        match *self {\n            Self::SocketAddress(ref addr) => write!(f, \"{addr}\"),\n            Self::DomainNameAddress(ref addr, ref port) => write!(f, \"{addr}:{port}\"),\n        }\n    }\n}\n\nimpl From<SocketAddrV4> for Address {\n    fn from(s: SocketAddrV4) -> Self {\n        Self::SocketAddress(s)\n    }\n}\n\nimpl From<(String, u16)> for Address {\n    fn from((dn, port): (String, u16)) -> Self {\n        Self::DomainNameAddress(dn, port)\n    }\n}\n\nimpl From<(&str, u16)> for Address {\n    fn from((dn, port): (&str, u16)) -> Self {\n        Self::DomainNameAddress(dn.to_owned(), port)\n    }\n}\n\nimpl From<&Self> for Address {\n    fn from(addr: &Self) -> Self {\n        addr.clone()\n    }\n}\n\nimpl From<Address> for socks5::Address {\n    fn from(addr: Address) -> Self {\n        match addr {\n            Address::SocketAddress(a) => Self::SocketAddress(SocketAddr::V4(a)),\n            Address::DomainNameAddress(d, p) => Self::DomainNameAddress(d, p),\n        }\n    }\n}\n\n/// Handshake Request\n///\n/// ```plain\n/// The client connects to the SOCKS server and sends a CONNECT/BIND request when\n/// it wants to establish a connection to an application server. The client\n/// includes in the request packet the IP address and the port number of the\n/// destination host, and userid, in the following format.\n///\n///                 +----+----+----+----+----+----+----+----+----+----+....+----+\n///                 | VN | CD | DSTPORT |      DSTIP        | USERID       |NULL|\n///                 +----+----+----+----+----+----+----+----+----+----+....+----+\n///  # of bytes:      1    1      2              4           variable       1\n///\n/// VN is the SOCKS protocol version number and should be 4. CD is the\n/// SOCKS command code and should be 1 for CONNECT request, 2 for BIND request. NULL is a byte\n/// of all zero bits.\n/// ```\n#[derive(Debug, Clone)]\npub struct HandshakeRequest {\n    pub cd: Command,\n    pub dst: Address,\n    pub user_id: Vec<u8>,\n}\n\nimpl HandshakeRequest {\n    /// Read from a reader\n    pub async fn read_from<R>(r: &mut R) -> Result<Self, Error>\n    where\n        R: AsyncBufRead + Unpin,\n    {\n        let mut buf = [0u8; 8];\n        let _ = r.read_exact(&mut buf).await?;\n\n        let vn = buf[0];\n        if vn != consts::SOCKS4_VERSION {\n            return Err(Error::UnsupportedSocksVersion(vn));\n        }\n\n        let cd = buf[1];\n        let command = match Command::from_u8(cd) {\n            Some(c) => c,\n            None => {\n                return Err(Error::UnsupportedSocksVersion(cd));\n            }\n        };\n\n        let port = BigEndian::read_u16(&buf[2..4]);\n\n        let mut user_id = Vec::new();\n        let _ = r.read_until(b'\\0', &mut user_id).await?;\n        if user_id.is_empty() || user_id.last() != Some(&b'\\0') {\n            return Err(io::Error::from(ErrorKind::UnexpectedEof).into());\n        }\n        user_id.pop(); // Pops the last b'\\0'\n\n        let dst = if buf[4] == 0x00 && buf[5] == 0x00 && buf[6] == 0x00 && buf[7] != 0x00 {\n            // SOCKS4a, indicates that it is a HOST address\n            let mut host = Vec::new();\n            let _ = r.read_until(b'\\0', &mut host).await?;\n            if host.is_empty() || host.last() != Some(&b'\\0') {\n                return Err(io::Error::from(ErrorKind::UnexpectedEof).into());\n            }\n            host.pop(); // Pops the last b'\\0'\n\n            match String::from_utf8(host) {\n                Ok(host) => Address::DomainNameAddress(host, port),\n                Err(..) => {\n                    return Err(Error::AddressHostInvalidEncoding);\n                }\n            }\n        } else {\n            let ip = Ipv4Addr::new(buf[4], buf[5], buf[6], buf[7]);\n            Address::SocketAddress(SocketAddrV4::new(ip, port))\n        };\n\n        Ok(Self {\n            cd: command,\n            dst,\n            user_id,\n        })\n    }\n\n    /// Writes to writer\n    pub async fn write_to<W>(&self, w: &mut W) -> io::Result<()>\n    where\n        W: AsyncWrite + Unpin,\n    {\n        let mut buf = BytesMut::with_capacity(self.serialized_len());\n        self.write_to_buf(&mut buf);\n        w.write_all(&buf).await\n    }\n\n    /// Writes to buffer\n    pub fn write_to_buf<B: BufMut>(&self, buf: &mut B) {\n        debug_assert!(\n            !self.user_id.contains(&b'\\0'),\n            \"USERID shouldn't contain any NULL characters\"\n        );\n\n        buf.put_u8(consts::SOCKS4_VERSION);\n        buf.put_u8(self.cd.as_u8());\n        match self.dst {\n            Address::SocketAddress(ref saddr) => {\n                let port = saddr.port();\n                buf.put_u16(port);\n                buf.put_slice(&saddr.ip().octets());\n\n                buf.put_slice(&self.user_id);\n                buf.put_u8(b'\\0');\n            }\n            Address::DomainNameAddress(ref dname, port) => {\n                buf.put_u16(port);\n\n                // 0.0.0.x (x != 0)\n                const PLACEHOLDER: [u8; 4] = [0x00, 0x00, 0x00, 0xff];\n                buf.put_slice(&PLACEHOLDER);\n\n                buf.put_slice(&self.user_id);\n                buf.put_u8(b'\\0');\n\n                buf.put_slice(dname.as_bytes());\n                buf.put_u8(b'\\0');\n            }\n        }\n    }\n\n    /// Length in bytes\n    #[inline]\n    pub fn serialized_len(&self) -> usize {\n        let mut s = 1 + 1 + 2 + 4 + self.user_id.len() + 1; // USERID.LEN + NULL\n        if let Address::DomainNameAddress(ref dname, _) = self.dst {\n            s += dname.len() + 1;\n        }\n        s\n    }\n}\n\n/// Handshake Response\n///\n/// ```plain\n///             +----+----+----+----+----+----+----+----+\n///             | VN | CD | DSTPORT |      DSTIP        |\n///             +----+----+----+----+----+----+----+----+\n/// # of bytes:   1    1      2              4\n/// ```\n#[derive(Debug, Clone)]\npub struct HandshakeResponse {\n    pub cd: ResultCode,\n}\n\nimpl HandshakeResponse {\n    /// Create a response with code\n    pub fn new(code: ResultCode) -> Self {\n        Self { cd: code }\n    }\n\n    /// Read from a reader\n    pub async fn read_from<R>(r: &mut R) -> Result<Self, Error>\n    where\n        R: AsyncRead + Unpin,\n    {\n        let mut buf = [0u8; 8];\n        let _ = r.read_exact(&mut buf).await?;\n\n        let vn = buf[0];\n        if vn != 0 {\n            return Err(Error::UnsupportedSocksVersion(vn));\n        }\n\n        let cd = buf[1];\n        let result_code = ResultCode::from_u8(cd);\n\n        // DSTPORT, DSTIP are ignored\n\n        Ok(Self { cd: result_code })\n    }\n\n    /// Write data into a writer\n    pub async fn write_to<W>(&self, w: &mut W) -> io::Result<()>\n    where\n        W: AsyncWrite + Unpin,\n    {\n        let mut buf = BytesMut::with_capacity(self.serialized_len());\n        self.write_to_buf(&mut buf);\n        w.write_all(&buf).await\n    }\n\n    /// Writes to buffer\n    pub fn write_to_buf<B: BufMut>(&self, buf: &mut B) {\n        let Self { ref cd } = *self;\n\n        buf.put_slice(&[\n            // VN: Result Code's version, must be 0\n            0x00,\n            // CD: Result Code\n            cd.as_u8(),\n            // DSTPORT: Ignored\n            0x00,\n            0x00,\n            // DSTIP: Ignored\n            0x00,\n            0x00,\n            0x00,\n            0x00,\n        ]);\n    }\n\n    /// Length in bytes\n    #[inline]\n    pub fn serialized_len(&self) -> usize {\n        1 + 1 + 2 + 4\n    }\n}\n\n/// SOCKS 4/4a Error\n#[derive(Error, Debug)]\npub enum Error {\n    // I/O Error\n    #[error(\"{0}\")]\n    IoError(#[from] io::Error),\n    #[error(\"host must be UTF-8 encoding\")]\n    AddressHostInvalidEncoding,\n    #[error(\"unsupported socks version {0:#x}\")]\n    UnsupportedSocksVersion(u8),\n    #[error(\"unsupported command {0:#x}\")]\n    UnsupportedCommand(u8),\n    #[error(\"{0}\")]\n    Result(ResultCode),\n}\n\nimpl From<Error> for io::Error {\n    fn from(err: Error) -> Self {\n        match err {\n            Error::IoError(err) => err,\n            e => Self::other(e),\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/tun/fake_tun.rs",
    "content": "//! Fake `tun` for those platforms that doesn't support `tun`\n\n#![allow(dead_code)]\n\nuse std::{\n    io::{self, Read, Write},\n    net::IpAddr,\n    ops::{Deref, DerefMut},\n    pin::Pin,\n    task::{Context, Poll},\n};\n\nuse tokio::io::{AsyncRead, AsyncWrite, ReadBuf};\n\n/// TUN interface OSI layer of operation.\n#[derive(Clone, Copy, Default, Debug, Eq, PartialEq)]\npub enum Layer {\n    L2,\n    #[default]\n    L3,\n}\n\n/// Configuration builder for a TUN interface.\n#[derive(Clone, Default, Debug)]\npub struct Configuration;\n\nimpl Configuration {\n    /// Set the tun name.\n    ///\n    /// [Note: on macOS, the tun name must be the form `utunx` where `x` is a number, such as `utun3`. -- end note]\n    pub fn tun_name<S: AsRef<str>>(&mut self, _tun_name: S) -> &mut Self {\n        self\n    }\n\n    /// Set the address.\n    pub fn address(&mut self, _value: IpAddr) -> &mut Self {\n        self\n    }\n\n    /// Set the destination address.\n    pub fn destination(&mut self, _value: IpAddr) -> &mut Self {\n        self\n    }\n\n    /// Set the broadcast address.\n    pub fn broadcast(&mut self, _value: IpAddr) -> &mut Self {\n        self\n    }\n\n    /// Set the netmask.\n    pub fn netmask(&mut self, _value: IpAddr) -> &mut Self {\n        self\n    }\n\n    /// Set the MTU.\n    pub fn mtu(&mut self, _value: u16) -> &mut Self {\n        self\n    }\n\n    /// Set the interface to be enabled once created.\n    pub fn up(&mut self) -> &mut Self {\n        self\n    }\n\n    /// Set the interface to be disabled once created.\n    pub fn down(&mut self) -> &mut Self {\n        self\n    }\n\n    /// Set the OSI layer of operation.\n    pub fn layer(&mut self, _value: Layer) -> &mut Self {\n        self\n    }\n\n    /// Set the raw fd.\n    #[cfg(unix)]\n    pub fn raw_fd(&mut self, _fd: ::std::os::fd::RawFd) -> &mut Self {\n        self\n    }\n}\n\n/// tun Error type\n#[derive(thiserror::Error, Debug)]\npub enum Error {\n    #[error(\"not implemented\")]\n    NotImplemented,\n\n    #[error(transparent)]\n    Io(#[from] std::io::Error),\n}\n\npub type Result<T, E = Error> = ::std::result::Result<T, E>;\n\n/// A TUN abstract device interface.\npub trait AbstractDevice: Read + Write {\n    /// Reconfigure the device.\n    fn configure(&mut self, _config: &Configuration) -> Result<()> {\n        Ok(())\n    }\n\n    /// Get the device index.\n    fn tun_index(&self) -> Result<i32>;\n\n    /// Get the device tun name.\n    fn tun_name(&self) -> Result<String>;\n\n    /// Set the device tun name.\n    fn set_tun_name(&mut self, tun_name: &str) -> Result<()>;\n\n    /// Turn on or off the interface.\n    fn enabled(&mut self, value: bool) -> Result<()>;\n\n    /// Get the address.\n    fn address(&self) -> Result<IpAddr>;\n\n    /// Set the address.\n    fn set_address(&mut self, value: IpAddr) -> Result<()>;\n\n    /// Get the destination address.\n    fn destination(&self) -> Result<IpAddr>;\n\n    /// Set the destination address.\n    fn set_destination(&mut self, value: IpAddr) -> Result<()>;\n\n    /// Get the broadcast address.\n    fn broadcast(&self) -> Result<IpAddr>;\n\n    /// Set the broadcast address.\n    fn set_broadcast(&mut self, value: IpAddr) -> Result<()>;\n\n    /// Get the netmask.\n    fn netmask(&self) -> Result<IpAddr>;\n\n    /// Set the netmask.\n    fn set_netmask(&mut self, value: IpAddr) -> Result<()>;\n\n    /// Get the MTU.\n    fn mtu(&self) -> Result<u16>;\n\n    /// Set the MTU.\n    ///\n    /// [Note: This setting has no effect on the Windows platform due to the mtu of wintun is always 65535. --end note]\n    fn set_mtu(&mut self, value: u16) -> Result<()>;\n\n    /// Return whether the underlying tun device on the platform has packet information\n    ///\n    /// [Note: This value is not used to specify whether the packets delivered from/to tun have packet information. -- end note]\n    fn packet_information(&self) -> bool;\n}\n\npub struct FakeQueue;\n\nimpl Read for FakeQueue {\n    fn read(&mut self, _: &mut [u8]) -> io::Result<usize> {\n        Err(io::Error::other(\"not implemented\"))\n    }\n}\n\nimpl Write for FakeQueue {\n    fn write(&mut self, _: &[u8]) -> io::Result<usize> {\n        Err(io::Error::other(\"not implemented\"))\n    }\n\n    fn flush(&mut self) -> io::Result<()> {\n        Err(io::Error::other(\"not implemented\"))\n    }\n}\n\npub struct FakeDevice;\n\nimpl AbstractDevice for FakeDevice {\n    fn tun_name(&self) -> Result<String> {\n        Err(Error::NotImplemented)\n    }\n\n    fn tun_index(&self) -> Result<i32> {\n        Err(Error::NotImplemented)\n    }\n\n    fn set_tun_name(&mut self, _: &str) -> Result<()> {\n        Err(Error::NotImplemented)\n    }\n\n    fn enabled(&mut self, _: bool) -> Result<()> {\n        Err(Error::NotImplemented)\n    }\n\n    fn address(&self) -> Result<IpAddr> {\n        Err(Error::NotImplemented)\n    }\n\n    fn set_address(&mut self, _: IpAddr) -> Result<()> {\n        Err(Error::NotImplemented)\n    }\n\n    fn destination(&self) -> Result<IpAddr> {\n        Err(Error::NotImplemented)\n    }\n\n    fn set_destination(&mut self, _: IpAddr) -> Result<()> {\n        Err(Error::NotImplemented)\n    }\n\n    fn broadcast(&self) -> Result<IpAddr> {\n        Err(Error::NotImplemented)\n    }\n\n    fn set_broadcast(&mut self, _: IpAddr) -> Result<()> {\n        Err(Error::NotImplemented)\n    }\n\n    fn netmask(&self) -> Result<IpAddr> {\n        Err(Error::NotImplemented)\n    }\n\n    fn set_netmask(&mut self, _: IpAddr) -> Result<()> {\n        Err(Error::NotImplemented)\n    }\n\n    fn mtu(&self) -> Result<u16> {\n        Err(Error::NotImplemented)\n    }\n\n    fn set_mtu(&mut self, _: u16) -> Result<()> {\n        Err(Error::NotImplemented)\n    }\n\n    fn packet_information(&self) -> bool {\n        false\n    }\n}\n\nimpl Read for FakeDevice {\n    fn read(&mut self, _: &mut [u8]) -> io::Result<usize> {\n        Err(io::Error::other(\"not implemented\"))\n    }\n}\n\nimpl Write for FakeDevice {\n    fn write(&mut self, _: &[u8]) -> io::Result<usize> {\n        Err(io::Error::other(\"not implemented\"))\n    }\n\n    fn flush(&mut self) -> io::Result<()> {\n        Err(io::Error::other(\"not implemented\"))\n    }\n}\n\npub struct AsyncDevice(FakeDevice);\n\nimpl AsRef<FakeDevice> for AsyncDevice {\n    fn as_ref(&self) -> &FakeDevice {\n        &self.0\n    }\n}\n\nimpl AsMut<FakeDevice> for AsyncDevice {\n    fn as_mut(&mut self) -> &mut FakeDevice {\n        &mut self.0\n    }\n}\n\nimpl Deref for AsyncDevice {\n    type Target = FakeDevice;\n\n    fn deref(&self) -> &Self::Target {\n        &self.0\n    }\n}\n\nimpl DerefMut for AsyncDevice {\n    fn deref_mut(&mut self) -> &mut Self::Target {\n        &mut self.0\n    }\n}\n\nimpl AsyncRead for AsyncDevice {\n    fn poll_read(self: Pin<&mut Self>, _cx: &mut Context<'_>, _buf: &mut ReadBuf<'_>) -> Poll<io::Result<()>> {\n        Err(io::Error::other(\"not implemented\")).into()\n    }\n}\n\nimpl AsyncWrite for AsyncDevice {\n    fn poll_write(self: Pin<&mut Self>, _cx: &mut Context<'_>, _buf: &[u8]) -> Poll<io::Result<usize>> {\n        Err(io::Error::other(\"not implemented\")).into()\n    }\n\n    fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {\n        Err(io::Error::other(\"not implemented\")).into()\n    }\n\n    fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {\n        Err(io::Error::other(\"not implemented\")).into()\n    }\n}\n\n/// Create a TUN device with the given name.\npub fn create_as_async(_: &Configuration) -> Result<AsyncDevice, Error> {\n    Err(Error::NotImplemented)\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/tun/ip_packet.rs",
    "content": "//! IP packet encapsulation\n\nuse std::net::IpAddr;\n\nuse smoltcp::wire::{IpProtocol, IpVersion, Ipv4Packet, Ipv6Packet};\n\n#[derive(Debug)]\npub enum IpPacket<T: AsRef<[u8]>> {\n    Ipv4(Ipv4Packet<T>),\n    Ipv6(Ipv6Packet<T>),\n}\n\nimpl<T: AsRef<[u8]> + Copy> IpPacket<T> {\n    pub fn new_checked(packet: T) -> smoltcp::wire::Result<Option<Self>> {\n        let buffer = packet.as_ref();\n        match IpVersion::of_packet(buffer)? {\n            IpVersion::Ipv4 => Ok(Some(Self::Ipv4(Ipv4Packet::new_checked(packet)?))),\n            IpVersion::Ipv6 => Ok(Some(Self::Ipv6(Ipv6Packet::new_checked(packet)?))),\n        }\n    }\n\n    pub fn src_addr(&self) -> IpAddr {\n        match *self {\n            Self::Ipv4(ref packet) => IpAddr::from(packet.src_addr()),\n            Self::Ipv6(ref packet) => IpAddr::from(packet.src_addr()),\n        }\n    }\n\n    pub fn dst_addr(&self) -> IpAddr {\n        match *self {\n            Self::Ipv4(ref packet) => IpAddr::from(packet.dst_addr()),\n            Self::Ipv6(ref packet) => IpAddr::from(packet.dst_addr()),\n        }\n    }\n\n    pub fn protocol(&self) -> IpProtocol {\n        match *self {\n            Self::Ipv4(ref packet) => packet.next_header(),\n            Self::Ipv6(ref packet) => packet.next_header(),\n        }\n    }\n}\n\nimpl<'a, T: AsRef<[u8]> + ?Sized> IpPacket<&'a T> {\n    /// Return a pointer to the payload.\n    #[inline]\n    pub fn payload(&self) -> &'a [u8] {\n        match *self {\n            IpPacket::Ipv4(ref packet) => packet.payload(),\n            IpPacket::Ipv6(ref packet) => packet.payload(),\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/tun/mod.rs",
    "content": "//! Shadowsocks Local server serving on a Tun interface\n\n#[cfg(unix)]\nuse std::os::unix::io::RawFd;\nuse std::{\n    io, mem,\n    net::{IpAddr, SocketAddr},\n    sync::Arc,\n    time::Duration,\n};\n\nuse byte_string::ByteStr;\nuse cfg_if::cfg_if;\nuse ipnet::IpNet;\nuse log::{debug, error, info, trace, warn};\nuse shadowsocks::config::Mode;\nuse smoltcp::wire::{IpProtocol, TcpPacket, UdpPacket};\nuse tokio::{\n    io::{AsyncReadExt, AsyncWriteExt},\n    sync::mpsc,\n    time,\n};\n\ncfg_if! {\n    if #[cfg(any(target_os = \"ios\",\n                 target_os = \"macos\",\n                 target_os = \"linux\",\n                 target_os = \"android\",\n                 target_os = \"windows\",\n                 target_os = \"freebsd\"))] {\n        use tun::{\n            create_as_async, AsyncDevice, Configuration as TunConfiguration, AbstractDevice, Error as TunError, Layer,\n        };\n    } else {\n        mod fake_tun;\n        use self::fake_tun::{\n            AbstractDevice, AsyncDevice, Configuration as TunConfiguration, Error as TunError, Layer, create_as_async,\n        };\n    }\n}\n\nuse crate::local::{context::ServiceContext, loadbalancing::PingBalancer};\n\nuse self::{ip_packet::IpPacket, tcp::TcpTun, udp::UdpTun, virt_device::TokenBuffer};\n\nmod ip_packet;\nmod tcp;\nmod udp;\nmod virt_device;\n\n/// Tun service builder\npub struct TunBuilder {\n    context: Arc<ServiceContext>,\n    balancer: PingBalancer,\n    tun_config: TunConfiguration,\n    udp_expiry_duration: Option<Duration>,\n    udp_capacity: Option<usize>,\n    mode: Mode,\n}\n\n/// TunConfiguration contains a HANDLE, which is a *mut c_void on Windows.\nunsafe impl Send for TunBuilder {}\n\nimpl TunBuilder {\n    /// Create a Tun service builder\n    pub fn new(context: Arc<ServiceContext>, balancer: PingBalancer) -> Self {\n        Self {\n            context,\n            balancer,\n            tun_config: TunConfiguration::default(),\n            udp_expiry_duration: None,\n            udp_capacity: None,\n            mode: Mode::TcpOnly,\n        }\n    }\n\n    pub fn address(&mut self, addr: IpNet) {\n        self.tun_config.address(addr.addr()).netmask(addr.netmask());\n    }\n\n    pub fn destination(&mut self, addr: IpNet) {\n        self.tun_config.destination(addr.addr());\n    }\n\n    pub fn name(&mut self, name: &str) {\n        self.tun_config.tun_name(name);\n    }\n\n    #[cfg(unix)]\n    pub fn file_descriptor(&mut self, fd: RawFd) {\n        self.tun_config.raw_fd(fd);\n    }\n\n    pub fn udp_expiry_duration(&mut self, udp_expiry_duration: Duration) {\n        self.udp_expiry_duration = Some(udp_expiry_duration);\n    }\n\n    pub fn udp_capacity(&mut self, udp_capacity: usize) {\n        self.udp_capacity = Some(udp_capacity);\n    }\n\n    pub fn mode(&mut self, mode: Mode) {\n        self.mode = mode;\n    }\n\n    /// Build Tun server\n    pub async fn build(mut self) -> io::Result<Tun> {\n        self.tun_config.layer(Layer::L3).up();\n\n        // XXX: tun2 set IFF_NO_PI by default.\n        //\n        // #[cfg(target_os = \"linux\")]\n        // self.tun_config.platform_config(|tun_config| {\n        //     // IFF_NO_PI preventing excessive buffer reallocating\n        //     tun_config.packet_information(false);\n        // });\n\n        let device = match create_as_async(&self.tun_config) {\n            Ok(d) => d,\n            Err(TunError::Io(err)) => return Err(err),\n            Err(err) => return Err(io::Error::other(err)),\n        };\n\n        let (udp, udp_cleanup_interval, udp_keepalive_rx) = UdpTun::new(\n            self.context.clone(),\n            self.balancer.clone(),\n            self.udp_expiry_duration,\n            self.udp_capacity,\n        );\n\n        let tcp = TcpTun::new(self.context, self.balancer, device.mtu().unwrap_or(1500) as u32);\n\n        Ok(Tun {\n            device,\n            tcp,\n            udp,\n            udp_cleanup_interval,\n            udp_keepalive_rx,\n            mode: self.mode,\n        })\n    }\n}\n\n/// Tun service\npub struct Tun {\n    device: AsyncDevice,\n    tcp: TcpTun,\n    udp: UdpTun,\n    udp_cleanup_interval: Duration,\n    udp_keepalive_rx: mpsc::Receiver<SocketAddr>,\n    mode: Mode,\n}\n\nimpl Tun {\n    /// Start serving\n    pub async fn run(mut self) -> io::Result<()> {\n        info!(\n            \"shadowsocks tun device {}, mode {}\",\n            self.device.tun_name().or_else(|r| Ok::<_, ()>(r.to_string())).unwrap(),\n            self.mode,\n        );\n\n        let address = match self.device.address() {\n            Ok(a) => a,\n            Err(err) => {\n                error!(\"[TUN] failed to get device address, error: {}\", err);\n                return Err(io::Error::other(err));\n            }\n        };\n\n        let netmask = match self.device.netmask() {\n            Ok(n) => n,\n            Err(err) => {\n                error!(\"[TUN] failed to get device netmask, error: {}\", err);\n                return Err(io::Error::other(err));\n            }\n        };\n\n        let address_net = match IpNet::with_netmask(address, netmask) {\n            Ok(n) => n,\n            Err(err) => {\n                error!(\"[TUN] invalid address {}, netmask {}, error: {}\", address, netmask, err);\n                return Err(io::Error::other(err));\n            }\n        };\n\n        trace!(\n            \"[TUN] tun device network: {} (address: {}, netmask: {})\",\n            address_net, address, netmask\n        );\n\n        let address_broadcast = address_net.broadcast();\n\n        let create_packet_buffer = || {\n            const PACKET_BUFFER_SIZE: usize = 65536;\n            let mut packet_buffer = TokenBuffer::with_capacity(PACKET_BUFFER_SIZE);\n            unsafe {\n                packet_buffer.set_len(PACKET_BUFFER_SIZE);\n            }\n            packet_buffer\n        };\n\n        let mut packet_buffer = create_packet_buffer();\n        let mut udp_cleanup_timer = time::interval(self.udp_cleanup_interval);\n\n        loop {\n            tokio::select! {\n                // tun device\n                n = self.device.read(&mut packet_buffer) => {\n                    let n = n?;\n\n                    let mut packet_buffer = mem::replace(&mut packet_buffer, create_packet_buffer());\n                    unsafe {\n                        packet_buffer.set_len(n);\n                    }\n\n                    trace!(\"[TUN] received IP packet {:?}\", ByteStr::new(&packet_buffer));\n\n                    if let Err(err) = self.handle_tun_frame(&address_broadcast, packet_buffer).await {\n                        error!(\"[TUN] handle IP frame failed, error: {}\", err);\n                    }\n                }\n\n                // UDP channel sent back\n                packet = self.udp.recv_packet() => {\n                    match self.device.write(&packet).await {\n                        Ok(n) => {\n                            if n < packet.len() {\n                                warn!(\"[TUN] sent IP packet (UDP), but truncated. sent {} < {}, {:?}\", n, packet.len(), ByteStr::new(&packet));\n                            } else {\n                                trace!(\"[TUN] sent IP packet (UDP) {:?}\", ByteStr::new(&packet));\n                            }\n                        }\n                        Err(err) => {\n                            error!(\"[TUN] failed to set packet information, error: {}, {:?}\", err, ByteStr::new(&packet));\n                        }\n                    }\n                }\n\n                // UDP cleanup expired associations\n                _ = udp_cleanup_timer.tick() => {\n                    self.udp.cleanup_expired().await;\n                }\n\n                // UDP keep-alive associations\n                peer_addr_opt = self.udp_keepalive_rx.recv() => {\n                    let peer_addr = peer_addr_opt.expect(\"UDP keep-alive channel closed unexpectedly\");\n                    self.udp.keep_alive(&peer_addr).await;\n                }\n\n                // TCP channel sent back\n                packet = self.tcp.recv_packet() => {\n                    match self.device.write(&packet).await {\n                        Ok(n) => {\n                            if n < packet.len() {\n                                warn!(\"[TUN] sent IP packet (TCP), but truncated. sent {} < {}, {:?}\", n, packet.len(), ByteStr::new(&packet));\n                            } else {\n                                trace!(\"[TUN] sent IP packet (TCP) {:?}\", ByteStr::new(&packet));\n                            }\n                        }\n                        Err(err) => {\n                            error!(\"[TUN] failed to set packet information, error: {}, {:?}\", err, ByteStr::new(&packet));\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    async fn handle_tun_frame(\n        &mut self,\n        device_broadcast_addr: &IpAddr,\n        frame: TokenBuffer,\n    ) -> smoltcp::wire::Result<()> {\n        let packet = match IpPacket::new_checked(frame.as_ref())? {\n            Some(packet) => packet,\n            None => {\n                warn!(\"unrecognized IP packet {:?}\", ByteStr::new(&frame));\n                return Ok(());\n            }\n        };\n\n        trace!(\"[TUN] {:?}\", packet);\n\n        let src_ip_addr = packet.src_addr();\n        let dst_ip_addr = packet.dst_addr();\n        let src_non_unicast = src_ip_addr == *device_broadcast_addr\n            || match src_ip_addr {\n                IpAddr::V4(v4) => v4.is_broadcast() || v4.is_multicast() || v4.is_unspecified(),\n                IpAddr::V6(v6) => v6.is_multicast() || v6.is_unspecified(),\n            };\n        let dst_non_unicast = dst_ip_addr == *device_broadcast_addr\n            || match dst_ip_addr {\n                IpAddr::V4(v4) => v4.is_broadcast() || v4.is_multicast() || v4.is_unspecified(),\n                IpAddr::V6(v6) => v6.is_multicast() || v6.is_unspecified(),\n            };\n\n        if src_non_unicast || dst_non_unicast {\n            trace!(\n                \"[TUN] IP packet {} (unicast? {}) -> {} (unicast? {}) throwing away\",\n                src_ip_addr, !src_non_unicast, dst_ip_addr, !dst_non_unicast\n            );\n            return Ok(());\n        }\n\n        match packet.protocol() {\n            IpProtocol::Tcp => {\n                if !self.mode.enable_tcp() {\n                    trace!(\"received TCP packet but mode is {}, throwing away\", self.mode);\n                    return Ok(());\n                }\n\n                let tcp_packet = match TcpPacket::new_checked(packet.payload()) {\n                    Ok(p) => p,\n                    Err(err) => {\n                        error!(\n                            \"invalid TCP packet err: {}, src_ip: {}, dst_ip: {}, payload: {:?}\",\n                            err,\n                            packet.src_addr(),\n                            packet.dst_addr(),\n                            ByteStr::new(packet.payload())\n                        );\n                        return Ok(());\n                    }\n                };\n\n                let src_port = tcp_packet.src_port();\n                let dst_port = tcp_packet.dst_port();\n\n                let src_addr = SocketAddr::new(packet.src_addr(), src_port);\n                let dst_addr = SocketAddr::new(packet.dst_addr(), dst_port);\n\n                trace!(\n                    \"[TUN] TCP packet {} (unicast? {}) -> {} (unicast? {}) {}\",\n                    src_addr, !src_non_unicast, dst_addr, !dst_non_unicast, tcp_packet\n                );\n\n                // TCP first handshake packet.\n                if let Err(err) = self.tcp.handle_packet(src_addr, dst_addr, &tcp_packet).await {\n                    error!(\n                        \"handle TCP packet failed, error: {}, {} <-> {}, packet: {:?}\",\n                        err, src_addr, dst_addr, tcp_packet\n                    );\n                }\n\n                self.tcp.drive_interface_state(frame).await;\n            }\n            IpProtocol::Udp => {\n                if !self.mode.enable_udp() {\n                    trace!(\"received UDP packet but mode is {}, throwing away\", self.mode);\n                    return Ok(());\n                }\n\n                let udp_packet = match UdpPacket::new_checked(packet.payload()) {\n                    Ok(p) => p,\n                    Err(err) => {\n                        error!(\n                            \"invalid UDP packet err: {}, src_ip: {}, dst_ip: {}, payload: {:?}\",\n                            err,\n                            packet.src_addr(),\n                            packet.dst_addr(),\n                            ByteStr::new(packet.payload())\n                        );\n                        return Ok(());\n                    }\n                };\n\n                let src_port = udp_packet.src_port();\n                let dst_port = udp_packet.dst_port();\n\n                let src_addr = SocketAddr::new(src_ip_addr, src_port);\n                let dst_addr = SocketAddr::new(packet.dst_addr(), dst_port);\n\n                let payload = udp_packet.payload();\n                trace!(\n                    \"[TUN] UDP packet {} (unicast? {}) -> {} (unicast? {}) {}\",\n                    src_addr, !src_non_unicast, dst_addr, !dst_non_unicast, udp_packet\n                );\n\n                if let Err(err) = self.udp.handle_packet(src_addr, dst_addr, payload).await {\n                    error!(\"handle UDP packet failed, err: {}, packet: {:?}\", err, udp_packet);\n                }\n            }\n            IpProtocol::Icmp | IpProtocol::Icmpv6 => {\n                // ICMP is handled by TCP's Interface.\n                // smoltcp's interface will always send replies to EchoRequest\n                self.tcp.drive_interface_state(frame).await;\n            }\n            _ => {\n                debug!(\"IP packet ignored (protocol: {:?})\", packet.protocol());\n                return Ok(());\n            }\n        }\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/tun/tcp.rs",
    "content": "use std::{\n    collections::HashMap,\n    future::Future,\n    io, mem,\n    net::{IpAddr, SocketAddr},\n    pin::Pin,\n    sync::{\n        Arc,\n        atomic::{AtomicBool, Ordering},\n    },\n    task::{Context, Poll, Waker},\n    thread::{self, JoinHandle, Thread},\n    time::Duration,\n};\n\nuse log::{debug, error, trace};\nuse shadowsocks::{net::TcpSocketOpts, relay::socks5::Address};\nuse smoltcp::{\n    iface::{Config as InterfaceConfig, Interface, PollResult, SocketHandle, SocketSet},\n    phy::{Checksum, DeviceCapabilities, Medium},\n    socket::tcp::{CongestionControl, Socket as TcpSocket, SocketBuffer as TcpSocketBuffer, State as TcpState},\n    storage::RingBuffer,\n    time::{Duration as SmolDuration, Instant as SmolInstant},\n    wire::{HardwareAddress, IpAddress, IpCidr, Ipv4Address, Ipv6Address, TcpPacket},\n};\nuse spin::Mutex as SpinMutex;\nuse tokio::{\n    io::{AsyncRead, AsyncWrite, ReadBuf},\n    sync::{mpsc, oneshot},\n};\n\nuse crate::{\n    local::{\n        context::ServiceContext,\n        loadbalancing::PingBalancer,\n        net::AutoProxyClientStream,\n        utils::{establish_tcp_tunnel, establish_tcp_tunnel_bypassed},\n    },\n    net::utils::to_ipv4_mapped,\n};\n\nuse super::virt_device::{TokenBuffer, VirtTunDevice};\n\n// NOTE: Default buffer could contain 5 AEAD packets\nconst DEFAULT_TCP_SEND_BUFFER_SIZE: u32 = (0x3FFFu32 * 5).next_power_of_two();\nconst DEFAULT_TCP_RECV_BUFFER_SIZE: u32 = (0x3FFFu32 * 5).next_power_of_two();\n\n#[derive(Debug, Clone, Copy, Eq, PartialEq)]\nenum TcpSocketState {\n    Normal,\n    Close,\n    Closing,\n    Closed,\n}\n\nstruct TcpSocketControl {\n    send_buffer: RingBuffer<'static, u8>,\n    send_waker: Option<Waker>,\n    recv_buffer: RingBuffer<'static, u8>,\n    recv_waker: Option<Waker>,\n    recv_state: TcpSocketState,\n    send_state: TcpSocketState,\n}\n\nstruct ManagerNotify {\n    thread: Thread,\n}\n\nimpl ManagerNotify {\n    fn new(thread: Thread) -> Self {\n        Self { thread }\n    }\n\n    fn notify(&self) {\n        self.thread.unpark();\n    }\n}\n\nstruct TcpSocketManager {\n    device: VirtTunDevice,\n    iface: Interface,\n    sockets: HashMap<SocketHandle, SharedTcpConnectionControl>,\n    socket_creation_rx: mpsc::UnboundedReceiver<TcpSocketCreation>,\n}\n\ntype SharedTcpConnectionControl = Arc<SpinMutex<TcpSocketControl>>;\n\nstruct TcpSocketCreation {\n    control: SharedTcpConnectionControl,\n    socket: TcpSocket<'static>,\n    socket_created_tx: oneshot::Sender<()>,\n}\n\nstruct TcpConnection {\n    control: SharedTcpConnectionControl,\n    manager_notify: Arc<ManagerNotify>,\n}\n\nimpl Drop for TcpConnection {\n    fn drop(&mut self) {\n        let mut control = self.control.lock();\n\n        if matches!(control.recv_state, TcpSocketState::Normal) {\n            control.recv_state = TcpSocketState::Close;\n        }\n\n        if matches!(control.send_state, TcpSocketState::Normal) {\n            control.send_state = TcpSocketState::Close;\n        }\n\n        self.manager_notify.notify();\n    }\n}\n\nimpl TcpConnection {\n    fn new(\n        socket: TcpSocket<'static>,\n        socket_creation_tx: &mpsc::UnboundedSender<TcpSocketCreation>,\n        manager_notify: Arc<ManagerNotify>,\n        tcp_opts: &TcpSocketOpts,\n    ) -> impl Future<Output = Self> + use<> {\n        let send_buffer_size = tcp_opts.send_buffer_size.unwrap_or(DEFAULT_TCP_SEND_BUFFER_SIZE);\n        let recv_buffer_size = tcp_opts.recv_buffer_size.unwrap_or(DEFAULT_TCP_RECV_BUFFER_SIZE);\n\n        let control = Arc::new(SpinMutex::new(TcpSocketControl {\n            send_buffer: RingBuffer::new(vec![0u8; send_buffer_size as usize]),\n            send_waker: None,\n            recv_buffer: RingBuffer::new(vec![0u8; recv_buffer_size as usize]),\n            recv_waker: None,\n            recv_state: TcpSocketState::Normal,\n            send_state: TcpSocketState::Normal,\n        }));\n        let (tx, rx) = oneshot::channel();\n        let _ = socket_creation_tx.send(TcpSocketCreation {\n            control: control.clone(),\n            socket,\n            socket_created_tx: tx,\n        });\n        async move {\n            // waiting socket add to SocketSet\n            let _ = rx.await;\n            Self {\n                control,\n                manager_notify,\n            }\n        }\n    }\n}\n\nimpl AsyncRead for TcpConnection {\n    fn poll_read(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>) -> Poll<io::Result<()>> {\n        let mut control = self.control.lock();\n\n        // Read from buffer\n        if control.recv_buffer.is_empty() {\n            // If socket is already closed / half closed, just return EOF directly.\n            if matches!(control.recv_state, TcpSocketState::Closed) {\n                return Ok(()).into();\n            }\n\n            // Nothing could be read. Wait for notify.\n            if let Some(old_waker) = control.recv_waker.replace(cx.waker().clone())\n                && !old_waker.will_wake(cx.waker())\n            {\n                old_waker.wake();\n            }\n\n            return Poll::Pending;\n        }\n\n        let recv_buf = unsafe { mem::transmute::<&mut [mem::MaybeUninit<u8>], &mut [u8]>(buf.unfilled_mut()) };\n        let n = control.recv_buffer.dequeue_slice(recv_buf);\n        buf.advance(n);\n\n        if n > 0 {\n            self.manager_notify.notify();\n        }\n        Ok(()).into()\n    }\n}\n\nimpl AsyncWrite for TcpConnection {\n    fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<io::Result<usize>> {\n        let mut control = self.control.lock();\n\n        // If state == Close | Closing | Closed, the TCP stream WR half is closed.\n        if !matches!(control.send_state, TcpSocketState::Normal) {\n            return Err(io::ErrorKind::BrokenPipe.into()).into();\n        }\n\n        // Write to buffer\n\n        if control.send_buffer.is_full() {\n            if let Some(old_waker) = control.send_waker.replace(cx.waker().clone())\n                && !old_waker.will_wake(cx.waker())\n            {\n                old_waker.wake();\n            }\n\n            return Poll::Pending;\n        }\n\n        let n = control.send_buffer.enqueue_slice(buf);\n\n        if n > 0 {\n            self.manager_notify.notify();\n        }\n        Ok(n).into()\n    }\n\n    fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {\n        Ok(()).into()\n    }\n\n    fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {\n        let mut control = self.control.lock();\n\n        if matches!(control.send_state, TcpSocketState::Closed) {\n            return Ok(()).into();\n        }\n\n        // SHUT_WR\n        if matches!(control.send_state, TcpSocketState::Normal) {\n            control.send_state = TcpSocketState::Close;\n        }\n\n        if let Some(old_waker) = control.send_waker.replace(cx.waker().clone())\n            && !old_waker.will_wake(cx.waker())\n        {\n            old_waker.wake();\n        }\n\n        self.manager_notify.notify();\n        Poll::Pending\n    }\n}\n\npub struct TcpTun {\n    context: Arc<ServiceContext>,\n    manager_handle: Option<JoinHandle<()>>,\n    manager_notify: Arc<ManagerNotify>,\n    manager_socket_creation_tx: mpsc::UnboundedSender<TcpSocketCreation>,\n    manager_running: Arc<AtomicBool>,\n    balancer: PingBalancer,\n    iface_rx: mpsc::UnboundedReceiver<TokenBuffer>,\n    iface_tx: mpsc::UnboundedSender<TokenBuffer>,\n    iface_tx_avail: Arc<AtomicBool>,\n}\n\nimpl Drop for TcpTun {\n    fn drop(&mut self) {\n        self.manager_running.store(false, Ordering::Relaxed);\n        self.manager_notify.notify();\n        let _ = self.manager_handle.take().unwrap().join();\n    }\n}\n\nimpl TcpTun {\n    pub fn new(context: Arc<ServiceContext>, balancer: PingBalancer, mtu: u32) -> Self {\n        let mut capabilities = DeviceCapabilities::default();\n        capabilities.medium = Medium::Ip;\n        capabilities.max_transmission_unit = mtu as usize;\n        capabilities.checksum.ipv4 = Checksum::Tx;\n        capabilities.checksum.tcp = Checksum::Tx;\n        capabilities.checksum.udp = Checksum::Tx;\n        capabilities.checksum.icmpv4 = Checksum::Tx;\n        capabilities.checksum.icmpv6 = Checksum::Tx;\n\n        let (mut device, iface_rx, iface_tx, iface_tx_avail) = VirtTunDevice::new(capabilities);\n\n        let mut iface_config = InterfaceConfig::new(HardwareAddress::Ip);\n        iface_config.random_seed = rand::random();\n        let mut iface = Interface::new(iface_config, &mut device, SmolInstant::now());\n        iface.update_ip_addrs(|ip_addrs| {\n            ip_addrs\n                .push(IpCidr::new(IpAddress::v4(0, 0, 0, 1), 0))\n                .expect(\"iface IPv4\");\n            ip_addrs\n                .push(IpCidr::new(IpAddress::v6(0, 0, 0, 0, 0, 0, 0, 1), 0))\n                .expect(\"iface IPv6\");\n        });\n        iface\n            .routes_mut()\n            .add_default_ipv4_route(Ipv4Address::new(0, 0, 0, 1))\n            .expect(\"IPv4 default route\");\n        iface\n            .routes_mut()\n            .add_default_ipv6_route(Ipv6Address::new(0, 0, 0, 0, 0, 0, 0, 1))\n            .expect(\"IPv6 default route\");\n        iface.set_any_ip(true);\n\n        let (manager_socket_creation_tx, manager_socket_creation_rx) = mpsc::unbounded_channel();\n        let mut manager = TcpSocketManager {\n            device,\n            iface,\n            sockets: HashMap::new(),\n            socket_creation_rx: manager_socket_creation_rx,\n        };\n\n        let manager_running = Arc::new(AtomicBool::new(true));\n\n        let manager_handle = {\n            let manager_running = manager_running.clone();\n\n            thread::Builder::new()\n                .name(\"smoltcp-poll\".to_owned())\n                .spawn(move || {\n                    let TcpSocketManager {\n                        ref mut device,\n                        ref mut iface,\n                        ref mut sockets,\n                        ref mut socket_creation_rx,\n                        ..\n                    } = manager;\n\n                    let mut socket_set = SocketSet::new(vec![]);\n\n                    while manager_running.load(Ordering::Relaxed) {\n                        while let Ok(TcpSocketCreation {\n                            control,\n                            socket,\n                            socket_created_tx: socket_create_tx,\n                        }) = socket_creation_rx.try_recv()\n                        {\n                            let handle = socket_set.add(socket);\n                            let _ = socket_create_tx.send(());\n                            sockets.insert(handle, control);\n                        }\n\n                        let before_poll = SmolInstant::now();\n                        if let PollResult::SocketStateChanged = iface.poll(before_poll, device, &mut socket_set) {\n                            trace!(\"VirtDevice::poll costed {}\", SmolInstant::now() - before_poll);\n                        }\n\n                        // Check all the sockets' status\n                        let mut sockets_to_remove = Vec::new();\n\n                        for (socket_handle, control) in sockets.iter() {\n                            let socket_handle = *socket_handle;\n                            let socket = socket_set.get_mut::<TcpSocket>(socket_handle);\n                            let mut control = control.lock();\n\n                            // Remove the socket only when it is in the closed state.\n                            if socket.state() == TcpState::Closed {\n                                sockets_to_remove.push(socket_handle);\n\n                                control.send_state = TcpSocketState::Closed;\n                                control.recv_state = TcpSocketState::Closed;\n\n                                if let Some(waker) = control.send_waker.take() {\n                                    waker.wake();\n                                }\n                                if let Some(waker) = control.recv_waker.take() {\n                                    waker.wake();\n                                }\n\n                                trace!(\"closed TCP connection\");\n                                continue;\n                            }\n\n                            // SHUT_WR\n                            if matches!(control.send_state, TcpSocketState::Close)\n                                && socket.send_queue() == 0\n                                && control.send_buffer.is_empty()\n                            {\n                                trace!(\"closing TCP Write Half, {:?}\", socket.state());\n\n                                // Close the socket. Set to FIN state\n                                socket.close();\n                                control.send_state = TcpSocketState::Closing;\n\n                                // We can still process the pending buffer.\n                            }\n\n                            // Check if readable\n                            let mut wake_receiver = false;\n                            while socket.can_recv() && !control.recv_buffer.is_full() {\n                                let result = socket.recv(|buffer| {\n                                    let n = control.recv_buffer.enqueue_slice(buffer);\n                                    (n, ())\n                                });\n\n                                match result {\n                                    Ok(..) => {\n                                        wake_receiver = true;\n                                    }\n                                    Err(err) => {\n                                        error!(\"socket recv error: {:?}, {:?}\", err, socket.state());\n\n                                        // Don't know why. Abort the connection.\n                                        socket.abort();\n\n                                        if matches!(control.recv_state, TcpSocketState::Normal) {\n                                            control.recv_state = TcpSocketState::Closed;\n                                        }\n                                        wake_receiver = true;\n\n                                        // The socket will be recycled in the next poll.\n                                        break;\n                                    }\n                                }\n                            }\n\n                            // If socket is not in ESTABLISH, FIN-WAIT-1, FIN-WAIT-2,\n                            // the local client have closed our receiver.\n                            if matches!(control.recv_state, TcpSocketState::Normal)\n                                && !socket.may_recv()\n                                && !matches!(\n                                    socket.state(),\n                                    TcpState::Listen\n                                        | TcpState::SynReceived\n                                        | TcpState::Established\n                                        | TcpState::FinWait1\n                                        | TcpState::FinWait2\n                                )\n                            {\n                                trace!(\"closed TCP Read Half, {:?}\", socket.state());\n\n                                // Let TcpConnection::poll_read returns EOF.\n                                control.recv_state = TcpSocketState::Closed;\n                                wake_receiver = true;\n                            }\n\n                            if wake_receiver\n                                && control.recv_waker.is_some()\n                                && let Some(waker) = control.recv_waker.take()\n                            {\n                                waker.wake();\n                            }\n\n                            // Check if writable\n                            let mut wake_sender = false;\n                            while socket.can_send() && !control.send_buffer.is_empty() {\n                                let result = socket.send(|buffer| {\n                                    let n = control.send_buffer.dequeue_slice(buffer);\n                                    (n, ())\n                                });\n\n                                match result {\n                                    Ok(..) => {\n                                        wake_sender = true;\n                                    }\n                                    Err(err) => {\n                                        error!(\"socket send error: {:?}, {:?}\", err, socket.state());\n\n                                        // Don't know why. Abort the connection.\n                                        socket.abort();\n\n                                        if matches!(control.send_state, TcpSocketState::Normal) {\n                                            control.send_state = TcpSocketState::Closed;\n                                        }\n                                        wake_sender = true;\n\n                                        // The socket will be recycled in the next poll.\n                                        break;\n                                    }\n                                }\n                            }\n\n                            if wake_sender\n                                && control.send_waker.is_some()\n                                && let Some(waker) = control.send_waker.take()\n                            {\n                                waker.wake();\n                            }\n                        }\n\n                        for socket_handle in sockets_to_remove {\n                            sockets.remove(&socket_handle);\n                            socket_set.remove(socket_handle);\n                        }\n\n                        if !device.recv_available() {\n                            let next_duration = iface\n                                .poll_delay(before_poll, &socket_set)\n                                .unwrap_or(SmolDuration::from_millis(5));\n                            if next_duration != SmolDuration::ZERO {\n                                thread::park_timeout(Duration::from(next_duration));\n                            }\n                        }\n                    }\n\n                    trace!(\"VirtDevice::poll thread exited\");\n                })\n                .unwrap()\n        };\n\n        let manager_notify = Arc::new(ManagerNotify::new(manager_handle.thread().clone()));\n\n        Self {\n            context,\n            manager_handle: Some(manager_handle),\n            manager_notify,\n            manager_socket_creation_tx,\n            manager_running,\n            balancer,\n            iface_rx,\n            iface_tx,\n            iface_tx_avail,\n        }\n    }\n\n    pub async fn handle_packet(\n        &mut self,\n        src_addr: SocketAddr,\n        dst_addr: SocketAddr,\n        tcp_packet: &TcpPacket<&[u8]>,\n    ) -> io::Result<()> {\n        // TCP first handshake packet, create a new Connection\n        if tcp_packet.syn() && !tcp_packet.ack() {\n            let accept_opts = self.context.accept_opts();\n\n            let send_buffer_size = accept_opts.tcp.send_buffer_size.unwrap_or(DEFAULT_TCP_SEND_BUFFER_SIZE);\n            let recv_buffer_size = accept_opts.tcp.recv_buffer_size.unwrap_or(DEFAULT_TCP_RECV_BUFFER_SIZE);\n\n            let mut socket = TcpSocket::new(\n                TcpSocketBuffer::new(vec![0u8; recv_buffer_size as usize]),\n                TcpSocketBuffer::new(vec![0u8; send_buffer_size as usize]),\n            );\n            socket.set_keep_alive(accept_opts.tcp.keepalive.map(From::from));\n            // FIXME: It should follow system's setting. 7200 is Linux's default.\n            socket.set_timeout(Some(SmolDuration::from_secs(7200)));\n            // NO ACK delay\n            // socket.set_ack_delay(None);\n            // Enable Cubic congestion control\n            socket.set_congestion_control(CongestionControl::Cubic);\n\n            if let Err(err) = socket.listen(dst_addr) {\n                return Err(io::Error::other(format!(\"listen error: {:?}\", err)));\n            }\n\n            debug!(\"created TCP connection for {} <-> {}\", src_addr, dst_addr);\n\n            let connection = TcpConnection::new(\n                socket,\n                &self.manager_socket_creation_tx,\n                self.manager_notify.clone(),\n                &accept_opts.tcp,\n            );\n\n            // establish a tunnel\n            let context = self.context.clone();\n            let balancer = self.balancer.clone();\n            tokio::spawn(async move {\n                let connection = connection.await;\n                if let Err(err) = handle_redir_client(context, balancer, connection, src_addr, dst_addr).await {\n                    error!(\"TCP tunnel failure, {} <-> {}, error: {}\", src_addr, dst_addr, err);\n                }\n            });\n        }\n\n        Ok(())\n    }\n\n    pub async fn drive_interface_state(&mut self, frame: TokenBuffer) {\n        if self.iface_tx.send(frame).is_err() {\n            panic!(\"interface send channel closed unexpectedly\");\n        }\n\n        // Wake up and poll the interface.\n        self.iface_tx_avail.store(true, Ordering::Release);\n        self.manager_notify.notify();\n    }\n\n    pub async fn recv_packet(&mut self) -> TokenBuffer {\n        match self.iface_rx.recv().await {\n            Some(v) => v,\n            None => unreachable!(\"channel closed unexpectedly\"),\n        }\n    }\n}\n\n/// Established Client Transparent Proxy\n///\n/// This method must be called after handshaking with client (for example, socks5 handshaking)\nasync fn establish_client_tcp_redir(\n    context: Arc<ServiceContext>,\n    balancer: PingBalancer,\n    mut stream: TcpConnection,\n    peer_addr: SocketAddr,\n    addr: &Address,\n) -> io::Result<()> {\n    if balancer.is_empty() {\n        let mut remote = AutoProxyClientStream::connect_bypassed(context, addr).await?;\n        return establish_tcp_tunnel_bypassed(&mut stream, &mut remote, peer_addr, addr).await;\n    }\n\n    let server = balancer.best_tcp_server();\n    let svr_cfg = server.server_config();\n\n    let mut remote =\n        AutoProxyClientStream::connect_with_opts(context, &server, addr, server.connect_opts_ref()).await?;\n    establish_tcp_tunnel(svr_cfg, &mut stream, &mut remote, peer_addr, addr).await\n}\n\nasync fn handle_redir_client(\n    context: Arc<ServiceContext>,\n    balancer: PingBalancer,\n    s: TcpConnection,\n    peer_addr: SocketAddr,\n    mut daddr: SocketAddr,\n) -> io::Result<()> {\n    // Get forward address from socket\n    //\n    // Try to convert IPv4 mapped IPv6 address for dual-stack mode.\n    if let SocketAddr::V6(ref a) = daddr\n        && let Some(v4) = to_ipv4_mapped(a.ip())\n    {\n        daddr = SocketAddr::new(IpAddr::from(v4), a.port());\n    }\n    let target_addr = Address::from(daddr);\n    establish_client_tcp_redir(context, balancer, s, peer_addr, &target_addr).await\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/tun/udp.rs",
    "content": "use std::{\n    io::{self, ErrorKind},\n    net::{IpAddr, SocketAddr},\n    sync::Arc,\n    time::Duration,\n};\n\nuse bytes::{BufMut, BytesMut};\nuse etherparse::PacketBuilder;\nuse log::debug;\nuse shadowsocks::relay::socks5::Address;\nuse tokio::sync::mpsc;\n\nuse crate::{\n    local::{\n        context::ServiceContext,\n        loadbalancing::PingBalancer,\n        net::{UdpAssociationManager, UdpInboundWrite},\n    },\n    net::utils::to_ipv4_mapped,\n};\n\npub struct UdpTun {\n    tun_rx: mpsc::Receiver<BytesMut>,\n    manager: UdpAssociationManager<UdpTunInboundWriter>,\n}\n\nimpl UdpTun {\n    pub fn new(\n        context: Arc<ServiceContext>,\n        balancer: PingBalancer,\n        time_to_live: Option<Duration>,\n        capacity: Option<usize>,\n    ) -> (Self, Duration, mpsc::Receiver<SocketAddr>) {\n        let (tun_tx, tun_rx) = mpsc::channel(64);\n        let (manager, cleanup_interval, keepalive_rx) = UdpAssociationManager::new(\n            context,\n            UdpTunInboundWriter::new(tun_tx),\n            time_to_live,\n            capacity,\n            balancer,\n        );\n\n        (Self { tun_rx, manager }, cleanup_interval, keepalive_rx)\n    }\n\n    pub async fn handle_packet(\n        &mut self,\n        src_addr: SocketAddr,\n        dst_addr: SocketAddr,\n        payload: &[u8],\n    ) -> io::Result<()> {\n        debug!(\"UDP {} -> {} payload.size: {} bytes\", src_addr, dst_addr, payload.len());\n        if let Err(err) = self.manager.send_to(src_addr, dst_addr.into(), payload).await {\n            debug!(\n                \"UDP {} -> {} payload.size: {} bytes failed, error: {}\",\n                src_addr,\n                dst_addr,\n                payload.len(),\n                err,\n            );\n        }\n        Ok(())\n    }\n\n    pub async fn recv_packet(&mut self) -> BytesMut {\n        match self.tun_rx.recv().await {\n            Some(b) => b,\n            None => unreachable!(\"channel closed unexpectedly\"),\n        }\n    }\n\n    #[inline(always)]\n    pub async fn cleanup_expired(&mut self) {\n        self.manager.cleanup_expired().await;\n    }\n\n    #[inline(always)]\n    pub async fn keep_alive(&mut self, peer_addr: &SocketAddr) {\n        self.manager.keep_alive(peer_addr).await;\n    }\n}\n\n#[derive(Clone)]\nstruct UdpTunInboundWriter {\n    tun_tx: mpsc::Sender<BytesMut>,\n}\n\nimpl UdpTunInboundWriter {\n    fn new(tun_tx: mpsc::Sender<BytesMut>) -> Self {\n        Self { tun_tx }\n    }\n}\n\nimpl UdpInboundWrite for UdpTunInboundWriter {\n    async fn send_to(&self, peer_addr: SocketAddr, remote_addr: &Address, data: &[u8]) -> io::Result<()> {\n        let addr = match *remote_addr {\n            Address::SocketAddress(sa) => {\n                // Try to convert IPv4 mapped IPv6 address if server is running on dual-stack mode\n                match (peer_addr, sa) {\n                    (SocketAddr::V4(..), SocketAddr::V4(..)) | (SocketAddr::V6(..), SocketAddr::V6(..)) => sa,\n                    (SocketAddr::V4(..), SocketAddr::V6(v6)) => {\n                        // If peer is IPv4, then remote_addr can only be IPv4-mapped-IPv6\n                        match to_ipv4_mapped(v6.ip()) {\n                            Some(v4) => SocketAddr::new(IpAddr::from(v4), v6.port()),\n                            None => {\n                                return Err(io::Error::new(\n                                    ErrorKind::InvalidData,\n                                    \"source and destination type unmatch\",\n                                ));\n                            }\n                        }\n                    }\n                    (SocketAddr::V6(..), SocketAddr::V4(v4)) => {\n                        // Convert remote_addr to IPv4-mapped-IPv6\n                        SocketAddr::new(IpAddr::from(v4.ip().to_ipv6_mapped()), v4.port())\n                    }\n                }\n            }\n            Address::DomainNameAddress(..) => {\n                let err = io::Error::new(\n                    ErrorKind::InvalidInput,\n                    \"tun destination must not be an domain name address\",\n                );\n                return Err(err);\n            }\n        };\n\n        let packet = match (peer_addr, addr) {\n            (SocketAddr::V4(peer), SocketAddr::V4(remote)) => {\n                let builder =\n                    PacketBuilder::ipv4(remote.ip().octets(), peer.ip().octets(), 20).udp(remote.port(), peer.port());\n\n                let packet = BytesMut::with_capacity(builder.size(data.len()));\n                let mut packet_writer = packet.writer();\n                builder.write(&mut packet_writer, data).expect(\"PacketBuilder::write\");\n\n                packet_writer.into_inner()\n            }\n            (SocketAddr::V6(peer), SocketAddr::V6(remote)) => {\n                let builder =\n                    PacketBuilder::ipv6(remote.ip().octets(), peer.ip().octets(), 20).udp(remote.port(), peer.port());\n\n                let packet = BytesMut::with_capacity(builder.size(data.len()));\n                let mut packet_writer = packet.writer();\n                builder.write(&mut packet_writer, data).expect(\"PacketBuilder::write\");\n\n                packet_writer.into_inner()\n            }\n            _ => {\n                return Err(io::Error::new(\n                    ErrorKind::InvalidData,\n                    \"source and destination type unmatch\",\n                ));\n            }\n        };\n\n        self.tun_tx.send(packet).await.expect(\"tun_tx::send\");\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/tun/virt_device.rs",
    "content": "//! Virtual Device for receiving packets from tun\n\nuse std::{\n    marker::PhantomData,\n    mem,\n    ops::{Deref, DerefMut},\n    sync::{\n        Arc, LazyLock, Mutex,\n        atomic::{AtomicBool, Ordering},\n    },\n};\n\nuse bytes::BytesMut;\nuse smoltcp::{\n    phy::{self, Device, DeviceCapabilities},\n    time::Instant,\n};\nuse tokio::sync::mpsc;\n\npub struct VirtTunDevice {\n    capabilities: DeviceCapabilities,\n    in_buf: mpsc::UnboundedReceiver<TokenBuffer>,\n    out_buf: mpsc::UnboundedSender<TokenBuffer>,\n    in_buf_avail: Arc<AtomicBool>,\n}\n\nimpl VirtTunDevice {\n    #[allow(clippy::type_complexity)]\n    pub fn new(\n        capabilities: DeviceCapabilities,\n    ) -> (\n        Self,\n        mpsc::UnboundedReceiver<TokenBuffer>,\n        mpsc::UnboundedSender<TokenBuffer>,\n        Arc<AtomicBool>,\n    ) {\n        let (iface_tx, iface_output) = mpsc::unbounded_channel();\n        let (iface_input, iface_rx) = mpsc::unbounded_channel();\n        let in_buf_avail = Arc::new(AtomicBool::new(false));\n\n        (\n            Self {\n                capabilities,\n                in_buf: iface_rx,\n                out_buf: iface_tx,\n                in_buf_avail: in_buf_avail.clone(),\n            },\n            iface_output,\n            iface_input,\n            in_buf_avail,\n        )\n    }\n\n    #[inline]\n    pub fn recv_available(&self) -> bool {\n        self.in_buf_avail.load(Ordering::Acquire)\n    }\n}\n\nimpl Device for VirtTunDevice {\n    type RxToken<'a> = VirtRxToken<'a>;\n    type TxToken<'a> = VirtTxToken<'a>;\n\n    fn receive(&mut self, _timestamp: Instant) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {\n        if let Ok(buffer) = self.in_buf.try_recv() {\n            let rx = Self::RxToken {\n                buffer,\n                phantom_device: PhantomData,\n            };\n            let tx = VirtTxToken(self);\n            return Some((rx, tx));\n        }\n        self.in_buf_avail.store(false, Ordering::Release);\n        None\n    }\n\n    fn transmit(&mut self, _timestamp: Instant) -> Option<Self::TxToken<'_>> {\n        Some(VirtTxToken(self))\n    }\n\n    fn capabilities(&self) -> DeviceCapabilities {\n        self.capabilities.clone()\n    }\n}\n\npub struct VirtRxToken<'a> {\n    buffer: TokenBuffer,\n    phantom_device: PhantomData<&'a VirtTunDevice>,\n}\n\nimpl phy::RxToken for VirtRxToken<'_> {\n    fn consume<R, F>(self, f: F) -> R\n    where\n        F: FnOnce(&[u8]) -> R,\n    {\n        f(&self.buffer)\n    }\n}\n\npub struct VirtTxToken<'a>(&'a mut VirtTunDevice);\n\nimpl phy::TxToken for VirtTxToken<'_> {\n    fn consume<R, F>(self, len: usize, f: F) -> R\n    where\n        F: FnOnce(&mut [u8]) -> R,\n    {\n        let mut buffer = TokenBuffer::with_capacity(len);\n        unsafe {\n            buffer.set_len(len);\n        }\n\n        let result = f(&mut buffer);\n        self.0.out_buf.send(buffer).expect(\"channel closed unexpectedly\");\n        result\n    }\n}\n\n// Maximum number of TokenBuffer cached globally.\n//\n// Each of them has capacity 65536 (defined in tun/mod.rs), so 64 * 65536 = 4MB.\nconst TOKEN_BUFFER_LIST_MAX_SIZE: usize = 64;\nstatic TOKEN_BUFFER_LIST: LazyLock<Mutex<Vec<BytesMut>>> = LazyLock::new(|| Mutex::new(Vec::new()));\n\npub struct TokenBuffer {\n    buffer: BytesMut,\n}\n\nimpl Drop for TokenBuffer {\n    fn drop(&mut self) {\n        let mut list = TOKEN_BUFFER_LIST.lock().unwrap();\n        if list.len() >= TOKEN_BUFFER_LIST_MAX_SIZE {\n            return;\n        }\n\n        let empty_buffer = BytesMut::new();\n        let mut buffer = mem::replace(&mut self.buffer, empty_buffer);\n        buffer.clear();\n\n        list.push(buffer);\n    }\n}\n\nimpl TokenBuffer {\n    pub fn with_capacity(cap: usize) -> Self {\n        let mut list = TOKEN_BUFFER_LIST.lock().unwrap();\n        if let Some(mut buffer) = list.pop() {\n            buffer.reserve(cap);\n            return Self { buffer };\n        }\n        Self {\n            buffer: BytesMut::with_capacity(cap),\n        }\n    }\n}\n\nimpl Deref for TokenBuffer {\n    type Target = BytesMut;\n\n    fn deref(&self) -> &Self::Target {\n        &self.buffer\n    }\n}\n\nimpl DerefMut for TokenBuffer {\n    fn deref_mut(&mut self) -> &mut Self::Target {\n        &mut self.buffer\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/tunnel/mod.rs",
    "content": "//! Shadowsocks Local Tunnel Server\n\npub use self::server::{Tunnel, TunnelBuilder};\n\npub mod server;\nmod tcprelay;\nmod udprelay;\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/tunnel/server.rs",
    "content": "//! Shadowsocks Local Tunnel Server\n\nuse std::{io, sync::Arc, time::Duration};\n\nuse futures::{FutureExt, future};\nuse shadowsocks::{ServerAddr, config::Mode, relay::socks5::Address};\n\nuse crate::local::{context::ServiceContext, loadbalancing::PingBalancer};\n\nuse super::{\n    tcprelay::{TunnelTcpServer, TunnelTcpServerBuilder},\n    udprelay::{TunnelUdpServer, TunnelUdpServerBuilder},\n};\n\npub struct TunnelBuilder {\n    context: Arc<ServiceContext>,\n    forward_addr: Address,\n    mode: Mode,\n    udp_expiry_duration: Option<Duration>,\n    udp_capacity: Option<usize>,\n    client_addr: ServerAddr,\n    udp_addr: Option<ServerAddr>,\n    balancer: PingBalancer,\n    #[cfg(target_os = \"macos\")]\n    launchd_tcp_socket_name: Option<String>,\n    #[cfg(target_os = \"macos\")]\n    launchd_udp_socket_name: Option<String>,\n}\n\nimpl TunnelBuilder {\n    /// Create a new Tunnel server forwarding to `forward_addr`\n    pub fn new(forward_addr: Address, client_addr: ServerAddr, balancer: PingBalancer) -> Self {\n        let context = ServiceContext::new();\n        Self::with_context(Arc::new(context), forward_addr, client_addr, balancer)\n    }\n\n    /// Create a new Tunnel server with context\n    pub fn with_context(\n        context: Arc<ServiceContext>,\n        forward_addr: Address,\n        client_addr: ServerAddr,\n        balancer: PingBalancer,\n    ) -> Self {\n        Self {\n            context,\n            forward_addr,\n            mode: Mode::TcpOnly,\n            udp_expiry_duration: None,\n            udp_capacity: None,\n            client_addr,\n            udp_addr: None,\n            balancer,\n            #[cfg(target_os = \"macos\")]\n            launchd_tcp_socket_name: None,\n            #[cfg(target_os = \"macos\")]\n            launchd_udp_socket_name: None,\n        }\n    }\n\n    /// Set UDP association's expiry duration\n    pub fn set_udp_expiry_duration(&mut self, d: Duration) {\n        self.udp_expiry_duration = Some(d);\n    }\n\n    /// Set total UDP association to be kept simultaneously in server\n    pub fn set_udp_capacity(&mut self, c: usize) {\n        self.udp_capacity = Some(c);\n    }\n\n    /// Set server mode\n    pub fn set_mode(&mut self, mode: Mode) {\n        self.mode = mode;\n    }\n\n    /// Set UDP bind address\n    pub fn set_udp_bind_addr(&mut self, addr: ServerAddr) {\n        self.udp_addr = Some(addr);\n    }\n\n    /// macOS launchd activate socket\n    #[cfg(target_os = \"macos\")]\n    pub fn set_launchd_tcp_socket_name(&mut self, n: String) {\n        self.launchd_tcp_socket_name = Some(n);\n    }\n\n    /// macOS launchd activate socket\n    #[cfg(target_os = \"macos\")]\n    pub fn set_launchd_udp_socket_name(&mut self, n: String) {\n        self.launchd_udp_socket_name = Some(n);\n    }\n\n    pub async fn build(self) -> io::Result<Tunnel> {\n        let mut tcp_server = None;\n        if self.mode.enable_tcp() {\n            #[allow(unused_mut)]\n            let mut builder = TunnelTcpServerBuilder::new(\n                self.context.clone(),\n                self.client_addr.clone(),\n                self.balancer.clone(),\n                self.forward_addr.clone(),\n            );\n\n            #[cfg(target_os = \"macos\")]\n            if let Some(s) = self.launchd_tcp_socket_name {\n                builder.set_launchd_socket_name(s);\n            }\n\n            let server = builder.build().await?;\n            tcp_server = Some(server);\n        }\n\n        let mut udp_server = None;\n        if self.mode.enable_udp() {\n            let udp_addr = self.udp_addr.unwrap_or(self.client_addr);\n\n            #[allow(unused_mut)]\n            let mut builder = TunnelUdpServerBuilder::new(\n                self.context.clone(),\n                udp_addr,\n                self.udp_expiry_duration,\n                self.udp_capacity,\n                self.balancer,\n                self.forward_addr,\n            );\n\n            #[cfg(target_os = \"macos\")]\n            if let Some(s) = self.launchd_udp_socket_name {\n                builder.set_launchd_socket_name(s);\n            }\n\n            let server = builder.build().await?;\n            udp_server = Some(server);\n        }\n\n        Ok(Tunnel { tcp_server, udp_server })\n    }\n}\n\n/// Tunnel Server\npub struct Tunnel {\n    tcp_server: Option<TunnelTcpServer>,\n    udp_server: Option<TunnelUdpServer>,\n}\n\nimpl Tunnel {\n    /// TCP server instance\n    pub fn tcp_server(&self) -> Option<&TunnelTcpServer> {\n        self.tcp_server.as_ref()\n    }\n\n    /// UDP server instance\n    pub fn udp_server(&self) -> Option<&TunnelUdpServer> {\n        self.udp_server.as_ref()\n    }\n\n    /// Start serving\n    pub async fn run(self) -> io::Result<()> {\n        let mut vfut = Vec::new();\n\n        if let Some(tcp_server) = self.tcp_server {\n            vfut.push(tcp_server.run().boxed());\n        }\n\n        if let Some(udp_server) = self.udp_server {\n            vfut.push(udp_server.run().boxed());\n        }\n\n        let (res, ..) = future::select_all(vfut).await;\n        res\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/tunnel/tcprelay.rs",
    "content": "//! TCP Tunnel Server\n\nuse std::{io, net::SocketAddr, sync::Arc, time::Duration};\n\nuse log::{error, info, trace};\nuse shadowsocks::{ServerAddr, net::TcpListener as ShadowTcpListener, relay::socks5::Address};\nuse tokio::{net::TcpStream, time};\n\nuse crate::local::{\n    context::ServiceContext,\n    loadbalancing::PingBalancer,\n    net::{AutoProxyClientStream, tcp::listener::create_standard_tcp_listener},\n    utils::{establish_tcp_tunnel, establish_tcp_tunnel_bypassed},\n};\n\npub struct TunnelTcpServerBuilder {\n    context: Arc<ServiceContext>,\n    client_config: ServerAddr,\n    balancer: PingBalancer,\n    forward_addr: Address,\n    #[cfg(target_os = \"macos\")]\n    launchd_socket_name: Option<String>,\n}\n\nimpl TunnelTcpServerBuilder {\n    pub(crate) fn new(\n        context: Arc<ServiceContext>,\n        client_config: ServerAddr,\n        balancer: PingBalancer,\n        forward_addr: Address,\n    ) -> Self {\n        Self {\n            context,\n            client_config,\n            balancer,\n            forward_addr,\n            #[cfg(target_os = \"macos\")]\n            launchd_socket_name: None,\n        }\n    }\n\n    /// macOS launchd activate socket\n    #[cfg(target_os = \"macos\")]\n    pub fn set_launchd_socket_name(&mut self, n: String) {\n        self.launchd_socket_name = Some(n);\n    }\n\n    pub async fn build(self) -> io::Result<TunnelTcpServer> {\n        cfg_if::cfg_if! {\n            if #[cfg(target_os = \"macos\")] {\n                let listener = match self.launchd_socket_name {\n                    Some(launchd_socket_name) => {\n                        use tokio::net::TcpListener as TokioTcpListener;\n                        use crate::net::launch_activate_socket::get_launch_activate_tcp_listener;\n\n                        let std_listener = get_launch_activate_tcp_listener(&launchd_socket_name, true)?;\n                        let tokio_listener = TokioTcpListener::from_std(std_listener)?;\n                        ShadowTcpListener::from_listener(tokio_listener, self.context.accept_opts())?\n                    } _ => {\n                        create_standard_tcp_listener(&self.context, &self.client_config).await?\n                    }\n                };\n            } else {\n                let listener = create_standard_tcp_listener(&self.context, &self.client_config).await?;\n            }\n        }\n\n        Ok(TunnelTcpServer {\n            context: self.context,\n            listener,\n            balancer: self.balancer,\n            forward_addr: self.forward_addr,\n        })\n    }\n}\n\n/// TCP Tunnel instance\npub struct TunnelTcpServer {\n    context: Arc<ServiceContext>,\n    listener: ShadowTcpListener,\n    balancer: PingBalancer,\n    forward_addr: Address,\n}\n\nimpl TunnelTcpServer {\n    /// Server's local address\n    pub fn local_addr(&self) -> io::Result<SocketAddr> {\n        self.listener.local_addr()\n    }\n\n    /// Start serving\n    pub async fn run(self) -> io::Result<()> {\n        info!(\"shadowsocks TCP tunnel listening on {}\", self.listener.local_addr()?);\n\n        let forward_addr = Arc::new(self.forward_addr);\n        loop {\n            let (stream, peer_addr) = match self.listener.accept().await {\n                Ok(s) => s,\n                Err(err) => {\n                    error!(\"accept failed with error: {}\", err);\n                    time::sleep(Duration::from_secs(1)).await;\n                    continue;\n                }\n            };\n\n            tokio::spawn(handle_tcp_client(\n                self.context.clone(),\n                stream,\n                self.balancer.clone(),\n                peer_addr,\n                forward_addr.clone(),\n            ));\n        }\n    }\n}\n\nasync fn handle_tcp_client(\n    context: Arc<ServiceContext>,\n    mut stream: TcpStream,\n    balancer: PingBalancer,\n    peer_addr: SocketAddr,\n    forward_addr: Arc<Address>,\n) -> io::Result<()> {\n    let forward_addr: &Address = &forward_addr;\n\n    if balancer.is_empty() {\n        trace!(\"establishing tcp tunnel {} <-> {} direct\", peer_addr, forward_addr);\n\n        let mut remote = AutoProxyClientStream::connect_bypassed(context, forward_addr).await?;\n        return establish_tcp_tunnel_bypassed(&mut stream, &mut remote, peer_addr, forward_addr).await;\n    }\n\n    let server = balancer.best_tcp_server();\n    let svr_cfg = server.server_config();\n    trace!(\n        \"establishing tcp tunnel {} <-> {} through server {} (outbound: {})\",\n        peer_addr,\n        forward_addr,\n        svr_cfg.tcp_external_addr(),\n        svr_cfg.addr(),\n    );\n\n    let mut remote =\n        AutoProxyClientStream::connect_proxied_with_opts(context, &server, forward_addr, server.connect_opts_ref())\n            .await?;\n    establish_tcp_tunnel(svr_cfg, &mut stream, &mut remote, peer_addr, forward_addr).await\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/tunnel/udprelay.rs",
    "content": "//! UDP Tunnel server\n\nuse std::{io, net::SocketAddr, sync::Arc, time::Duration};\n\nuse log::{debug, error, info};\nuse shadowsocks::{\n    ServerAddr,\n    relay::{socks5::Address, udprelay::MAXIMUM_UDP_PAYLOAD_SIZE},\n};\nuse tokio::{net::UdpSocket, time};\n\nuse crate::local::{\n    context::ServiceContext,\n    loadbalancing::PingBalancer,\n    net::{UdpAssociationManager, UdpInboundWrite, udp::listener::create_standard_udp_listener},\n};\n\npub struct TunnelUdpServerBuilder {\n    context: Arc<ServiceContext>,\n    client_config: ServerAddr,\n    time_to_live: Option<Duration>,\n    capacity: Option<usize>,\n    balancer: PingBalancer,\n    forward_addr: Address,\n    #[cfg(target_os = \"macos\")]\n    launchd_socket_name: Option<String>,\n}\n\nimpl TunnelUdpServerBuilder {\n    pub(crate) fn new(\n        context: Arc<ServiceContext>,\n        client_config: ServerAddr,\n        time_to_live: Option<Duration>,\n        capacity: Option<usize>,\n        balancer: PingBalancer,\n        forward_addr: Address,\n    ) -> Self {\n        Self {\n            context,\n            client_config,\n            time_to_live,\n            capacity,\n            balancer,\n            forward_addr,\n            #[cfg(target_os = \"macos\")]\n            launchd_socket_name: None,\n        }\n    }\n\n    /// macOS launchd activate socket\n    #[cfg(target_os = \"macos\")]\n    pub fn set_launchd_socket_name(&mut self, n: String) {\n        self.launchd_socket_name = Some(n);\n    }\n\n    pub async fn build(self) -> io::Result<TunnelUdpServer> {\n        cfg_if::cfg_if! {\n            if #[cfg(target_os = \"macos\")] {\n                let socket = match self.launchd_socket_name {\n                    Some(launchd_socket_name) => {\n                        use tokio::net::UdpSocket as TokioUdpSocket;\n                        use crate::net::launch_activate_socket::get_launch_activate_udp_socket;\n\n                        let std_socket = get_launch_activate_udp_socket(&launchd_socket_name, true)?;\n                        TokioUdpSocket::from_std(std_socket)?\n                    } _ => {\n                        create_standard_udp_listener(&self.context, &self.client_config).await?.into()\n                    }\n                };\n            } else {\n                let socket = create_standard_udp_listener(&self.context, &self.client_config).await?.into();\n            }\n        }\n\n        Ok(TunnelUdpServer {\n            context: self.context,\n            time_to_live: self.time_to_live,\n            capacity: self.capacity,\n            listener: Arc::new(socket),\n            balancer: self.balancer,\n            forward_addr: self.forward_addr,\n        })\n    }\n}\n\n#[derive(Clone)]\nstruct TunnelUdpInboundWriter {\n    inbound: Arc<UdpSocket>,\n}\n\nimpl UdpInboundWrite for TunnelUdpInboundWriter {\n    async fn send_to(&self, peer_addr: SocketAddr, _remote_addr: &Address, data: &[u8]) -> io::Result<()> {\n        self.inbound.send_to(data, peer_addr).await.map(|_| ())\n    }\n}\n\npub struct TunnelUdpServer {\n    context: Arc<ServiceContext>,\n    time_to_live: Option<Duration>,\n    capacity: Option<usize>,\n    listener: Arc<UdpSocket>,\n    balancer: PingBalancer,\n    forward_addr: Address,\n}\n\nimpl TunnelUdpServer {\n    /// Get server's local address\n    pub fn local_addr(&self) -> io::Result<SocketAddr> {\n        self.listener.local_addr()\n    }\n\n    /// Start serving\n    pub async fn run(self) -> io::Result<()> {\n        info!(\"shadowsocks UDP tunnel listening on {}\", self.listener.local_addr()?);\n\n        let (mut manager, cleanup_interval, mut keepalive_rx) = UdpAssociationManager::new(\n            self.context.clone(),\n            TunnelUdpInboundWriter {\n                inbound: self.listener.clone(),\n            },\n            self.time_to_live,\n            self.capacity,\n            self.balancer,\n        );\n\n        let mut buffer = [0u8; MAXIMUM_UDP_PAYLOAD_SIZE];\n        let mut cleanup_timer = time::interval(cleanup_interval);\n\n        loop {\n            tokio::select! {\n                _ = cleanup_timer.tick() => {\n                    // cleanup expired associations. iter() will remove expired elements\n                    manager.cleanup_expired().await;\n                }\n\n                peer_addr_opt = keepalive_rx.recv() => {\n                    let peer_addr = peer_addr_opt.expect(\"keep-alive channel closed unexpectedly\");\n                    manager.keep_alive(&peer_addr).await;\n                }\n\n                recv_result = self.listener.recv_from(&mut buffer) => {\n                    let (n, peer_addr) = match recv_result {\n                        Ok(s) => s,\n                        Err(err) => {\n                            error!(\"udp server recv_from failed with error: {}\", err);\n                            time::sleep(Duration::from_secs(1)).await;\n                            continue;\n                        }\n                    };\n\n                    if n == 0 {\n                        // For windows, it will generate a ICMP Port Unreachable Message\n                        // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-recvfrom\n                        // Which will result in recv_from return 0.\n                        //\n                        // It cannot be solved here, because `WSAGetLastError` is already set.\n                        //\n                        // See `relay::udprelay::utils::create_socket` for more detail.\n                        continue;\n                    }\n\n                    let data = &buffer[..n];\n                    if let Err(err) = manager.send_to(peer_addr, self.forward_addr.clone(), data)\n                        .await\n                    {\n                        debug!(\n                            \"udp packet relay {} -> {} with {} bytes failed, error: {}\",\n                            peer_addr,\n                            self.forward_addr,\n                            data.len(),\n                            err\n                        );\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/local/utils.rs",
    "content": "//! Shadowsocks Local Utilities\n\nuse std::{io, net::SocketAddr, time::Duration};\n\nuse log::{debug, trace};\nuse shadowsocks::{\n    config::ServerConfig,\n    relay::{socks5::Address, tcprelay::utils::copy_encrypted_bidirectional},\n};\nuse tokio::{\n    io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, copy_bidirectional},\n    time,\n};\n\nuse crate::local::net::AutoProxyIo;\n\npub(crate) async fn establish_tcp_tunnel<P, S>(\n    svr_cfg: &ServerConfig,\n    plain: &mut P,\n    shadow: &mut S,\n    peer_addr: SocketAddr,\n    target_addr: &Address,\n) -> io::Result<()>\nwhere\n    P: AsyncRead + AsyncWrite + Unpin,\n    S: AsyncRead + AsyncWrite + AutoProxyIo + Unpin,\n{\n    if shadow.is_proxied() {\n        debug!(\n            \"established tcp tunnel {} <-> {} through server {} (outbound: {})\",\n            peer_addr,\n            target_addr,\n            svr_cfg.tcp_external_addr(),\n            svr_cfg.addr(),\n        );\n    } else {\n        return establish_tcp_tunnel_bypassed(plain, shadow, peer_addr, target_addr).await;\n    }\n\n    // https://github.com/shadowsocks/shadowsocks-rust/issues/232\n    //\n    // Protocols like FTP, clients will wait for servers to send Welcome Message without sending anything.\n    //\n    // Wait at most 500ms, and then sends handshake packet to remote servers.\n    {\n        let mut buffer = [0u8; 8192];\n        match time::timeout(Duration::from_millis(500), plain.read(&mut buffer)).await {\n            Ok(Ok(0)) => {\n                // EOF. Just terminate right here.\n                return Ok(());\n            }\n            Ok(Ok(n)) => {\n                // Send the first packet.\n                shadow.write_all(&buffer[..n]).await?;\n            }\n            Ok(Err(err)) => return Err(err),\n            Err(..) => {\n                // Timeout. Send handshake to server.\n                let _ = shadow.write(&[]).await?;\n\n                trace!(\n                    \"tcp tunnel {} -> {} (proxied) sent handshake without data\",\n                    peer_addr, target_addr\n                );\n            }\n        }\n    }\n\n    match copy_encrypted_bidirectional(svr_cfg.method(), shadow, plain).await {\n        Ok((wn, rn)) => {\n            trace!(\n                \"tcp tunnel {} <-> {} (proxied) closed, L2R {} bytes, R2L {} bytes\",\n                peer_addr, target_addr, rn, wn\n            );\n        }\n        Err(err) => {\n            trace!(\n                \"tcp tunnel {} <-> {} (proxied) closed with error: {}\",\n                peer_addr, target_addr, err\n            );\n        }\n    }\n\n    Ok(())\n}\n\npub(crate) async fn establish_tcp_tunnel_bypassed<P, S>(\n    plain: &mut P,\n    shadow: &mut S,\n    peer_addr: SocketAddr,\n    target_addr: &Address,\n) -> io::Result<()>\nwhere\n    P: AsyncRead + AsyncWrite + Unpin,\n    S: AsyncRead + AsyncWrite + Unpin,\n{\n    debug!(\"established tcp tunnel {} <-> {} bypassed\", peer_addr, target_addr);\n\n    match copy_bidirectional(plain, shadow).await {\n        Ok((rn, wn)) => {\n            trace!(\n                \"tcp tunnel {} <-> {} (bypassed) closed, L2R {} bytes, R2L {} bytes\",\n                peer_addr, target_addr, rn, wn\n            );\n        }\n        Err(err) => {\n            trace!(\n                \"tcp tunnel {} <-> {} (bypassed) closed with error: {}\",\n                peer_addr, target_addr, err\n            );\n        }\n    }\n\n    Ok(())\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/manager/mod.rs",
    "content": "//! Shadowsocks manager service\n//!\n//! Service for managing multiple relay servers. [Manage Multiple Users](https://github.com/shadowsocks/shadowsocks/wiki/Manage-Multiple-Users)\n\nuse std::{io, net::SocketAddr, sync::Arc};\n\nuse log::trace;\nuse shadowsocks::net::{AcceptOpts, ConnectOpts};\n\nuse crate::{\n    config::{Config, ConfigType},\n    dns::build_dns_resolver,\n    server::SERVER_DEFAULT_KEEPALIVE_TIMEOUT,\n};\n\npub use self::server::{Manager, ManagerBuilder};\n\npub mod server;\n\n/// Starts a manager server\npub async fn run(config: Config) -> io::Result<()> {\n    assert_eq!(config.config_type, ConfigType::Manager);\n\n    trace!(\"{:?}\", config);\n\n    #[cfg(all(unix, not(target_os = \"android\")))]\n    if let Some(nofile) = config.nofile {\n        use crate::sys::set_nofile;\n        if let Err(err) = set_nofile(nofile) {\n            log::warn!(\"set_nofile {} failed, error: {}\", nofile, err);\n        }\n    }\n\n    let mut manager_builder = ManagerBuilder::new(config.manager.expect(\"missing manager config\"));\n\n    let mut connect_opts = ConnectOpts {\n        #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n        fwmark: config.outbound_fwmark,\n        #[cfg(target_os = \"freebsd\")]\n        user_cookie: config.outbound_user_cookie,\n\n        #[cfg(target_os = \"android\")]\n        vpn_protect_path: config.outbound_vpn_protect_path,\n\n        bind_local_addr: config.outbound_bind_addr.map(|ip| SocketAddr::new(ip, 0)),\n        bind_interface: config.outbound_bind_interface,\n\n        ..Default::default()\n    };\n\n    connect_opts.tcp.send_buffer_size = config.outbound_send_buffer_size;\n    connect_opts.tcp.recv_buffer_size = config.outbound_recv_buffer_size;\n    connect_opts.tcp.nodelay = config.no_delay;\n    connect_opts.tcp.fastopen = config.fast_open;\n    connect_opts.tcp.keepalive = config.keep_alive.or(Some(SERVER_DEFAULT_KEEPALIVE_TIMEOUT));\n    connect_opts.tcp.mptcp = config.mptcp;\n    connect_opts.udp.mtu = config.udp_mtu;\n    connect_opts.udp.allow_fragmentation = config.outbound_udp_allow_fragmentation;\n\n    let mut accept_opts = AcceptOpts {\n        ipv6_only: config.ipv6_only,\n        ..Default::default()\n    };\n    accept_opts.tcp.send_buffer_size = config.inbound_send_buffer_size;\n    accept_opts.tcp.recv_buffer_size = config.inbound_recv_buffer_size;\n    accept_opts.tcp.nodelay = config.no_delay;\n    accept_opts.tcp.fastopen = config.fast_open;\n    accept_opts.tcp.keepalive = config.keep_alive.or(Some(SERVER_DEFAULT_KEEPALIVE_TIMEOUT));\n    accept_opts.tcp.mptcp = config.mptcp;\n    accept_opts.udp.mtu = config.udp_mtu;\n\n    if let Some(resolver) =\n        build_dns_resolver(config.dns, config.ipv6_first, config.dns_cache_size, &connect_opts).await\n    {\n        manager_builder.set_dns_resolver(Arc::new(resolver));\n    }\n    manager_builder.set_ipv6_first(config.ipv6_first);\n\n    manager_builder.set_connect_opts(connect_opts);\n    manager_builder.set_accept_opts(accept_opts);\n\n    if let Some(c) = config.udp_max_associations {\n        manager_builder.set_udp_capacity(c);\n    }\n\n    if let Some(d) = config.udp_timeout {\n        manager_builder.set_udp_expiry_duration(d);\n    }\n\n    if let Some(acl) = config.acl {\n        manager_builder.set_acl(Arc::new(acl));\n    }\n\n    let manager = manager_builder.build().await?;\n\n    for svr_inst in config.server {\n        manager.add_server(svr_inst.config).await;\n    }\n\n    manager.run().await\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/manager/server.rs",
    "content": "//! Shadowsocks Manager server\n\n#[cfg(unix)]\nuse std::path::PathBuf;\nuse std::{collections::HashMap, io, net::SocketAddr, sync::Arc, time::Duration};\n\nuse cfg_if::cfg_if;\nuse log::{error, info, trace};\nuse shadowsocks::{\n    ManagerListener, ServerAddr,\n    config::{Mode, ServerConfig, ServerType, ServerUser, ServerUserManager},\n    context::{Context, SharedContext},\n    crypto::CipherKind,\n    dns_resolver::DnsResolver,\n    manager::{\n        datagram::ManagerSocketAddr,\n        protocol::{\n            self, AddRequest, AddResponse, ErrorResponse, ListResponse, ManagerRequest, PingResponse, RemoveRequest,\n            RemoveResponse, ServerUserConfig, StatRequest,\n        },\n    },\n    net::{AcceptOpts, ConnectOpts},\n    plugin::PluginConfig,\n};\nuse tokio::{sync::Mutex, task::JoinHandle};\n\nuse crate::{\n    acl::AccessControl,\n    config::{ManagerConfig, ManagerServerHost, ManagerServerMode, SecurityConfig},\n    net::FlowStat,\n    server::ServerBuilder,\n};\n\nenum ServerInstanceMode {\n    Builtin {\n        flow_stat: Arc<FlowStat>,\n        abortable: JoinHandle<io::Result<()>>,\n    },\n\n    #[cfg(unix)]\n    Standalone { flow_stat: u64 },\n}\n\nstruct ServerInstance {\n    mode: ServerInstanceMode,\n    svr_cfg: ServerConfig,\n}\n\nimpl Drop for ServerInstance {\n    fn drop(&mut self) {\n        #[allow(irrefutable_let_patterns)]\n        if let ServerInstanceMode::Builtin { ref abortable, .. } = self.mode {\n            abortable.abort();\n        }\n    }\n}\n\nimpl ServerInstance {\n    fn flow_stat(&self) -> u64 {\n        match self.mode {\n            ServerInstanceMode::Builtin { ref flow_stat, .. } => flow_stat.tx() + flow_stat.rx(),\n            #[cfg(unix)]\n            ServerInstanceMode::Standalone { flow_stat } => flow_stat,\n        }\n    }\n}\n\n/// Manager server builder\npub struct ManagerBuilder {\n    context: SharedContext,\n    svr_cfg: ManagerConfig,\n    connect_opts: ConnectOpts,\n    accept_opts: AcceptOpts,\n    udp_expiry_duration: Option<Duration>,\n    udp_capacity: Option<usize>,\n    acl: Option<Arc<AccessControl>>,\n    ipv6_first: bool,\n    security: SecurityConfig,\n}\n\nimpl ManagerBuilder {\n    /// Create a new manager server builder from configuration\n    pub fn new(svr_cfg: ManagerConfig) -> Self {\n        Self::with_context(svr_cfg, Context::new_shared(ServerType::Server))\n    }\n\n    /// Create a new manager server builder with context and configuration\n    pub(crate) fn with_context(svr_cfg: ManagerConfig, context: SharedContext) -> Self {\n        Self {\n            context,\n            svr_cfg,\n            connect_opts: ConnectOpts::default(),\n            accept_opts: AcceptOpts::default(),\n            udp_expiry_duration: None,\n            udp_capacity: None,\n            acl: None,\n            ipv6_first: false,\n            security: SecurityConfig::default(),\n        }\n    }\n\n    /// Set `ConnectOpts`\n    pub fn set_connect_opts(&mut self, opts: ConnectOpts) {\n        self.connect_opts = opts;\n    }\n\n    /// Set `AcceptOpts`\n    pub fn set_accept_opts(&mut self, opts: AcceptOpts) {\n        self.accept_opts = opts;\n    }\n\n    /// Set UDP association's expiry duration\n    pub fn set_udp_expiry_duration(&mut self, d: Duration) {\n        self.udp_expiry_duration = Some(d);\n    }\n\n    /// Set total UDP associations to be kept in one server\n    pub fn set_udp_capacity(&mut self, c: usize) {\n        self.udp_capacity = Some(c);\n    }\n\n    /// Get the manager's configuration\n    pub fn config(&self) -> &ManagerConfig {\n        &self.svr_cfg\n    }\n\n    /// Get customized DNS resolver\n    pub fn set_dns_resolver(&mut self, resolver: Arc<DnsResolver>) {\n        let context = Arc::get_mut(&mut self.context).expect(\"cannot set DNS resolver on a shared context\");\n        context.set_dns_resolver(resolver)\n    }\n\n    /// Set access control list\n    pub fn set_acl(&mut self, acl: Arc<AccessControl>) {\n        self.acl = Some(acl);\n    }\n\n    /// Try to connect IPv6 addresses first if hostname could be resolved to both IPv4 and IPv6\n    pub fn set_ipv6_first(&mut self, ipv6_first: bool) {\n        self.ipv6_first = ipv6_first;\n    }\n\n    /// Set security config\n    pub fn set_security_config(&mut self, security: SecurityConfig) {\n        self.security = security;\n    }\n\n    /// Build the manager server instance\n    pub async fn build(self) -> io::Result<Manager> {\n        let listener = ManagerListener::bind(&self.context, &self.svr_cfg.addr).await?;\n        Ok(Manager {\n            context: self.context,\n            servers: Mutex::new(HashMap::new()),\n            svr_cfg: self.svr_cfg,\n            connect_opts: self.connect_opts,\n            accept_opts: self.accept_opts,\n            udp_expiry_duration: self.udp_expiry_duration,\n            udp_capacity: self.udp_capacity,\n            acl: self.acl,\n            ipv6_first: self.ipv6_first,\n            security: self.security,\n            listener,\n        })\n    }\n}\n\n/// Manager server\npub struct Manager {\n    context: SharedContext,\n    servers: Mutex<HashMap<u16, ServerInstance>>,\n    svr_cfg: ManagerConfig,\n    connect_opts: ConnectOpts,\n    accept_opts: AcceptOpts,\n    udp_expiry_duration: Option<Duration>,\n    udp_capacity: Option<usize>,\n    acl: Option<Arc<AccessControl>>,\n    ipv6_first: bool,\n    security: SecurityConfig,\n    listener: ManagerListener,\n}\n\nimpl Manager {\n    /// Manager server's configuration\n    pub fn manager_config(&self) -> &ManagerConfig {\n        &self.svr_cfg\n    }\n\n    /// Manager server's listen address\n    pub fn local_addr(&self) -> io::Result<ManagerSocketAddr> {\n        self.listener.local_addr()\n    }\n\n    /// Start serving\n    pub async fn run(mut self) -> io::Result<()> {\n        let local_addr = self.listener.local_addr()?;\n        info!(\"shadowsocks manager server listening on {}\", local_addr);\n\n        loop {\n            let (req, peer_addr) = match self.listener.recv_from().await {\n                Ok(r) => r,\n                Err(err) => {\n                    error!(\"manager recv_from error: {}\", err);\n                    continue;\n                }\n            };\n\n            trace!(\"received {:?} from {:?}\", req, peer_addr);\n\n            match req {\n                ManagerRequest::Add(ref req) => match self.handle_add(req).await {\n                    Ok(rsp) => {\n                        let _ = self.listener.send_to(&rsp, &peer_addr).await;\n                    }\n                    Err(err) => {\n                        error!(\"add server_port: {} failed, error: {}\", req.server_port, err);\n                        let rsp = ErrorResponse(err);\n                        let _ = self.listener.send_to(&rsp, &peer_addr).await;\n                    }\n                },\n                ManagerRequest::Remove(ref req) => {\n                    let rsp = self.handle_remove(req).await;\n                    let _ = self.listener.send_to(&rsp, &peer_addr).await;\n                }\n                ManagerRequest::List(..) => {\n                    let rsp = self.handle_list().await;\n                    let _ = self.listener.send_to(&rsp, &peer_addr).await;\n                }\n                ManagerRequest::Ping(..) => {\n                    let rsp = self.handle_ping().await;\n                    let _ = self.listener.send_to(&rsp, &peer_addr).await;\n                }\n                ManagerRequest::Stat(ref stat) => self.handle_stat(stat).await,\n            }\n        }\n    }\n\n    /// Add a server programmatically\n    pub async fn add_server(&self, svr_cfg: ServerConfig) {\n        match self.svr_cfg.server_mode {\n            ManagerServerMode::Builtin => self.add_server_builtin(svr_cfg).await,\n            #[cfg(unix)]\n            ManagerServerMode::Standalone => self.add_server_standalone(svr_cfg).await,\n        }\n    }\n\n    async fn add_server_builtin(&self, svr_cfg: ServerConfig) {\n        // Each server should use a separate Context, but shares\n        //\n        // * AccessControlList\n        // * DNS Resolver\n        let mut server_builder = ServerBuilder::new(svr_cfg.clone());\n\n        server_builder.set_connect_opts(self.connect_opts.clone());\n        server_builder.set_accept_opts(self.accept_opts.clone());\n        server_builder.set_dns_resolver(self.context.dns_resolver().clone());\n\n        if let Some(d) = self.udp_expiry_duration {\n            server_builder.set_udp_expiry_duration(d);\n        }\n\n        if let Some(c) = self.udp_capacity {\n            server_builder.set_udp_capacity(c);\n        }\n\n        if let Some(ref acl) = self.acl {\n            server_builder.set_acl(acl.clone());\n        }\n\n        if self.ipv6_first {\n            server_builder.set_ipv6_first(self.ipv6_first);\n        }\n\n        server_builder.set_security_config(&self.security);\n\n        let server_port = server_builder.server_config().addr().port();\n\n        let mut servers = self.servers.lock().await;\n        // Close existed server\n        if let Some(v) = servers.remove(&server_port) {\n            info!(\n                \"closed managed server listening on {}, inbound address {}\",\n                v.svr_cfg.addr(),\n                v.svr_cfg.tcp_external_addr()\n            );\n        }\n\n        let flow_stat = server_builder.flow_stat();\n        let server = match server_builder.build().await {\n            Ok(s) => s,\n            Err(err) => {\n                error!(\"failed to start server ({}), error: {}\", svr_cfg.addr(), err);\n                return;\n            }\n        };\n\n        let abortable = tokio::spawn(async move { server.run().await });\n\n        servers.insert(\n            server_port,\n            ServerInstance {\n                mode: ServerInstanceMode::Builtin { flow_stat, abortable },\n                svr_cfg,\n            },\n        );\n    }\n\n    #[cfg(unix)]\n    fn server_pid_path(&self, port: u16) -> PathBuf {\n        let pid_file_name = format!(\"shadowsocks-server-{port}.pid\");\n        let mut pid_path = self.svr_cfg.server_working_directory.clone();\n        pid_path.push(&pid_file_name);\n        pid_path\n    }\n\n    #[cfg(unix)]\n    fn server_config_path(&self, port: u16) -> PathBuf {\n        let config_file_name = format!(\"shadowsocks-server-{port}.json\");\n        let mut config_file_path = self.svr_cfg.server_working_directory.clone();\n        config_file_path.push(&config_file_name);\n        config_file_path\n    }\n\n    #[cfg(unix)]\n    fn kill_standalone_server(&self, port: u16) {\n        use log::{debug, warn};\n        use std::{\n            fs::{self, File},\n            io::Read,\n        };\n\n        let pid_path = self.server_pid_path(port);\n        if pid_path.exists()\n            && let Ok(mut pid_file) = File::open(&pid_path)\n        {\n            let mut pid_content = String::new();\n            if pid_file.read_to_string(&mut pid_content).is_ok() {\n                let pid_content = pid_content.trim();\n\n                match pid_content.parse::<libc::pid_t>() {\n                    Ok(pid) => {\n                        let _ = unsafe { libc::kill(pid, libc::SIGTERM) };\n                        debug!(\"killed standalone server port {}, pid: {}\", port, pid);\n                    }\n                    Err(..) => {\n                        warn!(\"failed to read pid from {}\", pid_path.display());\n                    }\n                }\n            }\n        }\n\n        let server_config_path = self.server_config_path(port);\n\n        let _ = fs::remove_file(pid_path);\n        let _ = fs::remove_file(server_config_path);\n    }\n\n    #[cfg(unix)]\n    async fn add_server_standalone(&self, svr_cfg: ServerConfig) {\n        use std::{\n            fs::{self, OpenOptions},\n            io::Write,\n        };\n\n        use tokio::process::Command;\n\n        use crate::config::{Config, ConfigType, ServerInstanceConfig};\n\n        // Lock the map first incase there are multiple requests to create one server instance\n        let mut servers = self.servers.lock().await;\n\n        // Check if working_directory exists\n        if !self.svr_cfg.server_working_directory.exists() {\n            fs::create_dir_all(&self.svr_cfg.server_working_directory).expect(\"create working_directory\");\n        }\n\n        let port = svr_cfg.addr().port();\n\n        // Check if there is already a running process\n        self.kill_standalone_server(port);\n\n        // Create configuration file for server\n        let config_file_path = self.server_config_path(port);\n        let pid_path = self.server_pid_path(port);\n\n        let server_instance = ServerInstanceConfig {\n            config: svr_cfg.clone(),\n            acl: None, // Set with --acl command line argument\n            #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n            outbound_fwmark: None,\n            #[cfg(target_os = \"freebsd\")]\n            outbound_user_cookie: None,\n            outbound_bind_addr: None,\n            outbound_bind_interface: None,\n            outbound_udp_allow_fragmentation: None,\n        };\n\n        let mut config = Config::new(ConfigType::Server);\n        config.server.push(server_instance);\n\n        trace!(\"created standalone server with config {:?}\", config);\n\n        let config_file_content = format!(\"{config}\");\n\n        match OpenOptions::new()\n            .write(true)\n            .create(true)\n            .truncate(true)\n            .open(&config_file_path)\n        {\n            Err(err) => {\n                error!(\n                    \"failed to open {} for writing, error: {}\",\n                    config_file_path.display(),\n                    err\n                );\n                return;\n            }\n            Ok(mut file) => {\n                if let Err(err) = file.write_all(config_file_content.as_bytes()) {\n                    error!(\"failed to write {}, error: {}\", config_file_path.display(), err);\n                    return;\n                }\n                let _ = file.sync_data();\n            }\n        }\n\n        let manager_addr = self.svr_cfg.addr.to_string();\n\n        // Start server process\n        let mut child_command = Command::new(&self.svr_cfg.server_program);\n        child_command\n            .arg(\"-c\")\n            .arg(&config_file_path)\n            .arg(\"--daemonize\")\n            .arg(\"--daemonize-pid\")\n            .arg(&pid_path)\n            .arg(\"--manager-addr\")\n            .arg(&manager_addr);\n\n        if let Some(ref acl) = self.acl {\n            child_command.arg(\"--acl\").arg(acl.file_path().to_str().expect(\"acl\"));\n        }\n\n        let child_result = child_command.kill_on_drop(false).spawn();\n\n        if let Err(err) = child_result {\n            error!(\n                \"failed to spawn process of {}, error: {}\",\n                self.svr_cfg.server_program, err\n            );\n            return;\n        }\n\n        // Greate. Record into the map\n        servers.insert(\n            port,\n            ServerInstance {\n                mode: ServerInstanceMode::Standalone { flow_stat: 0 },\n                svr_cfg,\n            },\n        );\n    }\n\n    async fn handle_add(&self, req: &AddRequest) -> io::Result<AddResponse> {\n        let addr = match self.svr_cfg.server_host {\n            ManagerServerHost::Domain(ref dname) => ServerAddr::DomainName(dname.clone(), req.server_port),\n            ManagerServerHost::Ip(ip) => ServerAddr::SocketAddr(SocketAddr::new(ip, req.server_port)),\n        };\n\n        let method = match req.method {\n            Some(ref m) => match m.parse::<CipherKind>() {\n                Ok(method) => method,\n                Err(..) => {\n                    error!(\"unrecognized method \\\"{}\\\", req: {:?}\", m, req);\n\n                    let err = format!(\"unrecognized method \\\"{m}\\\"\");\n                    return Ok(AddResponse(err));\n                }\n            },\n            None => match self.svr_cfg.method {\n                Some(m) => m,\n                None => {\n                    cfg_if! {\n                        if #[cfg(feature = \"aead-cipher\")] {\n                            // If AEAD cipher is enabled, use chacha20-poly1305 as default method\n                            // NOTE: This behavior is defined in shadowsocks-libev's `manager.c`\n                            CipherKind::CHACHA20_POLY1305\n                        } else {\n                            // AEAD cipher is disabled, default method is not defined in any standard or implementations.\n                            // TODO: Complete this after discussion.\n                            return Ok(AddResponse(\"method is required\".to_string()));\n                        }\n                    }\n                }\n            },\n        };\n\n        let mut svr_cfg = match ServerConfig::new(addr, req.password.clone(), method) {\n            Ok(svr_cfg) => svr_cfg,\n            Err(err) => {\n                error!(\"failed to create ServerConfig, error: {}\", err);\n                return Ok(AddResponse(\"invalid server\".to_string()));\n            }\n        };\n\n        if let Some(ref plugin) = req.plugin {\n            let p = PluginConfig {\n                plugin: plugin.clone(),\n                plugin_opts: req.plugin_opts.clone(),\n                plugin_args: Vec::new(),\n                plugin_mode: match req.plugin_mode {\n                    None => Mode::TcpOnly,\n                    Some(ref mode) => match mode.parse::<Mode>() {\n                        Ok(m) => m,\n                        Err(..) => {\n                            error!(\"unrecognized plugin_mode \\\"{}\\\", req: {:?}\", mode, req);\n\n                            let err = format!(\"unrecognized plugin_mode \\\"{}\\\"\", mode);\n                            return Ok(AddResponse(err));\n                        }\n                    },\n                },\n            };\n            svr_cfg.set_plugin(p);\n        } else if let Some(ref plugin) = self.svr_cfg.plugin {\n            svr_cfg.set_plugin(plugin.clone());\n        }\n\n        let mode = match req.mode {\n            None => None,\n            Some(ref mode) => match mode.parse::<Mode>() {\n                Ok(m) => Some(m),\n                Err(..) => {\n                    error!(\"unrecognized mode \\\"{}\\\", req: {:?}\", mode, req);\n\n                    let err = format!(\"unrecognized mode \\\"{mode}\\\"\");\n                    return Ok(AddResponse(err));\n                }\n            },\n        };\n\n        svr_cfg.set_mode(mode.unwrap_or(self.svr_cfg.mode));\n\n        if let Some(ref users) = req.users {\n            let mut user_manager = ServerUserManager::new();\n\n            for user in users.iter() {\n                let user = match ServerUser::with_encoded_key(&user.name, &user.password) {\n                    Ok(u) => u,\n                    Err(..) => {\n                        error!(\n                            \"users[].password must be encoded with base64, but found: {}\",\n                            user.password\n                        );\n\n                        return Err(io::Error::other(\"users[].password must be encoded with base64\"));\n                    }\n                };\n\n                user_manager.add_user(user);\n            }\n\n            svr_cfg.set_user_manager(user_manager);\n        }\n\n        self.add_server(svr_cfg).await;\n\n        Ok(AddResponse(\"ok\".to_owned()))\n    }\n\n    async fn handle_remove(&self, req: &RemoveRequest) -> RemoveResponse {\n        let mut servers = self.servers.lock().await;\n        servers.remove(&req.server_port);\n\n        #[cfg(unix)]\n        if self.svr_cfg.server_mode == ManagerServerMode::Standalone {\n            self.kill_standalone_server(req.server_port);\n        }\n\n        RemoveResponse(\"ok\".to_owned())\n    }\n\n    async fn handle_list(&self) -> ListResponse {\n        let instances = self.servers.lock().await;\n\n        let mut servers = Vec::new();\n\n        for (_, server) in instances.iter() {\n            let svr_cfg = &server.svr_cfg;\n\n            let mut users = None;\n            if let Some(user_manager) = server.svr_cfg.user_manager() {\n                let mut vu = Vec::with_capacity(user_manager.user_count());\n\n                for user in user_manager.users_iter() {\n                    vu.push(ServerUserConfig {\n                        name: user.name().to_owned(),\n                        password: user.encoded_key(),\n                    });\n                }\n\n                users = Some(vu);\n            }\n\n            let sc = protocol::ServerConfig {\n                server_port: svr_cfg.addr().port(),\n                password: svr_cfg.password().to_owned(),\n                method: None,\n                no_delay: None,\n                plugin: None,\n                plugin_opts: None,\n                plugin_mode: None,\n                mode: None,\n                users,\n            };\n            servers.push(sc);\n        }\n\n        ListResponse { servers }\n    }\n\n    async fn handle_ping(&self) -> PingResponse {\n        let instances = self.servers.lock().await;\n\n        let mut stat = HashMap::new();\n        for (port, server) in instances.iter() {\n            stat.insert(*port, server.flow_stat());\n        }\n\n        PingResponse { stat }\n    }\n\n    #[cfg(not(unix))]\n    async fn handle_stat(&self, _: &StatRequest) {}\n\n    #[cfg(unix)]\n    async fn handle_stat(&self, stat: &StatRequest) {\n        use log::warn;\n        use std::collections::hash_map::Entry;\n\n        use crate::config::{Config, ConfigType};\n\n        // `stat` is only supported for Standalone mode\n        if self.svr_cfg.server_mode != ManagerServerMode::Standalone {\n            return;\n        }\n\n        let mut instances = self.servers.lock().await;\n\n        // Get or create a new instance then record the data statistic numbers\n        for (port, flow) in stat.stat.iter() {\n            match instances.entry(*port) {\n                Entry::Occupied(mut occ) => match occ.get_mut().mode {\n                    ServerInstanceMode::Builtin { .. } => {\n                        error!(\"received `stat` for port {} that is running a builtin server\", *port)\n                    }\n                    ServerInstanceMode::Standalone { ref mut flow_stat } => *flow_stat = *flow,\n                },\n                Entry::Vacant(vac) => {\n                    // Read config from file\n\n                    let server_config_path = self.server_config_path(*port);\n                    if !server_config_path.exists() {\n                        warn!(\n                            \"received `stat` for port {} but file {} doesn't exist\",\n                            *port,\n                            server_config_path.display()\n                        );\n                        continue;\n                    }\n\n                    match Config::load_from_file(&server_config_path, ConfigType::Server) {\n                        Err(err) => {\n                            error!(\n                                \"failed to load {} for server port {}, error: {}\",\n                                server_config_path.display(),\n                                *port,\n                                err\n                            );\n                            continue;\n                        }\n                        Ok(config) => {\n                            trace!(\n                                \"loaded {} for server port {}, {:?}\",\n                                server_config_path.display(),\n                                *port,\n                                config\n                            );\n\n                            if config.server.len() != 1 {\n                                error!(\n                                    \"invalid config {} for server port {}, containing {} servers\",\n                                    server_config_path.display(),\n                                    *port,\n                                    config.server.len()\n                                );\n                                continue;\n                            }\n\n                            let svr_cfg = config.server[0].config.clone();\n\n                            vac.insert(ServerInstance {\n                                mode: ServerInstanceMode::Standalone { flow_stat: *flow },\n                                svr_cfg,\n                            });\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/net/flow.rs",
    "content": "//! Server flow statistic\n\nuse std::sync::atomic::Ordering;\n\n#[cfg(target_has_atomic = \"64\")]\ntype FlowCounter = std::sync::atomic::AtomicU64;\n#[cfg(not(target_has_atomic = \"64\"))]\ntype FlowCounter = std::sync::atomic::AtomicU32;\n\n/// Connection flow statistic\npub struct FlowStat {\n    tx: FlowCounter,\n    rx: FlowCounter,\n}\n\nimpl Default for FlowStat {\n    fn default() -> Self {\n        Self {\n            tx: FlowCounter::new(0),\n            rx: FlowCounter::new(0),\n        }\n    }\n}\n\nimpl FlowStat {\n    /// Create an empty flow statistic\n    pub fn new() -> Self {\n        Self::default()\n    }\n\n    /// Transmitted bytes count\n    pub fn tx(&self) -> u64 {\n        self.tx.load(Ordering::Relaxed) as _\n    }\n\n    /// Increase transmitted bytes\n    pub fn incr_tx(&self, n: u64) {\n        self.tx.fetch_add(n as _, Ordering::AcqRel);\n    }\n\n    /// Received bytes count\n    pub fn rx(&self) -> u64 {\n        self.rx.load(Ordering::Relaxed) as _\n    }\n\n    /// Increase received bytes\n    pub fn incr_rx(&self, n: u64) {\n        self.rx.fetch_add(n as _, Ordering::AcqRel);\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/net/launch_activate_socket.rs",
    "content": "//! macOS launch activate socket\n//!\n//! <https://developer.apple.com/documentation/xpc/1505523-launch_activate_socket>\n//! <https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html>\n\nuse std::{\n    io,\n    net::{TcpListener, UdpSocket},\n    os::unix::io::FromRawFd,\n};\n\nuse log::debug;\n\nuse crate::sys::get_launch_activate_socket;\n\n/// Get a macOS launch active socket as a `TcpListener`\npub fn get_launch_activate_tcp_listener(name: &str, nonblock: bool) -> io::Result<TcpListener> {\n    let fd = get_launch_activate_socket(name)?;\n    debug!(\"created TCP listener from launch activate socket {}\", fd);\n    let listener = unsafe { TcpListener::from_raw_fd(fd) };\n    if nonblock {\n        listener.set_nonblocking(true)?;\n    }\n    Ok(listener)\n}\n\n/// Get a macOS launch activate socket as a `UdpSocket`\npub fn get_launch_activate_udp_socket(name: &str, nonblock: bool) -> io::Result<UdpSocket> {\n    let fd = get_launch_activate_socket(name)?;\n    debug!(\"created UDP socket from launch activate socket {}\", fd);\n    let socket = unsafe { UdpSocket::from_raw_fd(fd) };\n    if nonblock {\n        socket.set_nonblocking(true)?;\n    }\n    Ok(socket)\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/net/mod.rs",
    "content": "//! Shadowsocks Service Network Utilities\n\npub use self::{flow::FlowStat, mon_socket::MonProxySocket, mon_stream::MonProxyStream};\n\npub mod flow;\n#[cfg(target_os = \"macos\")]\npub mod launch_activate_socket;\npub mod mon_socket;\npub mod mon_stream;\npub mod packet_window;\npub mod utils;\n\n/// Packet size for all UDP associations' send queue\npub const UDP_ASSOCIATION_SEND_CHANNEL_SIZE: usize = 1024;\n\n/// Keep-alive channel size for UDP associations' manager\npub const UDP_ASSOCIATION_KEEP_ALIVE_CHANNEL_SIZE: usize = 64;\n"
  },
  {
    "path": "crates/shadowsocks-service/src/net/mon_socket.rs",
    "content": "//! UDP socket with flow statistic monitored\n\nuse std::{io, net::SocketAddr, sync::Arc};\n\nuse shadowsocks::{\n    ProxySocket,\n    relay::{\n        socks5::Address,\n        udprelay::{DatagramReceive, DatagramSend, options::UdpSocketControlData},\n    },\n};\n\nuse super::flow::FlowStat;\n\n/// Monitored `ProxySocket`\npub struct MonProxySocket<S> {\n    socket: ProxySocket<S>,\n    flow_stat: Arc<FlowStat>,\n}\n\nimpl<S> MonProxySocket<S> {\n    /// Create a new socket with flow monitor\n    pub fn from_socket(socket: ProxySocket<S>, flow_stat: Arc<FlowStat>) -> Self {\n        Self { socket, flow_stat }\n    }\n\n    /// Get the underlying `ProxySocket<S>` immutable reference\n    #[inline]\n    pub fn get_ref(&self) -> &ProxySocket<S> {\n        &self.socket\n    }\n\n    /// Get the flow statistic data\n    #[inline]\n    pub fn flow_stat(&self) -> &FlowStat {\n        &self.flow_stat\n    }\n}\n\nimpl<S> MonProxySocket<S>\nwhere\n    S: DatagramSend,\n{\n    /// Send a UDP packet to addr through proxy\n    #[inline]\n    pub async fn send(&self, addr: &Address, payload: &[u8]) -> io::Result<()> {\n        let n = self.socket.send(addr, payload).await?;\n        self.flow_stat.incr_tx(n as u64);\n\n        Ok(())\n    }\n\n    /// Send a UDP packet to addr through proxy\n    #[inline]\n    pub async fn send_with_ctrl(\n        &self,\n        addr: &Address,\n        control: &UdpSocketControlData,\n        payload: &[u8],\n    ) -> io::Result<()> {\n        let n = self.socket.send_with_ctrl(addr, control, payload).await?;\n        self.flow_stat.incr_tx(n as u64);\n\n        Ok(())\n    }\n\n    /// Send a UDP packet to target from proxy\n    #[inline]\n    pub async fn send_to(&self, target: SocketAddr, addr: &Address, payload: &[u8]) -> io::Result<()> {\n        let n = self.socket.send_to(target, addr, payload).await?;\n        self.flow_stat.incr_tx(n as u64);\n\n        Ok(())\n    }\n\n    /// Send a UDP packet to target from proxy\n    #[inline]\n    pub async fn send_to_with_ctrl(\n        &self,\n        target: SocketAddr,\n        addr: &Address,\n        control: &UdpSocketControlData,\n        payload: &[u8],\n    ) -> io::Result<()> {\n        let n = self.socket.send_to_with_ctrl(target, addr, control, payload).await?;\n        self.flow_stat.incr_tx(n as u64);\n\n        Ok(())\n    }\n}\n\nimpl<S> MonProxySocket<S>\nwhere\n    S: DatagramReceive,\n{\n    /// Receive packet from Shadowsocks' UDP server\n    ///\n    /// This function will use `recv_buf` to store intermediate data, so it has to be big enough to store the whole shadowsocks' packet\n    ///\n    /// It is recommended to allocate a buffer to have at least 65536 bytes.\n    #[inline]\n    pub async fn recv(&self, recv_buf: &mut [u8]) -> io::Result<(usize, Address)> {\n        let (n, addr, recv_n) = self.socket.recv(recv_buf).await?;\n        self.flow_stat.incr_rx(recv_n as u64);\n\n        Ok((n, addr))\n    }\n\n    /// Receive packet from Shadowsocks' UDP server\n    ///\n    /// This function will use `recv_buf` to store intermediate data, so it has to be big enough to store the whole shadowsocks' packet\n    ///\n    /// It is recommended to allocate a buffer to have at least 65536 bytes.\n    #[inline]\n    pub async fn recv_with_ctrl(\n        &self,\n        recv_buf: &mut [u8],\n    ) -> io::Result<(usize, Address, Option<UdpSocketControlData>)> {\n        let (n, addr, recv_n, control) = self.socket.recv_with_ctrl(recv_buf).await?;\n        self.flow_stat.incr_rx(recv_n as u64);\n\n        Ok((n, addr, control))\n    }\n\n    /// Receive packet from Shadowsocks' UDP server\n    ///\n    /// This function will use `recv_buf` to store intermediate data, so it has to be big enough to store the whole shadowsocks' packet\n    ///\n    /// It is recommended to allocate a buffer to have at least 65536 bytes.\n    #[inline]\n    pub async fn recv_from(&self, recv_buf: &mut [u8]) -> io::Result<(usize, SocketAddr, Address)> {\n        let (n, peer_addr, addr, recv_n) = self.socket.recv_from(recv_buf).await?;\n        self.flow_stat.incr_rx(recv_n as u64);\n\n        Ok((n, peer_addr, addr))\n    }\n\n    /// Receive packet from Shadowsocks' UDP server\n    ///\n    /// This function will use `recv_buf` to store intermediate data, so it has to be big enough to store the whole shadowsocks' packet\n    ///\n    /// It is recommended to allocate a buffer to have at least 65536 bytes.\n    #[inline]\n    pub async fn recv_from_with_ctrl(\n        &self,\n        recv_buf: &mut [u8],\n    ) -> io::Result<(usize, SocketAddr, Address, Option<UdpSocketControlData>)> {\n        let (n, peer_addr, addr, recv_n, control) = self.socket.recv_from_with_ctrl(recv_buf).await?;\n        self.flow_stat.incr_rx(recv_n as u64);\n\n        Ok((n, peer_addr, addr, control))\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/net/mon_stream.rs",
    "content": "//! TCP stream with flow statistic monitored\n\nuse std::{\n    io::{self, IoSlice},\n    pin::Pin,\n    sync::Arc,\n    task::{Context, Poll},\n};\n\nuse pin_project::pin_project;\nuse tokio::io::{AsyncRead, AsyncWrite, ReadBuf};\n\nuse super::flow::FlowStat;\n\n/// Monitored `ProxyStream`\n#[pin_project]\npub struct MonProxyStream<S> {\n    #[pin]\n    stream: S,\n    flow_stat: Arc<FlowStat>,\n}\n\nimpl<S> MonProxyStream<S> {\n    #[inline]\n    pub fn from_stream(stream: S, flow_stat: Arc<FlowStat>) -> Self {\n        Self { stream, flow_stat }\n    }\n\n    #[inline]\n    pub fn get_ref(&self) -> &S {\n        &self.stream\n    }\n\n    #[inline]\n    pub fn get_mut(&mut self) -> &mut S {\n        &mut self.stream\n    }\n\n    #[inline]\n    pub fn into_inner(self) -> S {\n        self.stream\n    }\n}\n\nimpl<S> AsyncRead for MonProxyStream<S>\nwhere\n    S: AsyncRead + Unpin,\n{\n    #[inline]\n    fn poll_read(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>) -> Poll<io::Result<()>> {\n        let this = self.project();\n        match this.stream.poll_read(cx, buf) {\n            Poll::Pending => Poll::Pending,\n            Poll::Ready(Ok(())) => {\n                let n = buf.filled().len();\n                this.flow_stat.incr_rx(n as u64);\n                Poll::Ready(Ok(()))\n            }\n            Poll::Ready(Err(err)) => Poll::Ready(Err(err)),\n        }\n    }\n}\n\nimpl<S> AsyncWrite for MonProxyStream<S>\nwhere\n    S: AsyncWrite + Unpin,\n{\n    #[inline]\n    fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<io::Result<usize>> {\n        let this = self.project();\n        match this.stream.poll_write(cx, buf) {\n            Poll::Pending => Poll::Pending,\n            Poll::Ready(Ok(n)) => {\n                this.flow_stat.incr_tx(n as u64);\n                Poll::Ready(Ok(n))\n            }\n            Poll::Ready(Err(err)) => Poll::Ready(Err(err)),\n        }\n    }\n\n    #[inline]\n    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {\n        self.project().stream.poll_flush(cx)\n    }\n\n    #[inline]\n    fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {\n        self.project().stream.poll_shutdown(cx)\n    }\n\n    #[inline]\n    fn poll_write_vectored(\n        self: Pin<&mut Self>,\n        cx: &mut Context<'_>,\n        bufs: &[IoSlice<'_>],\n    ) -> Poll<io::Result<usize>> {\n        self.project().stream.poll_write_vectored(cx, bufs)\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/net/packet_window.rs",
    "content": "// SPDX-License-Identifier: MIT\n//\n// Copyright (C) 2017-2021 WireGuard LLC. All Rights Reserved.\n\n//! Packet window\n//!\n//! https://github.com/WireGuard/wireguard-go/blob/master/replay/replay.go\n\nconst BLOCK_BIT_LOG: u64 = 6; // 1<<6 == 64 bits\nconst BLOCK_BITS: u64 = 1 << BLOCK_BIT_LOG; // must be power of 2\nconst RING_BLOCKS: u64 = 1 << 7; // must be power of 2\nconst WINDOW_SIZE: u64 = (RING_BLOCKS - 1) * BLOCK_BITS;\nconst BLOCK_MASK: u64 = RING_BLOCKS - 1;\nconst BIT_MASK: u64 = BLOCK_BITS - 1;\n\n/// Packet window for checking `packet_id` is in the sliding window\n#[derive(Debug, Clone)]\npub struct PacketWindowFilter {\n    last_packet_id: u64,\n    packet_ring: [u64; RING_BLOCKS as usize],\n}\n\nimpl Default for PacketWindowFilter {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nimpl PacketWindowFilter {\n    /// Create an empty filter\n    pub fn new() -> Self {\n        Self {\n            last_packet_id: 0,\n            packet_ring: [0u64; RING_BLOCKS as usize],\n        }\n    }\n\n    /// Reset filter to the initial state\n    pub fn reset(&mut self) {\n        self.last_packet_id = 0;\n        self.packet_ring[0] = 0;\n    }\n\n    /// Check and remember the `packet_id`\n    ///\n    /// Overlimit `packet_id >= limit` are always rejected\n    pub fn validate_packet_id(&mut self, packet_id: u64, limit: u64) -> bool {\n        if packet_id >= limit {\n            return false;\n        }\n\n        let mut index_block = packet_id >> BLOCK_BIT_LOG;\n        if packet_id > self.last_packet_id {\n            // Move the window forward\n\n            let current = self.last_packet_id >> BLOCK_BIT_LOG;\n            let mut diff = index_block - current;\n            if diff > RING_BLOCKS {\n                // Clear the whole filter\n                diff = RING_BLOCKS;\n            }\n            for d in 1..=diff {\n                let i = current + d;\n                self.packet_ring[(i & BLOCK_MASK) as usize] = 0;\n            }\n            self.last_packet_id = packet_id;\n        } else if self.last_packet_id - packet_id > WINDOW_SIZE {\n            // Behind the current window\n            return false;\n        }\n\n        // Check and set bit\n        index_block &= BLOCK_MASK;\n        let index_bit = packet_id & BIT_MASK;\n        let old = self.packet_ring[index_block as usize];\n        let new = old | (1 << index_bit);\n        self.packet_ring[index_block as usize] = new;\n        old != new\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n\n    use std::cell::RefCell;\n\n    #[test]\n    fn test_packet_window() {\n        const REJECT_AFTER_MESSAGES: u64 = u64::MAX - (1u64 << 13);\n\n        let filter = RefCell::new(PacketWindowFilter::new());\n\n        let test_number = RefCell::new(0);\n        #[allow(non_snake_case)]\n        let T = |n: u64, expected: bool| {\n            *(test_number.borrow_mut()) += 1;\n            if filter.borrow_mut().validate_packet_id(n, REJECT_AFTER_MESSAGES) != expected {\n                panic!(\"Test {} failed, {} {}\", test_number.borrow(), n, expected);\n            }\n        };\n\n        const T_LIM: u64 = WINDOW_SIZE + 1;\n\n        T(0, true); // 1\n        T(1, true); // 2\n        T(1, false); // 3\n        T(9, true); // 4\n        T(8, true); // 5\n        T(7, true); // 6\n        T(7, false); // 7\n        T(T_LIM, true); // 8\n        T(T_LIM - 1, true); // 9\n        T(T_LIM - 1, false); // 10\n        T(T_LIM - 2, true); // 11\n        T(2, true); // 12\n        T(2, false); // 13\n        T(T_LIM + 16, true); // 14\n        T(3, false); // 15\n        T(T_LIM + 16, false); // 16\n        T(T_LIM * 4, true); // 17\n        T(T_LIM * 4 - (T_LIM - 1), true); // 18\n        T(10, false); // 19\n        T(T_LIM * 4 - T_LIM, false); // 20\n        T(T_LIM * 4 - (T_LIM + 1), false); // 21\n        T(T_LIM * 4 - (T_LIM - 2), true); // 22\n        T(T_LIM * 4 + 1 - T_LIM, false); // 23\n        T(0, false); // 24\n        T(REJECT_AFTER_MESSAGES, false); // 25\n        T(REJECT_AFTER_MESSAGES - 1, true); // 26\n        T(REJECT_AFTER_MESSAGES, false); // 27\n        T(REJECT_AFTER_MESSAGES - 1, false); // 28\n        T(REJECT_AFTER_MESSAGES - 2, true); // 29\n        T(REJECT_AFTER_MESSAGES + 1, false); // 30\n        T(REJECT_AFTER_MESSAGES + 2, false); // 31\n        T(REJECT_AFTER_MESSAGES - 2, false); // 32\n        T(REJECT_AFTER_MESSAGES - 3, true); // 33\n        T(0, false); // 34\n\n        println!(\"Bulk test 1\");\n        filter.borrow_mut().reset();\n        *(test_number.borrow_mut()) = 0;\n        for i in 1..=WINDOW_SIZE {\n            T(i, true);\n        }\n        T(0, true);\n        T(0, false);\n\n        println!(\"Bulk test 2\");\n        filter.borrow_mut().reset();\n        *(test_number.borrow_mut()) = 0;\n        for i in 2..=WINDOW_SIZE + 1 {\n            T(i, true);\n        }\n        T(1, true);\n        T(0, false);\n\n        println!(\"Bulk test 3\");\n        filter.borrow_mut().reset();\n        *(test_number.borrow_mut()) = 0;\n        for i in (1..=WINDOW_SIZE + 1).rev() {\n            T(i, true);\n        }\n\n        println!(\"Bulk test 4\");\n        filter.borrow_mut().reset();\n        *(test_number.borrow_mut()) = 0;\n        for i in (2..=WINDOW_SIZE + 2).rev() {\n            T(i, true);\n        }\n        T(0, false);\n\n        println!(\"Bulk test 5\");\n        filter.borrow_mut().reset();\n        *(test_number.borrow_mut()) = 0;\n        for i in (1..=WINDOW_SIZE).rev() {\n            T(i, true);\n        }\n        T(WINDOW_SIZE + 1, true);\n        T(0, false);\n\n        println!(\"Bulk test 6\");\n        filter.borrow_mut().reset();\n        *(test_number.borrow_mut()) = 0;\n        for i in (1..=WINDOW_SIZE).rev() {\n            T(i, true);\n        }\n        T(0, true);\n        T(WINDOW_SIZE + 1, true);\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/net/utils.rs",
    "content": "//! Network Utilities\n\nuse std::{\n    io,\n    net::{Ipv4Addr, Ipv6Addr},\n};\n\nuse tokio::io::{AsyncRead, AsyncReadExt};\n\n/// Consumes all data from `reader` and throws away until EOF\npub async fn ignore_until_end<R>(reader: &mut R) -> io::Result<()>\nwhere\n    R: AsyncRead + Unpin,\n{\n    let mut buffer = [0u8; 2048];\n\n    loop {\n        let n = reader.read(&mut buffer).await?;\n        if n == 0 {\n            break;\n        }\n    }\n\n    Ok(())\n}\n\n/// Helper function for converting IPv4 mapped IPv6 address\n///\n/// This is the same as `Ipv6Addr::to_ipv4_mapped`, but it is still unstable in the current libstd\n#[allow(unused)]\npub(crate) fn to_ipv4_mapped(ipv6: &Ipv6Addr) -> Option<Ipv4Addr> {\n    match ipv6.octets() {\n        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, a, b, c, d] => Some(Ipv4Addr::new(a, b, c, d)),\n        _ => None,\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/server/context.rs",
    "content": "//! Shadowsocks Local Server Context\n\nuse std::{net::SocketAddr, sync::Arc};\n\nuse shadowsocks::{\n    config::ServerType,\n    context::{Context, SharedContext},\n    dns_resolver::DnsResolver,\n    net::ConnectOpts,\n    relay::Address,\n};\n\nuse crate::{acl::AccessControl, config::SecurityConfig, net::FlowStat};\n\n/// Server Service Context\n#[derive(Clone)]\npub struct ServiceContext {\n    context: SharedContext,\n    connect_opts: ConnectOpts,\n\n    // Access Control\n    acl: Option<Arc<AccessControl>>,\n\n    // Flow statistic report\n    flow_stat: Arc<FlowStat>,\n}\n\nimpl Default for ServiceContext {\n    fn default() -> Self {\n        Self {\n            context: Context::new_shared(ServerType::Server),\n            connect_opts: ConnectOpts::default(),\n            acl: None,\n            flow_stat: Arc::new(FlowStat::new()),\n        }\n    }\n}\n\nimpl ServiceContext {\n    /// Create a new `ServiceContext`\n    pub fn new() -> Self {\n        Self::default()\n    }\n\n    /// Get cloned `shadowsocks` Context\n    pub fn context(&self) -> SharedContext {\n        self.context.clone()\n    }\n\n    /// Get `shadowsocks` Context reference\n    pub fn context_ref(&self) -> &Context {\n        self.context.as_ref()\n    }\n\n    /// Set `ConnectOpts`\n    pub fn set_connect_opts(&mut self, connect_opts: ConnectOpts) {\n        self.connect_opts = connect_opts;\n    }\n\n    /// Get `ConnectOpts` reference\n    pub fn connect_opts_ref(&self) -> &ConnectOpts {\n        &self.connect_opts\n    }\n\n    /// Set Access Control List\n    pub fn set_acl(&mut self, acl: Arc<AccessControl>) {\n        self.acl = Some(acl);\n    }\n\n    /// Get Access Control List reference\n    pub fn acl(&self) -> Option<&AccessControl> {\n        self.acl.as_deref()\n    }\n\n    /// Get cloned flow statistic\n    pub fn flow_stat(&self) -> Arc<FlowStat> {\n        self.flow_stat.clone()\n    }\n\n    /// Get flow statistic reference\n    pub fn flow_stat_ref(&self) -> &FlowStat {\n        self.flow_stat.as_ref()\n    }\n\n    /// Set customized DNS resolver\n    pub fn set_dns_resolver(&mut self, resolver: Arc<DnsResolver>) {\n        let context = Arc::get_mut(&mut self.context).expect(\"cannot set DNS resolver on a shared context\");\n        context.set_dns_resolver(resolver)\n    }\n\n    /// Get reference of DNS resolver\n    pub fn dns_resolver(&self) -> &DnsResolver {\n        self.context.dns_resolver()\n    }\n\n    /// Check if target should be bypassed\n    pub async fn check_outbound_blocked(&self, addr: &Address) -> bool {\n        match self.acl {\n            None => false,\n            Some(ref acl) => acl.check_outbound_blocked(&self.context, addr).await,\n        }\n    }\n\n    /// Check if client should be blocked\n    pub fn check_client_blocked(&self, addr: &SocketAddr) -> bool {\n        match self.acl {\n            None => false,\n            Some(ref acl) => acl.check_client_blocked(addr),\n        }\n    }\n\n    /// Try to connect IPv6 addresses first if hostname could be resolved to both IPv4 and IPv6\n    pub fn set_ipv6_first(&mut self, ipv6_first: bool) {\n        let context = Arc::get_mut(&mut self.context).expect(\"cannot set ipv6_first on a shared context\");\n        context.set_ipv6_first(ipv6_first);\n    }\n\n    /// Set security config\n    pub fn set_security_config(&mut self, security: &SecurityConfig) {\n        let context = Arc::get_mut(&mut self.context).expect(\"cannot set security on a shared context\");\n        context.set_replay_attack_policy(security.replay_attack.policy);\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/server/mod.rs",
    "content": "//! Shadowsocks server\n\nuse std::{io, net::SocketAddr, sync::Arc, time::Duration};\n\nuse futures::future;\nuse log::trace;\nuse shadowsocks::net::{AcceptOpts, ConnectOpts, UdpSocketOpts};\n\nuse crate::{\n    config::{Config, ConfigType},\n    dns::build_dns_resolver,\n    utils::ServerHandle,\n};\n\npub use self::{\n    server::{Server, ServerBuilder},\n    tcprelay::TcpServer,\n    udprelay::UdpServer,\n};\n\npub mod context;\n#[allow(clippy::module_inception)]\npub mod server;\nmod tcprelay;\nmod udprelay;\n\n/// Default TCP Keep Alive timeout\n///\n/// This is borrowed from Go's `net` library's default setting\npub(crate) const SERVER_DEFAULT_KEEPALIVE_TIMEOUT: Duration = Duration::from_secs(15);\n\n/// Starts a shadowsocks server\npub async fn run(config: Config) -> io::Result<()> {\n    assert_eq!(config.config_type, ConfigType::Server);\n    assert!(!config.server.is_empty());\n\n    trace!(\"{:?}\", config);\n\n    // Warning for Stream Ciphers\n    #[cfg(feature = \"stream-cipher\")]\n    for inst in config.server.iter() {\n        let server = &inst.config;\n\n        if server.method().is_stream() {\n            log::warn!(\n                \"stream cipher {} for server {} have inherent weaknesses (see discussion in https://github.com/shadowsocks/shadowsocks-org/issues/36). \\\n                    DO NOT USE. It will be removed in the future.\",\n                server.method(),\n                server.addr()\n            );\n        }\n    }\n\n    #[cfg(all(unix, not(target_os = \"android\")))]\n    if let Some(nofile) = config.nofile {\n        use crate::sys::set_nofile;\n        if let Err(err) = set_nofile(nofile) {\n            log::warn!(\"set_nofile {} failed, error: {}\", nofile, err);\n        }\n    }\n\n    let mut servers = Vec::new();\n\n    let mut connect_opts = ConnectOpts {\n        #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n        fwmark: config.outbound_fwmark,\n        #[cfg(target_os = \"freebsd\")]\n        user_cookie: config.outbound_user_cookie,\n\n        #[cfg(target_os = \"android\")]\n        vpn_protect_path: config.outbound_vpn_protect_path,\n\n        bind_local_addr: config.outbound_bind_addr.map(|ip| SocketAddr::new(ip, 0)),\n        bind_interface: config.outbound_bind_interface,\n\n        udp: UdpSocketOpts {\n            allow_fragmentation: config.outbound_udp_allow_fragmentation,\n\n            ..Default::default()\n        },\n\n        ..Default::default()\n    };\n\n    connect_opts.tcp.send_buffer_size = config.outbound_send_buffer_size;\n    connect_opts.tcp.recv_buffer_size = config.outbound_recv_buffer_size;\n    connect_opts.tcp.nodelay = config.no_delay;\n    connect_opts.tcp.fastopen = config.fast_open;\n    connect_opts.tcp.keepalive = config.keep_alive.or(Some(SERVER_DEFAULT_KEEPALIVE_TIMEOUT));\n    connect_opts.tcp.mptcp = config.mptcp;\n    connect_opts.udp.mtu = config.udp_mtu;\n\n    let mut accept_opts = AcceptOpts {\n        ipv6_only: config.ipv6_only,\n        ..Default::default()\n    };\n    accept_opts.tcp.send_buffer_size = config.inbound_send_buffer_size;\n    accept_opts.tcp.recv_buffer_size = config.inbound_recv_buffer_size;\n    accept_opts.tcp.nodelay = config.no_delay;\n    accept_opts.tcp.fastopen = config.fast_open;\n    accept_opts.tcp.keepalive = config.keep_alive.or(Some(SERVER_DEFAULT_KEEPALIVE_TIMEOUT));\n    accept_opts.tcp.mptcp = config.mptcp;\n    accept_opts.udp.mtu = config.udp_mtu;\n\n    let resolver = build_dns_resolver(config.dns, config.ipv6_first, config.dns_cache_size, &connect_opts)\n        .await\n        .map(Arc::new);\n\n    let acl = config.acl.map(Arc::new);\n\n    for inst in config.server {\n        let svr_cfg = inst.config;\n        let mut server_builder = ServerBuilder::new(svr_cfg);\n\n        if let Some(ref r) = resolver {\n            server_builder.set_dns_resolver(r.clone());\n        }\n\n        let mut connect_opts = connect_opts.clone();\n        let accept_opts = accept_opts.clone();\n\n        #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n        if let Some(fwmark) = inst.outbound_fwmark {\n            connect_opts.fwmark = Some(fwmark);\n        }\n\n        #[cfg(target_os = \"freebsd\")]\n        if let Some(user_cookie) = inst.outbound_user_cookie {\n            connect_opts.user_cookie = Some(user_cookie);\n        }\n\n        if let Some(bind_local_addr) = inst.outbound_bind_addr {\n            connect_opts.bind_local_addr = Some(SocketAddr::new(bind_local_addr, 0));\n        }\n\n        if let Some(bind_interface) = inst.outbound_bind_interface {\n            connect_opts.bind_interface = Some(bind_interface);\n        }\n\n        if let Some(udp_allow_fragmentation) = inst.outbound_udp_allow_fragmentation {\n            connect_opts.udp.allow_fragmentation = udp_allow_fragmentation;\n        }\n\n        server_builder.set_connect_opts(connect_opts);\n        server_builder.set_accept_opts(accept_opts);\n\n        if let Some(c) = config.udp_max_associations {\n            server_builder.set_udp_capacity(c);\n        }\n        if let Some(d) = config.udp_timeout {\n            server_builder.set_udp_expiry_duration(d);\n        }\n        if let Some(ref m) = config.manager {\n            server_builder.set_manager_addr(m.addr.clone());\n        }\n\n        match inst.acl {\n            Some(acl) => server_builder.set_acl(Arc::new(acl)),\n            None => {\n                if let Some(ref acl) = acl {\n                    server_builder.set_acl(acl.clone());\n                }\n            }\n        }\n\n        if config.ipv6_first {\n            server_builder.set_ipv6_first(config.ipv6_first);\n        }\n\n        server_builder.set_security_config(&config.security);\n\n        let server = server_builder.build().await?;\n        servers.push(server);\n    }\n\n    if servers.len() == 1 {\n        let server = servers.pop().unwrap();\n        return server.run().await;\n    }\n\n    let mut vfut = Vec::with_capacity(servers.len());\n\n    for server in servers {\n        vfut.push(ServerHandle(tokio::spawn(async move { server.run().await })));\n    }\n\n    let (res, ..) = future::select_all(vfut).await;\n    res\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/server/server.rs",
    "content": "//! Shadowsocks Server instance\n\nuse std::{collections::HashMap, io, sync::Arc, time::Duration};\n\nuse futures::future;\nuse log::{error, trace};\nuse shadowsocks::{\n    ManagerClient,\n    config::{ManagerAddr, ServerConfig},\n    dns_resolver::DnsResolver,\n    net::{AcceptOpts, ConnectOpts},\n    plugin::{Plugin, PluginMode},\n};\nuse tokio::time;\n\nuse crate::{acl::AccessControl, config::SecurityConfig, net::FlowStat, utils::ServerHandle};\n\nuse super::{context::ServiceContext, tcprelay::TcpServer, udprelay::UdpServer};\n\n/// Shadowsocks Server Builder\npub struct ServerBuilder {\n    context: ServiceContext,\n    svr_cfg: ServerConfig,\n    udp_expiry_duration: Option<Duration>,\n    udp_capacity: Option<usize>,\n    manager_addr: Option<ManagerAddr>,\n    accept_opts: AcceptOpts,\n}\n\nimpl ServerBuilder {\n    /// Create a new server builder from configuration\n    pub fn new(svr_cfg: ServerConfig) -> Self {\n        Self::with_context(ServiceContext::new(), svr_cfg)\n    }\n\n    /// Create a new server builder with context\n    fn with_context(context: ServiceContext, svr_cfg: ServerConfig) -> Self {\n        Self {\n            context,\n            svr_cfg,\n            udp_expiry_duration: None,\n            udp_capacity: None,\n            manager_addr: None,\n            accept_opts: AcceptOpts::default(),\n        }\n    }\n\n    /// Get flow statistic\n    pub fn flow_stat(&self) -> Arc<FlowStat> {\n        self.context.flow_stat()\n    }\n\n    /// Get flow statistic reference\n    pub fn flow_stat_ref(&self) -> &FlowStat {\n        self.context.flow_stat_ref()\n    }\n\n    /// Set `ConnectOpts`\n    pub fn set_connect_opts(&mut self, opts: ConnectOpts) {\n        self.context.set_connect_opts(opts)\n    }\n\n    /// Set UDP association's expiry duration\n    pub fn set_udp_expiry_duration(&mut self, d: Duration) {\n        self.udp_expiry_duration = Some(d);\n    }\n\n    /// Set total UDP associations to be kept in one server\n    pub fn set_udp_capacity(&mut self, c: usize) {\n        self.udp_capacity = Some(c);\n    }\n\n    /// Set manager's address to report `stat`\n    pub fn set_manager_addr(&mut self, manager_addr: ManagerAddr) {\n        self.manager_addr = Some(manager_addr);\n    }\n\n    /// Get server's configuration\n    pub fn server_config(&self) -> &ServerConfig {\n        &self.svr_cfg\n    }\n\n    /// Set customized DNS resolver\n    pub fn set_dns_resolver(&mut self, resolver: Arc<DnsResolver>) {\n        self.context.set_dns_resolver(resolver)\n    }\n\n    /// Set access control list\n    pub fn set_acl(&mut self, acl: Arc<AccessControl>) {\n        self.context.set_acl(acl);\n    }\n\n    /// Set `AcceptOpts` for accepting new connections\n    pub fn set_accept_opts(&mut self, opts: AcceptOpts) {\n        self.accept_opts = opts;\n    }\n\n    /// Try to connect IPv6 addresses first if hostname could be resolved to both IPv4 and IPv6\n    pub fn set_ipv6_first(&mut self, ipv6_first: bool) {\n        self.context.set_ipv6_first(ipv6_first);\n    }\n\n    /// Set security config\n    pub fn set_security_config(&mut self, security: &SecurityConfig) {\n        self.context.set_security_config(security)\n    }\n\n    /// Start the server\n    ///\n    /// 1. Starts plugin (subprocess)\n    /// 2. Starts TCP server (listener)\n    /// 3. Starts UDP server (listener)\n    pub async fn build(mut self) -> io::Result<Server> {\n        let context = Arc::new(self.context);\n\n        let mut plugin = None;\n\n        if let Some(plugin_cfg) = self.svr_cfg.plugin() {\n            let plugin_process = Plugin::start(plugin_cfg, self.svr_cfg.addr(), PluginMode::Server)?;\n            self.svr_cfg.set_plugin_addr(plugin_process.local_addr().into());\n            plugin = Some(plugin_process);\n        }\n\n        let mut tcp_server = None;\n        if self.svr_cfg.mode().enable_tcp() {\n            let server = TcpServer::new(context.clone(), self.svr_cfg.clone(), self.accept_opts.clone()).await?;\n            tcp_server = Some(server);\n        }\n\n        let mut udp_server = None;\n        if self.svr_cfg.mode().enable_udp() {\n            let server = UdpServer::new(\n                context.clone(),\n                self.svr_cfg.clone(),\n                self.udp_expiry_duration,\n                self.udp_capacity,\n                self.accept_opts.clone(),\n            )\n            .await?;\n            udp_server = Some(server);\n        }\n\n        Ok(Server {\n            context,\n            svr_cfg: self.svr_cfg,\n            tcp_server,\n            udp_server,\n            manager_addr: self.manager_addr,\n            plugin,\n        })\n    }\n}\n\n/// Shadowsocks Server instance\npub struct Server {\n    context: Arc<ServiceContext>,\n    svr_cfg: ServerConfig,\n    tcp_server: Option<TcpServer>,\n    udp_server: Option<UdpServer>,\n    manager_addr: Option<ManagerAddr>,\n    plugin: Option<Plugin>,\n}\n\nimpl Server {\n    /// Get Server's configuration\n    pub fn server_config(&self) -> &ServerConfig {\n        &self.svr_cfg\n    }\n\n    /// Get TCP server instance\n    pub fn tcp_server(&self) -> Option<&TcpServer> {\n        self.tcp_server.as_ref()\n    }\n\n    /// Get UDP server instance\n    pub fn udp_server(&self) -> Option<&UdpServer> {\n        self.udp_server.as_ref()\n    }\n\n    /// Start serving\n    pub async fn run(self) -> io::Result<()> {\n        let mut vfut = Vec::new();\n\n        if let Some(plugin) = self.plugin {\n            vfut.push(ServerHandle(tokio::spawn(async move {\n                match plugin.join().await {\n                    Ok(status) => {\n                        error!(\"plugin exited with status: {}\", status);\n                        Ok(())\n                    }\n                    Err(err) => {\n                        error!(\"plugin exited with error: {}\", err);\n                        Err(err)\n                    }\n                }\n            })));\n        }\n\n        if let Some(tcp_server) = self.tcp_server {\n            vfut.push(ServerHandle(tokio::spawn(tcp_server.run())));\n        }\n\n        if let Some(udp_server) = self.udp_server {\n            vfut.push(ServerHandle(tokio::spawn(udp_server.run())));\n        }\n\n        if let Some(manager_addr) = self.manager_addr {\n            vfut.push(ServerHandle(tokio::spawn(async move {\n                loop {\n                    match ManagerClient::connect(\n                        self.context.context_ref(),\n                        &manager_addr,\n                        self.context.connect_opts_ref(),\n                    )\n                    .await\n                    {\n                        Err(err) => {\n                            error!(\"failed to connect manager {}, error: {}\", manager_addr, err);\n                        }\n                        Ok(mut client) => {\n                            use shadowsocks::manager::protocol::StatRequest;\n\n                            let mut stat = HashMap::new();\n                            let flow = self.context.flow_stat_ref();\n                            stat.insert(self.svr_cfg.addr().port(), flow.tx() + flow.rx());\n\n                            let req = StatRequest { stat };\n\n                            match client.stat(&req).await {\n                                Err(err) => {\n                                    error!(\n                                        \"failed to send stat to manager {}, error: {}, {:?}\",\n                                        manager_addr, err, req\n                                    );\n                                }\n                                _ => {\n                                    trace!(\"report to manager {}, {:?}\", manager_addr, req);\n                                }\n                            }\n                        }\n                    }\n\n                    // Report every 10 seconds\n                    time::sleep(Duration::from_secs(10)).await;\n                }\n            })));\n        }\n\n        if let (Err(err), ..) = future::select_all(vfut).await {\n            error!(\"servers exited with error: {}\", err);\n        }\n\n        let err = io::Error::other(\"server exited unexpectedly\");\n        Err(err)\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/server/tcprelay.rs",
    "content": "//! Shadowsocks TCP server\n\nuse std::{\n    future::Future,\n    io::{self, ErrorKind},\n    net::SocketAddr,\n    sync::Arc,\n    time::Duration,\n};\n\nuse log::{debug, error, info, trace, warn};\nuse shadowsocks::{\n    ProxyListener, ServerConfig,\n    crypto::CipherKind,\n    net::{AcceptOpts, TcpStream as OutboundTcpStream},\n    relay::tcprelay::{ProxyServerStream, utils::copy_encrypted_bidirectional},\n};\nuse tokio::{\n    io::{AsyncReadExt, AsyncWriteExt},\n    net::TcpStream as TokioTcpStream,\n    time,\n};\n\nuse crate::net::{MonProxyStream, utils::ignore_until_end};\n\nuse super::context::ServiceContext;\n\n/// TCP server instance\npub struct TcpServer {\n    context: Arc<ServiceContext>,\n    svr_cfg: ServerConfig,\n    listener: ProxyListener,\n}\n\nimpl TcpServer {\n    pub(crate) async fn new(\n        context: Arc<ServiceContext>,\n        svr_cfg: ServerConfig,\n        accept_opts: AcceptOpts,\n    ) -> io::Result<Self> {\n        let listener = ProxyListener::bind_with_opts(context.context(), &svr_cfg, accept_opts).await?;\n        Ok(Self {\n            context,\n            svr_cfg,\n            listener,\n        })\n    }\n\n    /// Server's configuration\n    pub fn server_config(&self) -> &ServerConfig {\n        &self.svr_cfg\n    }\n\n    /// Server's listen address\n    pub fn local_addr(&self) -> io::Result<SocketAddr> {\n        self.listener.local_addr()\n    }\n\n    /// Start server's accept loop\n    pub async fn run(self) -> io::Result<()> {\n        info!(\n            \"shadowsocks tcp server listening on {}, inbound address {}\",\n            self.listener.local_addr().expect(\"listener.local_addr\"),\n            self.svr_cfg.addr()\n        );\n\n        loop {\n            let flow_stat = self.context.flow_stat();\n\n            let (local_stream, peer_addr) = match self\n                .listener\n                .accept_map(|s| MonProxyStream::from_stream(s, flow_stat))\n                .await\n            {\n                Ok(s) => s,\n                Err(err) => {\n                    error!(\"tcp server accept failed with error: {}\", err);\n                    time::sleep(Duration::from_secs(1)).await;\n                    continue;\n                }\n            };\n\n            if self.context.check_client_blocked(&peer_addr) {\n                warn!(\"access denied from {} by ACL rules\", peer_addr);\n                continue;\n            }\n\n            let client = TcpServerClient {\n                context: self.context.clone(),\n                method: self.svr_cfg.method(),\n                peer_addr,\n                stream: local_stream,\n                timeout: self.svr_cfg.timeout(),\n            };\n\n            tokio::spawn(async move {\n                if let Err(err) = client.serve().await {\n                    debug!(\"tcp server stream aborted with error: {}\", err);\n                }\n            });\n        }\n    }\n}\n\n#[inline]\nasync fn timeout_fut<F, R>(duration: Option<Duration>, f: F) -> io::Result<R>\nwhere\n    F: Future<Output = io::Result<R>>,\n{\n    match duration {\n        None => f.await,\n        Some(d) => match time::timeout(d, f).await {\n            Ok(o) => o,\n            Err(..) => Err(ErrorKind::TimedOut.into()),\n        },\n    }\n}\n\nstruct TcpServerClient {\n    context: Arc<ServiceContext>,\n    method: CipherKind,\n    peer_addr: SocketAddr,\n    stream: ProxyServerStream<MonProxyStream<TokioTcpStream>>,\n    timeout: Option<Duration>,\n}\n\nimpl TcpServerClient {\n    async fn serve(mut self) -> io::Result<()> {\n        // let target_addr = match Address::read_from(&mut self.stream).await {\n        let target_addr = match timeout_fut(self.timeout, self.stream.handshake()).await {\n            Ok(a) => a,\n            // Err(Socks5Error::IoError(ref err)) if err.kind() == ErrorKind::UnexpectedEof => {\n            //     debug!(\n            //         \"handshake failed, received EOF before a complete target Address, peer: {}\",\n            //         self.peer_addr\n            //     );\n            //     return Ok(());\n            // }\n            Err(err) if err.kind() == ErrorKind::UnexpectedEof => {\n                debug!(\n                    \"tcp handshake failed, received EOF before a complete target Address, peer: {}\",\n                    self.peer_addr\n                );\n                return Ok(());\n            }\n            Err(err) if err.kind() == ErrorKind::TimedOut => {\n                debug!(\n                    \"tcp handshake failed, timeout before a complete target Address, peer: {}\",\n                    self.peer_addr\n                );\n                return Ok(());\n            }\n            Err(err) => {\n                // https://github.com/shadowsocks/shadowsocks-rust/issues/292\n                //\n                // Keep connection open. Except AEAD-2022\n                warn!(\"tcp handshake failed. peer: {}, {}\", self.peer_addr, err);\n\n                #[cfg(feature = \"aead-cipher-2022\")]\n                if self.method.is_aead_2022() {\n                    // Set SO_LINGER(0) for misbehave clients, which will eventually receive RST. (ECONNRESET)\n                    // This will also prevent the socket entering TIME_WAIT state.\n\n                    let stream = self.stream.into_inner().into_inner();\n\n                    // tokio's TcpStream.set_linger was marked as deprecated.\n                    // But we set linger(0), which won't block the thread when close() the socket.\n                    let _ = socket2::SockRef::from(&stream).set_linger(Some(Duration::ZERO));\n\n                    return Ok(());\n                }\n\n                debug!(\"tcp silent-drop peer: {}\", self.peer_addr);\n\n                // Unwrap and get the plain stream.\n                // Otherwise it will keep reporting decryption error before reaching EOF.\n                //\n                // Note: This will drop all data in the decryption buffer, which is no going back.\n                let mut stream = self.stream.into_inner();\n\n                let res = ignore_until_end(&mut stream).await;\n\n                trace!(\n                    \"tcp silent-drop peer: {} is now closing with result {:?}\",\n                    self.peer_addr, res\n                );\n\n                return Ok(());\n            }\n        };\n\n        trace!(\n            \"accepted tcp client connection {}, establishing tunnel to {}\",\n            self.peer_addr, target_addr\n        );\n\n        if self.context.check_outbound_blocked(&target_addr).await {\n            error!(\n                \"tcp client {} outbound {} blocked by ACL rules\",\n                self.peer_addr, target_addr\n            );\n            return Ok(());\n        }\n\n        let mut remote_stream = match timeout_fut(\n            self.timeout,\n            OutboundTcpStream::connect_remote_with_opts(\n                self.context.context_ref(),\n                &target_addr,\n                self.context.connect_opts_ref(),\n            ),\n        )\n        .await\n        {\n            Ok(s) => s,\n            Err(err) => {\n                error!(\n                    \"tcp tunnel {} -> {} connect failed, error: {}\",\n                    self.peer_addr, target_addr, err\n                );\n                return Err(err);\n            }\n        };\n\n        // https://github.com/shadowsocks/shadowsocks-rust/issues/232\n        //\n        // Protocols like FTP, clients will wait for servers to send Welcome Message without sending anything.\n        //\n        // Wait at most 500ms, and then sends handshake packet to remote servers.\n        if self.context.connect_opts_ref().tcp.fastopen {\n            let mut buffer = [0u8; 8192];\n            match time::timeout(Duration::from_millis(500), self.stream.read(&mut buffer)).await {\n                Ok(Ok(0)) => {\n                    // EOF. Just terminate right here.\n                    return Ok(());\n                }\n                Ok(Ok(n)) => {\n                    // Send the first packet.\n                    timeout_fut(self.timeout, remote_stream.write_all(&buffer[..n])).await?;\n                }\n                Ok(Err(err)) => return Err(err),\n                Err(..) => {\n                    // Timeout. Send handshake to server.\n                    timeout_fut(self.timeout, remote_stream.write(&[])).await?;\n\n                    trace!(\n                        \"tcp tunnel {} -> {} sent TFO connect without data\",\n                        self.peer_addr, target_addr\n                    );\n                }\n            }\n        }\n\n        debug!(\n            \"established tcp tunnel {} <-> {} with {:?}\",\n            self.peer_addr,\n            target_addr,\n            self.context.connect_opts_ref()\n        );\n\n        match copy_encrypted_bidirectional(self.method, &mut self.stream, &mut remote_stream).await {\n            Ok((rn, wn)) => {\n                trace!(\n                    \"tcp tunnel {} <-> {} closed, L2R {} bytes, R2L {} bytes\",\n                    self.peer_addr, target_addr, rn, wn\n                );\n            }\n            Err(err) => {\n                trace!(\n                    \"tcp tunnel {} <-> {} closed with error: {}\",\n                    self.peer_addr, target_addr, err\n                );\n            }\n        }\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/server/udprelay.rs",
    "content": "//! Shadowsocks UDP server\n\nuse std::{cell::RefCell, io, net::SocketAddr, sync::Arc, time::Duration};\n\nuse bytes::Bytes;\nuse futures::future;\nuse log::{debug, error, info, trace, warn};\nuse lru_time_cache::LruCache;\nuse rand::{RngExt, rngs::SmallRng};\nuse shadowsocks::{\n    ServerConfig,\n    config::ServerUser,\n    crypto::CipherCategory,\n    lookup_then,\n    net::{\n        AcceptOpts, AddrFamily, UdpSocket as OutboundUdpSocket, UdpSocket as InboundUdpSocket,\n        get_ip_stack_capabilities,\n    },\n    relay::{\n        socks5::Address,\n        udprelay::{MAXIMUM_UDP_PAYLOAD_SIZE, ProxySocket, options::UdpSocketControlData},\n    },\n};\nuse tokio::{runtime::Handle, sync::mpsc, task::JoinHandle, time};\n\nuse crate::net::{\n    MonProxySocket, UDP_ASSOCIATION_KEEP_ALIVE_CHANNEL_SIZE, UDP_ASSOCIATION_SEND_CHANNEL_SIZE,\n    packet_window::PacketWindowFilter, utils::to_ipv4_mapped,\n};\n\nuse super::context::ServiceContext;\n\n#[derive(Debug, Clone, Copy)]\nenum NatKey {\n    PeerAddr(SocketAddr),\n    #[cfg(feature = \"aead-cipher-2022\")]\n    SessionId(u64),\n}\n\ntype AssociationMap = LruCache<SocketAddr, UdpAssociation>;\n#[cfg(feature = \"aead-cipher-2022\")]\ntype SessionMap = LruCache<u64, UdpAssociation>;\n\nenum NatMap {\n    Association(AssociationMap),\n    #[cfg(feature = \"aead-cipher-2022\")]\n    Session(SessionMap),\n}\n\nimpl NatMap {\n    fn cleanup_expired(&mut self) {\n        match *self {\n            Self::Association(ref mut m) => {\n                m.iter();\n            }\n            #[cfg(feature = \"aead-cipher-2022\")]\n            Self::Session(ref mut m) => {\n                m.iter();\n            }\n        }\n    }\n\n    fn keep_alive(&mut self, key: &NatKey) {\n        match (self, key) {\n            (Self::Association(m), NatKey::PeerAddr(peer_addr)) => {\n                m.get(peer_addr);\n            }\n            #[cfg(feature = \"aead-cipher-2022\")]\n            (Self::Session(m), NatKey::SessionId(session_id)) => {\n                m.get(session_id);\n            }\n            #[allow(unreachable_patterns)]\n            _ => unreachable!(\"NatMap & NatKey mismatch\"),\n        }\n    }\n}\n\n/// UDP server instance\npub struct UdpServer {\n    context: Arc<ServiceContext>,\n    assoc_map: NatMap,\n    keepalive_tx: mpsc::Sender<NatKey>,\n    keepalive_rx: mpsc::Receiver<NatKey>,\n    time_to_live: Duration,\n    listener: Arc<MonProxySocket<InboundUdpSocket>>,\n    svr_cfg: ServerConfig,\n}\n\nimpl UdpServer {\n    pub(crate) async fn new(\n        context: Arc<ServiceContext>,\n        svr_cfg: ServerConfig,\n        time_to_live: Option<Duration>,\n        capacity: Option<usize>,\n        accept_opts: AcceptOpts,\n    ) -> io::Result<Self> {\n        let time_to_live = time_to_live.unwrap_or(crate::DEFAULT_UDP_EXPIRY_DURATION);\n\n        fn create_assoc_map<K, V>(time_to_live: Duration, capacity: Option<usize>) -> LruCache<K, V>\n        where\n            K: Ord + Clone,\n        {\n            match capacity {\n                Some(capacity) => LruCache::with_expiry_duration_and_capacity(time_to_live, capacity),\n                None => LruCache::with_expiry_duration(time_to_live),\n            }\n        }\n\n        let assoc_map = match svr_cfg.method().category() {\n            CipherCategory::None => NatMap::Association(create_assoc_map(time_to_live, capacity)),\n            #[cfg(feature = \"aead-cipher\")]\n            CipherCategory::Aead => NatMap::Association(create_assoc_map(time_to_live, capacity)),\n            #[cfg(feature = \"stream-cipher\")]\n            CipherCategory::Stream => NatMap::Association(create_assoc_map(time_to_live, capacity)),\n            #[cfg(feature = \"aead-cipher-2022\")]\n            CipherCategory::Aead2022 => NatMap::Session(create_assoc_map(time_to_live, capacity)),\n        };\n\n        let (keepalive_tx, keepalive_rx) = mpsc::channel(UDP_ASSOCIATION_KEEP_ALIVE_CHANNEL_SIZE);\n\n        let socket = ProxySocket::bind_with_opts(context.context(), &svr_cfg, accept_opts).await?;\n        let socket = MonProxySocket::from_socket(socket, context.flow_stat());\n        let listener = Arc::new(socket);\n\n        Ok(Self {\n            context,\n            assoc_map,\n            keepalive_tx,\n            keepalive_rx,\n            time_to_live,\n            listener,\n            svr_cfg,\n        })\n    }\n\n    /// Server's configuration\n    pub fn server_config(&self) -> &ServerConfig {\n        &self.svr_cfg\n    }\n\n    /// Server's listen address\n    pub fn local_addr(&self) -> io::Result<SocketAddr> {\n        self.listener.get_ref().local_addr()\n    }\n\n    /// Start server's accept loop\n    pub async fn run(mut self) -> io::Result<()> {\n        info!(\n            \"shadowsocks udp server listening on {}, inbound address {}\",\n            self.local_addr().expect(\"listener.local_addr\"),\n            self.svr_cfg.addr(),\n        );\n\n        let mut cleanup_timer = time::interval(self.time_to_live);\n\n        let mut orx_opt = None;\n\n        let cpus = Handle::current().metrics().num_workers();\n        let mut other_receivers = Vec::new();\n        if cpus > 1 {\n            let (otx, orx) = mpsc::channel((cpus - 1) * 16);\n            orx_opt = Some(orx);\n\n            other_receivers.reserve(cpus - 1);\n            trace!(\"udp server starting extra {} recv workers\", cpus - 1);\n\n            for _ in 1..cpus {\n                let otx = otx.clone();\n                let listener = self.listener.clone();\n                let context = self.context.clone();\n\n                other_receivers.push(tokio::spawn(async move {\n                    let mut buffer = [0u8; MAXIMUM_UDP_PAYLOAD_SIZE];\n\n                    loop {\n                        let (n, peer_addr, target_addr, control) =\n                            match Self::recv_one_packet(&context, &listener, &mut buffer).await {\n                                Some(s) => s,\n                                None => continue,\n                            };\n\n                        if (otx\n                            .send((peer_addr, target_addr, control, Bytes::copy_from_slice(&buffer[..n])))\n                            .await)\n                            .is_err()\n                        {\n                            // If Result is error, the channel receiver is closed. We should exit the task.\n                            break;\n                        }\n                    }\n                }));\n            }\n        }\n\n        struct MulticoreTaskGuard<'a> {\n            tasks: &'a mut Vec<JoinHandle<()>>,\n        }\n\n        impl Drop for MulticoreTaskGuard<'_> {\n            fn drop(&mut self) {\n                for task in self.tasks.iter_mut() {\n                    task.abort();\n                }\n            }\n        }\n\n        let _guard = MulticoreTaskGuard {\n            tasks: &mut other_receivers,\n        };\n\n        type QueuedDataType = (SocketAddr, Address, Option<UdpSocketControlData>, Bytes);\n\n        #[inline]\n        async fn multicore_recv(orx_opt: &mut Option<mpsc::Receiver<QueuedDataType>>) -> QueuedDataType {\n            match orx_opt {\n                None => future::pending().await,\n                Some(orx) => match orx.recv().await {\n                    Some(t) => t,\n                    None => unreachable!(\"multicore sender should keep at least 1\"),\n                },\n            }\n        }\n\n        let mut buffer = [0u8; MAXIMUM_UDP_PAYLOAD_SIZE];\n        // Make a clone to self.listener to avoid borrowing self\n        let listener = self.listener.clone();\n        loop {\n            tokio::select! {\n                _ = cleanup_timer.tick() => {\n                    // cleanup expired associations. iter() will remove expired elements\n                    self.assoc_map.cleanup_expired();\n                }\n\n                peer_addr_opt = self.keepalive_rx.recv() => {\n                    let peer_addr = peer_addr_opt.expect(\"keep-alive channel closed unexpectedly\");\n                    self.assoc_map.keep_alive(&peer_addr);\n                }\n\n                recv_result = Self::recv_one_packet(&self.context, &listener, &mut buffer) => {\n                    let (n, peer_addr, target_addr, control) = match recv_result {\n                        Some(s) => s,\n                        None => continue,\n                    };\n\n                    let data = &buffer[..n];\n                    if let Err(err) = self.send_packet(&listener, peer_addr, target_addr, control, Bytes::copy_from_slice(data)).await {\n                        debug!(\n                            \"udp packet relay {} with {} bytes failed, error: {}\",\n                            peer_addr,\n                            data.len(),\n                            err\n                        );\n                    }\n                }\n\n                recv_result = multicore_recv(&mut orx_opt), if orx_opt.is_some() => {\n                    let (peer_addr, target_addr, control, data) = recv_result;\n                    let data_len = data.len();\n                    if let Err(err) = self.send_packet(&listener, peer_addr, target_addr, control, data).await {\n                        debug!(\n                            \"udp packet relay {} with {} bytes failed, error: {}\",\n                            peer_addr,\n                            data_len,\n                            err\n                        );\n                    }\n                }\n            }\n        }\n    }\n\n    async fn recv_one_packet(\n        context: &ServiceContext,\n        l: &MonProxySocket<InboundUdpSocket>,\n        buffer: &mut [u8],\n    ) -> Option<(usize, SocketAddr, Address, Option<UdpSocketControlData>)> {\n        let (n, peer_addr, target_addr, control) = match l.recv_from_with_ctrl(buffer).await {\n            Ok(s) => s,\n            Err(err) => {\n                error!(\"udp server recv packet failed. {}\", err);\n                return None;\n            }\n        };\n\n        if n == 0 {\n            // For windows, it will generate a ICMP Port Unreachable Message\n            // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-recvfrom\n            // Which will result in recv_from return 0.\n            //\n            // It cannot be solved here, because `WSAGetLastError` is already set.\n            //\n            // See `relay::udprelay::utils::create_socket` for more detail.\n            return None;\n        }\n\n        if context.check_client_blocked(&peer_addr) {\n            warn!(\n                \"udp client {} outbound {} access denied by ACL rules\",\n                peer_addr, target_addr\n            );\n            return None;\n        }\n\n        if context.check_outbound_blocked(&target_addr).await {\n            warn!(\"udp client {} outbound {} blocked by ACL rules\", peer_addr, target_addr);\n            return None;\n        }\n\n        Some((n, peer_addr, target_addr, control))\n    }\n\n    async fn send_packet(\n        &mut self,\n        listener: &Arc<MonProxySocket<InboundUdpSocket>>,\n        peer_addr: SocketAddr,\n        target_addr: Address,\n        control: Option<UdpSocketControlData>,\n        data: Bytes,\n    ) -> io::Result<()> {\n        match self.assoc_map {\n            NatMap::Association(ref mut m) => {\n                if let Some(assoc) = m.get(&peer_addr) {\n                    return assoc.try_send((peer_addr, target_addr, data, control));\n                }\n\n                let assoc = UdpAssociation::new_association(\n                    self.context.clone(),\n                    listener.clone(),\n                    peer_addr,\n                    self.keepalive_tx.clone(),\n                );\n\n                debug!(\"created udp association for {}\", peer_addr);\n\n                assoc.try_send((peer_addr, target_addr, data, control))?;\n                m.insert(peer_addr, assoc);\n            }\n            #[cfg(feature = \"aead-cipher-2022\")]\n            NatMap::Session(ref mut m) => {\n                let xcontrol = match control {\n                    None => {\n                        error!(\"control is required for session based NAT, from {}\", peer_addr);\n                        return Err(io::Error::other(\"control data missing in packet\"));\n                    }\n                    Some(ref c) => c,\n                };\n\n                let client_session_id = xcontrol.client_session_id;\n\n                if let Some(assoc) = m.get(&client_session_id) {\n                    return assoc.try_send((peer_addr, target_addr, data, control));\n                }\n\n                let assoc = UdpAssociation::new_session(\n                    self.context.clone(),\n                    listener.clone(),\n                    peer_addr,\n                    self.keepalive_tx.clone(),\n                    client_session_id,\n                );\n\n                debug!(\n                    \"created udp association for {} with session {}\",\n                    peer_addr, client_session_id\n                );\n\n                assoc.try_send((peer_addr, target_addr, data, control))?;\n                m.insert(client_session_id, assoc);\n            }\n        }\n\n        Ok(())\n    }\n}\n\ntype UdpAssociationSendMessage = (SocketAddr, Address, Bytes, Option<UdpSocketControlData>);\n\nstruct UdpAssociation {\n    assoc_handle: JoinHandle<()>,\n    sender: mpsc::Sender<UdpAssociationSendMessage>,\n}\n\nimpl Drop for UdpAssociation {\n    fn drop(&mut self) {\n        self.assoc_handle.abort();\n    }\n}\n\nimpl UdpAssociation {\n    fn new_association(\n        context: Arc<ServiceContext>,\n        inbound: Arc<MonProxySocket<InboundUdpSocket>>,\n        peer_addr: SocketAddr,\n        keepalive_tx: mpsc::Sender<NatKey>,\n    ) -> Self {\n        let (assoc_handle, sender) = UdpAssociationContext::create(context, inbound, peer_addr, keepalive_tx, None);\n        Self { assoc_handle, sender }\n    }\n\n    #[cfg(feature = \"aead-cipher-2022\")]\n    fn new_session(\n        context: Arc<ServiceContext>,\n        inbound: Arc<MonProxySocket<InboundUdpSocket>>,\n        peer_addr: SocketAddr,\n        keepalive_tx: mpsc::Sender<NatKey>,\n        client_session_id: u64,\n    ) -> Self {\n        let (assoc_handle, sender) =\n            UdpAssociationContext::create(context, inbound, peer_addr, keepalive_tx, Some(client_session_id));\n        Self { assoc_handle, sender }\n    }\n\n    fn try_send(&self, data: UdpAssociationSendMessage) -> io::Result<()> {\n        if self.sender.try_send(data).is_err() {\n            let err = io::Error::other(\"udp relay channel full\");\n            return Err(err);\n        }\n        Ok(())\n    }\n}\n\nstruct ClientSessionContext {\n    client_session_id: u64,\n    packet_window_filter: PacketWindowFilter,\n    client_user: Option<Arc<ServerUser>>,\n}\n\nimpl ClientSessionContext {\n    fn new(client_session_id: u64) -> Self {\n        Self {\n            client_session_id,\n            packet_window_filter: PacketWindowFilter::new(),\n            client_user: None,\n        }\n    }\n}\n\nstruct UdpAssociationContext {\n    context: Arc<ServiceContext>,\n    peer_addr: SocketAddr,\n    outbound_ipv4_socket: Option<OutboundUdpSocket>,\n    outbound_ipv6_socket: Option<OutboundUdpSocket>,\n    keepalive_tx: mpsc::Sender<NatKey>,\n    keepalive_flag: bool,\n    inbound: Arc<MonProxySocket<InboundUdpSocket>>,\n    // AEAD 2022\n    client_session: Option<ClientSessionContext>,\n    server_session_id: u64,\n    server_packet_id: u64,\n}\n\nimpl Drop for UdpAssociationContext {\n    fn drop(&mut self) {\n        debug!(\"udp association for {} is closed\", self.peer_addr);\n    }\n}\n\nthread_local! {\n    static CLIENT_SESSION_RNG: RefCell<SmallRng> = RefCell::new(rand::make_rng());\n}\n\n#[inline]\nfn generate_server_session_id() -> u64 {\n    loop {\n        let id = CLIENT_SESSION_RNG.with(|rng| rng.borrow_mut().random());\n        if id != 0 {\n            break id;\n        }\n    }\n}\n\nimpl UdpAssociationContext {\n    fn create(\n        context: Arc<ServiceContext>,\n        inbound: Arc<MonProxySocket<InboundUdpSocket>>,\n        peer_addr: SocketAddr,\n        keepalive_tx: mpsc::Sender<NatKey>,\n        client_session_id: Option<u64>,\n    ) -> (JoinHandle<()>, mpsc::Sender<UdpAssociationSendMessage>) {\n        // Pending packets UDP_ASSOCIATION_SEND_CHANNEL_SIZE for each association should be good enough for a server.\n        // If there are plenty of packets stuck in the channel, dropping excessive packets is a good way to protect the server from\n        // being OOM.\n        let (sender, receiver) = mpsc::channel(UDP_ASSOCIATION_SEND_CHANNEL_SIZE);\n\n        let mut assoc = Self {\n            context,\n            peer_addr,\n            outbound_ipv4_socket: None,\n            outbound_ipv6_socket: None,\n            keepalive_tx,\n            keepalive_flag: false,\n            inbound,\n            client_session: client_session_id.map(ClientSessionContext::new),\n            // server_session_id must be generated randomly\n            server_session_id: generate_server_session_id(),\n            server_packet_id: 0,\n        };\n        let handle = tokio::spawn(async move { assoc.dispatch_packet(receiver).await });\n\n        (handle, sender)\n    }\n\n    async fn dispatch_packet(&mut self, mut receiver: mpsc::Receiver<UdpAssociationSendMessage>) {\n        let mut outbound_ipv4_buffer = Vec::new();\n        let mut outbound_ipv6_buffer = Vec::new();\n        let mut keepalive_interval = time::interval(Duration::from_secs(1));\n\n        loop {\n            tokio::select! {\n                packet_received_opt = receiver.recv() => {\n                    let (peer_addr, target_addr, data, control) = match packet_received_opt {\n                        Some(d) => d,\n                        None => {\n                            trace!(\"udp association for {} -> ... channel closed\", self.peer_addr);\n                            break;\n                        }\n                    };\n\n                    self.dispatch_received_packet(peer_addr, &target_addr, &data, &control).await;\n                }\n\n                received_opt = receive_from_outbound_opt(&self.outbound_ipv4_socket, &mut outbound_ipv4_buffer), if self.outbound_ipv4_socket.is_some() => {\n                    let (n, addr) = match received_opt {\n                        Ok(r) => r,\n                        Err(err) => {\n                            error!(\"udp relay {} <- ... failed, error: {}\", self.peer_addr, err);\n                            // Socket failure. Reset for recreation.\n                            self.outbound_ipv4_socket = None;\n                            continue;\n                        }\n                    };\n\n                    let addr = Address::from(addr);\n                    self.send_received_respond_packet(addr, &outbound_ipv4_buffer[..n]).await;\n                }\n\n                received_opt = receive_from_outbound_opt(&self.outbound_ipv6_socket, &mut outbound_ipv6_buffer), if self.outbound_ipv6_socket.is_some() => {\n                    let (n, addr) = match received_opt {\n                        Ok(r) => r,\n                        Err(err) => {\n                            error!(\"udp relay {} <- ... failed, error: {}\", self.peer_addr, err);\n                            // Socket failure. Reset for recreation.\n                            self.outbound_ipv6_socket = None;\n                            continue;\n                        }\n                    };\n\n                    let addr = Address::from(addr);\n                    self.send_received_respond_packet(addr, &outbound_ipv6_buffer[..n]).await;\n                }\n\n                _ = keepalive_interval.tick() => {\n                    if self.keepalive_flag {\n                        let nat_key = match self.client_session {\n                            None => NatKey::PeerAddr(self.peer_addr),\n                            #[cfg(feature = \"aead-cipher-2022\")]\n                            Some(ref s) => NatKey::SessionId(s.client_session_id),\n                            #[cfg(not(feature = \"aead-cipher-2022\"))]\n                            Some(..) => unreachable!(\"client_session_id is not None but aead-cipher-2022 is not enabled\"),\n                        };\n\n                        if self.keepalive_tx.try_send(nat_key).is_err() {\n                            debug!(\"udp relay {:?} keep-alive failed, channel full or closed\", nat_key);\n                        } else {\n                            self.keepalive_flag = false;\n                        }\n                    }\n                }\n            }\n        }\n\n        #[inline]\n        async fn receive_from_outbound_opt(\n            socket: &Option<OutboundUdpSocket>,\n            buf: &mut Vec<u8>,\n        ) -> io::Result<(usize, SocketAddr)> {\n            match *socket {\n                None => future::pending().await,\n                Some(ref s) => {\n                    if buf.is_empty() {\n                        buf.resize(MAXIMUM_UDP_PAYLOAD_SIZE, 0);\n                    }\n                    s.recv_from(buf).await\n                }\n            }\n        }\n    }\n\n    async fn dispatch_received_packet(\n        &mut self,\n        peer_addr: SocketAddr,\n        target_addr: &Address,\n        data: &[u8],\n        control: &Option<UdpSocketControlData>,\n    ) {\n        if let Some(ref mut session) = self.client_session\n            && peer_addr != self.peer_addr\n        {\n            debug!(\n                \"udp relay for {} changed to {}, session: {:?}\",\n                self.peer_addr, peer_addr, session.client_session_id\n            );\n            self.peer_addr = peer_addr;\n        }\n\n        trace!(\n            \"udp relay {} -> {} with {} bytes, control: {:?}\",\n            self.peer_addr,\n            target_addr,\n            data.len(),\n            control,\n        );\n\n        if self.context.check_outbound_blocked(target_addr).await {\n            error!(\n                \"udp client {} outbound {} blocked by ACL rules\",\n                self.peer_addr, target_addr\n            );\n            return;\n        }\n\n        if let Some(control) = control {\n            // Check if Packet ID is in the window\n\n            let session_context = self\n                .client_session\n                .get_or_insert_with(|| ClientSessionContext::new(control.client_session_id));\n\n            let packet_id = control.packet_id;\n            if !session_context\n                .packet_window_filter\n                .validate_packet_id(packet_id, u64::MAX)\n            {\n                error!(\"udp client {} packet_id {} out of window\", self.peer_addr, packet_id);\n                return;\n            }\n\n            session_context.client_user.clone_from(&control.user);\n        }\n\n        if let Err(err) = self.dispatch_received_outbound_packet(target_addr, data).await {\n            error!(\n                \"udp relay {} -> {} with {} bytes, error: {}\",\n                self.peer_addr,\n                target_addr,\n                data.len(),\n                err\n            );\n        }\n    }\n\n    async fn dispatch_received_outbound_packet(&mut self, target_addr: &Address, data: &[u8]) -> io::Result<()> {\n        match *target_addr {\n            Address::SocketAddress(sa) => self.send_received_outbound_packet(sa, data).await,\n            Address::DomainNameAddress(ref dname, port) => {\n                lookup_then!(self.context.context_ref(), dname, port, |sa| {\n                    self.send_received_outbound_packet(sa, data).await\n                })\n                .map(|_| ())\n            }\n        }\n    }\n\n    async fn send_received_outbound_packet(&mut self, original_target_addr: SocketAddr, data: &[u8]) -> io::Result<()> {\n        let ip_stack_caps = get_ip_stack_capabilities();\n\n        let target_addr = match original_target_addr {\n            SocketAddr::V4(ref v4) => {\n                // If IPv4-mapped-IPv6 is supported.\n                // Converts IPv4 address to IPv4-mapped-IPv6\n                // All sockets will be created in IPv6 (nearly all modern OS supports IPv6 sockets)\n                if ip_stack_caps.support_ipv4_mapped_ipv6 {\n                    SocketAddr::new(v4.ip().to_ipv6_mapped().into(), v4.port())\n                } else {\n                    original_target_addr\n                }\n            }\n            SocketAddr::V6(ref v6) => {\n                // If IPv6 is not supported. Try to map it back to IPv4.\n                if !ip_stack_caps.support_ipv6 || !ip_stack_caps.support_ipv4_mapped_ipv6 {\n                    match v6.ip().to_ipv4_mapped() {\n                        Some(v4) => SocketAddr::new(v4.into(), v6.port()),\n                        None => original_target_addr,\n                    }\n                } else {\n                    original_target_addr\n                }\n            }\n        };\n\n        let socket = match target_addr {\n            SocketAddr::V4(..) => match self.outbound_ipv4_socket {\n                Some(ref mut socket) => socket,\n                None => {\n                    let socket =\n                        OutboundUdpSocket::connect_any_with_opts(AddrFamily::Ipv4, self.context.connect_opts_ref())\n                            .await?;\n                    self.outbound_ipv4_socket.insert(socket)\n                }\n            },\n            SocketAddr::V6(..) => match self.outbound_ipv6_socket {\n                Some(ref mut socket) => socket,\n                None => {\n                    let socket =\n                        OutboundUdpSocket::connect_any_with_opts(AddrFamily::Ipv6, self.context.connect_opts_ref())\n                            .await?;\n                    self.outbound_ipv6_socket.insert(socket)\n                }\n            },\n        };\n\n        match socket.send_to(data, target_addr).await {\n            Ok(n) => {\n                if n != data.len() {\n                    warn!(\n                        \"{} -> {} sent {} bytes != expected {} bytes\",\n                        self.peer_addr,\n                        target_addr,\n                        n,\n                        data.len()\n                    );\n                }\n                Ok(())\n            }\n            Err(err) => Err(err),\n        }\n    }\n\n    async fn send_received_respond_packet(&mut self, mut addr: Address, data: &[u8]) {\n        trace!(\"udp relay {} <- {} received {} bytes\", self.peer_addr, addr, data.len());\n\n        // Keep association alive in map\n        self.keepalive_flag = true;\n\n        // Convert IPv4-mapped-IPv6 to IPv4\n        //\n        // It is an undefined behavior in shadowsocks' protocol about how to handle IPv4-mapped-IPv6.\n        // But for some implementations, they may expect the target address to be IPv4, because\n        // the peer address is IPv4 when calling `sendto`.\n        if let Address::SocketAddress(SocketAddr::V6(ref v6)) = addr\n            && let Some(v4) = to_ipv4_mapped(v6.ip())\n        {\n            addr = Address::SocketAddress(SocketAddr::new(v4.into(), v6.port()));\n        }\n\n        match self.client_session {\n            None => {\n                // Naive route, send data directly back to client without session\n                match self.inbound.send_to(self.peer_addr, &addr, data).await {\n                    Err(err) => {\n                        warn!(\n                            \"udp failed to send back {} bytes to client {}, from target {}, error: {}\",\n                            data.len(),\n                            self.peer_addr,\n                            addr,\n                            err\n                        );\n                    }\n                    _ => {\n                        trace!(\"udp relay {} <- {} with {} bytes\", self.peer_addr, addr, data.len());\n                    }\n                }\n            }\n            Some(ref client_session) => {\n                // AEAD 2022, client session\n\n                // Increase Packet ID before send\n                self.server_packet_id = match self.server_packet_id.checked_add(1) {\n                    Some(i) => i,\n                    None => {\n                        // FIXME: server_packet_id overflowed. There is no way to recover from this error.\n                        //\n                        // Application clients may open a new session when it couldn't receive proper respond.\n\n                        warn!(\n                            \"udp failed to send back {} bytes to client {}, from target {}, server packet id overflowed\",\n                            data.len(),\n                            self.peer_addr,\n                            addr\n                        );\n                        return;\n                    }\n                };\n\n                let mut control = UdpSocketControlData::default();\n                control.client_session_id = client_session.client_session_id;\n                control.server_session_id = self.server_session_id;\n                control.packet_id = self.server_packet_id;\n                control.user.clone_from(&client_session.client_user);\n\n                match self\n                    .inbound\n                    .send_to_with_ctrl(self.peer_addr, &addr, &control, data)\n                    .await\n                {\n                    Err(err) => {\n                        warn!(\n                            \"udp failed to send back {} bytes to client {}, from target {}, control: {:?}, error: {}\",\n                            data.len(),\n                            self.peer_addr,\n                            addr,\n                            control,\n                            err\n                        );\n                    }\n                    _ => {\n                        trace!(\n                            \"udp relay {} <- {} with {} bytes, control {:?}\",\n                            self.peer_addr,\n                            addr,\n                            data.len(),\n                            control\n                        );\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/sys/mod.rs",
    "content": "use cfg_if::cfg_if;\n\ncfg_if! {\n    if #[cfg(unix)] {\n        mod unix;\n        #[allow(unused_imports)]\n        pub use self::unix::*;\n    }\n\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/sys/unix/macos.rs",
    "content": "//! macOS specific APIs\n\nuse std::{ffi::CString, io, os::fd::RawFd, ptr};\n\nuse log::error;\n\nunsafe extern \"C\" {\n    /// https://developer.apple.com/documentation/xpc/1505523-launch_activate_socket\n    fn launch_activate_socket(\n        name: *const libc::c_char,\n        fds: *mut *mut libc::c_int,\n        cnt: *mut libc::size_t,\n    ) -> libc::c_int;\n}\n\npub fn get_launch_activate_socket(name: &str) -> io::Result<RawFd> {\n    let mut fds: *mut libc::c_int = ptr::null_mut();\n    let mut cnt: libc::size_t = 0;\n\n    let cname = match CString::new(name) {\n        Ok(n) => n,\n        Err(..) => {\n            return Err(io::Error::other(format!(\n                \"activate socket name \\\"{}\\\" contains NUL bytes\",\n                name\n            )));\n        }\n    };\n\n    unsafe {\n        let ret = launch_activate_socket(cname.as_ptr(), &mut fds as *mut _, &mut cnt as *mut _);\n        if ret != 0 {\n            let err = io::Error::last_os_error();\n            match err.raw_os_error() {\n                Some(libc::ENOENT) => {\n                    error!(\"activate socket name \\\"{}\\\" doesn't exist, error: {}\", name, err);\n                }\n                Some(libc::ESRCH) => {\n                    error!(\"current process is not managed by launchd, error: {}\", err);\n                }\n                Some(libc::EALREADY) => {\n                    error!(\n                        \"activate socket name \\\"{}\\\" has already been activated, error: {}\",\n                        name, err\n                    );\n                }\n                _ => {}\n            }\n\n            return Err(err);\n        }\n    }\n\n    let result = if cnt == 0 {\n        Err(io::Error::new(\n            io::ErrorKind::InvalidData,\n            format!(\"launch socket with name \\\"{}\\\" doesn't exist\", name),\n        ))\n    } else if cnt > 1 {\n        for idx in 0..cnt {\n            unsafe {\n                let fd = *(fds.add(idx));\n                let _ = libc::close(fd);\n            }\n        }\n\n        Err(io::Error::new(\n            io::ErrorKind::InvalidData,\n            format!(\n                \"launch socket with name \\\"{}\\\" should be unique, but found {}\",\n                name, cnt\n            ),\n        ))\n    } else {\n        // Take fds[0] as the result\n        let fd = unsafe { *fds };\n        Ok(fd as RawFd)\n    };\n\n    if !fds.is_null() {\n        unsafe { libc::free(fds as *mut _) };\n    }\n\n    result\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/sys/unix/mod.rs",
    "content": "use std::io;\n\nuse cfg_if::cfg_if;\n\ncfg_if! {\n    if #[cfg(target_os = \"macos\")] {\n        mod macos;\n        #[allow(unused_imports)]\n        pub use self::macos::*;\n    }\n}\n\n#[allow(dead_code)]\n#[cfg(not(target_os = \"android\"))]\npub fn set_nofile(nofile: u64) -> io::Result<()> {\n    use std::io::Error;\n\n    unsafe {\n        // set both soft and hard limit\n        let lim = libc::rlimit {\n            rlim_cur: nofile as libc::rlim_t,\n            rlim_max: nofile as libc::rlim_t,\n        };\n\n        if libc::setrlimit(libc::RLIMIT_NOFILE, &lim as *const _) < 0 {\n            return Err(Error::last_os_error());\n        }\n    }\n\n    Ok(())\n}\n\n#[allow(dead_code)]\n#[cfg(target_os = \"android\")]\npub fn set_nofile(_nofile: u64) -> io::Result<()> {\n    // Android doesn't have this API\n    Ok(())\n}\n"
  },
  {
    "path": "crates/shadowsocks-service/src/utils.rs",
    "content": "//! Service Utilities\n\nuse std::{\n    future::Future,\n    io,\n    pin::Pin,\n    task::{Context, Poll},\n};\n\nuse futures::ready;\nuse tokio::task::JoinHandle;\n\n/// Wrapper of `tokio::task::JoinHandle`, which links to a server instance.\n///\n/// `ServerHandle` implements `Future` which will join the `JoinHandle` and get the result.\n/// When `ServerHandle` drops, it will abort the task.\npub struct ServerHandle(pub JoinHandle<io::Result<()>>);\n\nimpl Drop for ServerHandle {\n    #[inline]\n    fn drop(&mut self) {\n        self.0.abort();\n    }\n}\n\nimpl Future for ServerHandle {\n    type Output = io::Result<()>;\n\n    #[inline]\n    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {\n        match ready!(Pin::new(&mut self.0).poll(cx)) {\n            Ok(res) => res.into(),\n            Err(err) => Err(io::Error::other(err)).into(),\n        }\n    }\n}\n"
  },
  {
    "path": "debian/.gitignore",
    "content": "shadowsocks-rust\ndebhelper-*\n*.debhelper\nfiles\n*.substvars\n"
  },
  {
    "path": "debian/changelog",
    "content": "shadowsocks-rust (1.24.0) unstable; urgency=medium\n\n  ## Features\n\n  - #1993, #2044 Support logging to file and syslog\n  - #2026 HTTP Client support auto retry if cached connection was lost\n\n  ## Miscellaneous\n\n  - RUSTSEC-2025-0120, `json5` upgraded to v1.3\n  - MSRV bumps to v1.88\n\n  -- ty <zonyitoo@gmail.com>  Thur, 11 Dec 2025 07:37:00 +0800\n\nshadowsocks-rust (1.23.5) unstable; urgency=medium\n\n  ## Features\n\n  - #1963 Updated `once_cell::sync::Lazy` to `std::sync::LazyLock`\n  - #1967 ACL supported `outbound_allow_list`\n  - #1974 Allow customizable `SocketProtect` trait for Android VpnService\n\n  ## Bug Fixes\n\n  - #1966 Build `xdg` only on *nix platforms\n  - #1968 Make `hickory-dns` truly optional\n\n -- ty <zonyitoo@gmail.com>  Fri, 04 Jul 2025 22:58:00 +0800\n\nshadowsocks-rust (1.23.4) unstable; urgency=medium\n\n  ## Bug Fixes\n\n  - shadowsocks/shadowsocks-android#3185 `local-dns`: Fixed skipping remote resolver for remote servers' names\n\n -- ty <zonyitoo@gmail.com>  Mon, 12 May 2025 23:29:00 +0800\n\nshadowsocks-rust (1.23.3) unstable; urgency=medium\n\n  ## Features\n\n  - #1943 `online-config`: SIP008 online configuration supports adding plugin whitelist (see README for details)\n\n  ## Bug Fixes\n\n  - Build feature `--full` won't report errors for targets that are not supported by `local-tun` and `local-redir`.\n\n -- ty <zonyitoo@gmail.com>  Sun, 11 May 2025 21:21:00 +0800\n\nshadowsocks-rust (1.23.2) unstable; urgency=medium\n\n  ## Bug Fixes\n\n  - #1940 `local-tun`: Fixes `panic` when resizing cached buffers\n\n -- ty <zonyitoo@gmail.com>  Fri, 25 Apr 2025 08:20:00 +0800\n\nshadowsocks-rust (1.23.1) unstable; urgency=medium\n\n  ## Features\n\n  - #1922 `local-tun`: Enable congestion control algorithm for TCP connections\n  - #1923 `local-tun`: Disable TCP package receive checksum for improving performance\n  - `local-tun`: Buffer for receiving/sending packets from/to `tun` device are cached globally\n\n  ## Bug Fixes\n\n  - #1929 `outbound_bind_addr` for UDP sockets failed to `bind()` if it is an IPv4 address\n  - Double check IPSK key length (AEAD-2022) when reading from configuration file\n\n -- ty <zonyitoo@gmail.com>  Mon, 21 Apr 2025 22:26:00 +0800\n\nshadowsocks-rust (1.23.0) unstable; urgency=medium\n\n  ## Features, Breaking Changes\n\n  - MSRV bumps to v1.85, Rust language edition upgraded to `2024`\n  - `rand` crate upgraded to v0.9, which may be incompatible with other older crates\n  - `local-fake-dns` switched storage engine from `sled` to `rocksdb`, users should delete the old database file and let `sslocal` recreate it ageain\n    - `local-fake-dns` is moved from `full` to `full-extra` feature because its still unstable\n\n  ## Bug fixes\n\n  - #1832 Fixes FreeBSD build error\n  - #1833 Fixes `sswinservice.exe` file paths in Powershell build script\n  - `mips-*` targets cross build reenabled\n\n  ## Miscellaneous\n\n  - #1834 Shadowsocks entrance APIs has strongly typed errors\n\n -- ty <zonyitoo@gmail.com>  Wed, 19 Mar 2025 21:40:00 +0800\n\nshadowsocks-rust (1.22.0) unstable; urgency=medium\n\n  ## Features, Breaking Changes\n\n  - `ServerConfig::new` returns a `Result`, fails if `password` doesn't match `method`'s requirements\n  - `ConnectOpts::bind_local_addr` supports binding to a specific port\n  - Uses `async` in trait, bump MSRV to v1.75\n  - #1790 `outbound_udp_allow_fragmentation` new option for allowing UDP outbound sockets to enable IP fragmentation\n  - `tun2` has been merged back to `meh/rust-tun`\n  - #1810 `UdpSocket::bind`\n  - `shadowsocks-rust` binary crate \"default\" feature set to `full`\n\n  ## Bug Fixes\n\n  - Method `none` (`plain`) skips key derivation process.\n  - #1762 Do not crash in `ServerConfig::from_url()` on unknown method\n  - #1759 Flush `local-tun` tcp writer half before close\n  - #1765 Disallow HTTP/SOCKS4a in `socks` protocol handler when authentication is required\n  - `ConnectOpts`'s per-server options should not be shared globally\n  - #1814 `local-dns` upstream udp packet buffer size 256\n\n  ## Miscellaneous\n\n  - Make cryptographic dependencies optional in default build of `shadowsocks` crate.\n\nshadowsocks-rust (1.21.2) unstable; urgency=medium\n\n  ## Bug Fixes\n\n  - #1730 `local-http`: HTTP Client removes Authority from Request URI only for HTTP/1.x\n\nshadowsocks-rust (1.21.1) unstable; urgency=medium\n\n  ## Bug Fixes\n\n  - #1730 `local-http`: The URI field in HTTP Request sent from `sslocal` should only contain path and query.\n\n  ## Miscellaneous\n\n  - #1702 Debian package build removes dependency of `pwgen`\n\nshadowsocks-rust (1.21.0) unstable; urgency=medium\n\n  ## Features\n\n  - #1641 `shadowsocks`: `ProxySocket` supports generic I/O socket type\n  - #1567 `shadowsocks-service`: Support OpenBSD Packet-Filter (pf)\n\nshadowsocks-rust (1.20.4) unstable; urgency=medium\n\n  ## Features\n\n  - #1616 `local`: Allow configuring SOCKS5 `UDP_ASSOCIATE` address\n  - #1607 Published in MacPorts: https://ports.macports.org/port/shadowsocks-rust/\n  - #1613 `ProxyServerStream::from_stream` made public\n\n  ## Bug Fixes\n\n  - #1612 `server`: Properly exit server instance if any of the sub-tasks exited\n\nshadowsocks-rust (1.20.3) unstable; urgency=medium\n\n  ## Features\n\n  - `local`: Ping Balancer scores replaced standard deviation with median absolute deviation, which should help focusing less on outlying observations in latency samples.\n\n  ## Bug Fixes\n\n  - #1589 `local-tun`: Removes linking to [`SetInterfaceDnsSettings`](https://learn.microsoft.com/en-us/windows/win32/api/netioapi/nf-netioapi-setinterfacednssettings) on Windows\n\nshadowsocks-rust (1.20.2) unstable; urgency=medium\n\n  ## Features\n\n  - #1560 PingBalancer check Firefox portal allowing `200` HTTP status\n\nshadowsocks-rust (1.20.1) unstable; urgency=medium\n\n  ## Bug Fixes\n\n  - `local-online-config`: SIP008 auto reload configuration task will add online servers without replacing the existed ones. This bug will eventually cause `sslocal` consumes too many memories and get OOM killed.\n\n  Users are encourage to update to this version if using 1.19.4 to 1.20.0.\n\n  ## Features\n\n  - `shadowsocks-service`: Updated [`rustls`](https://crates.io/crates/rustls) to v0.23 with [`ring`](https://crates.io/crates/ring) backend.\n  - `local-redir`, `server`: Better approach to check current platform IP stack capabilities like Go (IPv4, IPv6, IPv4-mapped-IPv6 supports).\n  - Explicitly enable dual-stack if listen addresses (`server`, `local_address`) are IPv4-mapped-IPv6, by setting `IPV6_V6ONLY=0`.\n\nshadowsocks-rust (1.20.0) unstable; urgency=medium\n\n  ## Breaking Changes\n\n  - #887 shadowsocks stream cipher (`TABLE`) doesn't need to make a derived key instead of using user's predefined key directly. This change will make shadowsocks-rust not going to be compatible with its older version. Users who are using `TABLE` cipher should upgrade all your local and server instances to the latest version of shadowsocks-rust. On the other hand, `TABLE` cipher is marked deprecated because it is vulnerable, users **must** migrate to other more secured methods immediately.\n\nshadowsocks-rust (1.19.4) unstable; urgency=medium\n\n  ## Features\n\n  - `local-online-config`: Making HTTP requests with `local-http`'s HttpClient implementation, mainly for supporting `outbound_*` socket configurations.\n\n  ## Miscellaneous\n\n  - Fixed build failures on some platforms.\n\nshadowsocks-rust (1.19.3) unstable; urgency=medium\n\n  ## Breaking Changes\n\n  - Feature `dns-over-h3` moved from feature `full` to `full-extra`. DNS over H3 is still an experimental feature.\n  - `local-fake-dns`: Disabled compression (zstd), which seems to be deprecated by [`sled`](https://crates.io/crates/sled).\n\n  ## Features\n\n  - `local-online-config`: Set 30s timeout for update HTTP requests.\n\nshadowsocks-rust (1.19.2) unstable; urgency=medium\n\n  ## Bug Fixes\n\n  - `local-tun`: `tun2` handles IP packet information automatically.\n\nshadowsocks-rust (1.19.1) unstable; urgency=medium\n\n  ## Features\n\n  - Rollback `rustls` to v0.22, v0.23 first introduced `aws-lc` as the default crypto implementation, but it cannot be built on some targets if there are still older versions of `rustls` in the dependency tree.\n  - `local-tun`: Switch from `tun` to `tun2`, which is a fork of `tun`. `tun` seems to be abandoned.\n\n  ## Bug Fixes\n\n  - #1539 `local-fake-dns`: Query Response Message has to include the original Query and flags.\n\nshadowsocks-rust (1.19.0) unstable; urgency=medium\n\n  ## Features\n\n  - #302 `sslocal` support SIP008 Online Configuration. Pull `servers` from remote servers automatically. (Experimental)\n  - Add `basic`, `full`, `full-extra` features makes building command line arguments shorter\n  \n  ## Bug Fixes\n\n  - #1525 Check `\"users\"` in server configuration if `method` doesn't support AEAD-2022 EIH.\n  - #1528 Fixed FreeBSD build.\n\n  ## Miscellaneous\n\n  - Snap: Add alias names like `sslocal`, `ssserver`, ...\n  - `local-tun` feature could be enabled even if target platform is not supported.\n\n  ## BREAKING\n\n  - Minimal Supported Rust Version (MSRV) is v1.74\n\nshadowsocks-rust (1.18.4) unstable; urgency=medium\n\n  ## Features\n\n  - #1495 Binaries support `--plugin-mode` command line argument\n  - `local-tun` is enabled by default for Windows targets in CI builds\n\n  ## Bug Fixes\n\n  - #1516 `local-dns` UDP client support AEAD-2022 protocol properly\n\nshadowsocks-rust (1.18.3) unstable; urgency=medium\n\n  ## Features\n\n  - #1466 Support `outbound_fwmark` in server side to split outbound tunnel\n  - #1467 Default build for `*-windows-*` targets includes `sswinservice`\n  - `local-fakedns`: Add a basic implementation of Fake-DNS, which will allocate IPs from pool for DNS queries. This experimental feature could be useful when using `local-tun`, `local-redir` or other features that could only receive IP destinations, the domain name that is resolved by the Fake-DNS will be translated from IP back to domain name when connecting to the remote.\n  - #1500 Add `launchd_udp_socket_name`, `launchd_tcp_socket_name` to basic config format\n\n  ## Bug Fixes\n\n  - Fixed build on OpenBSD\n  - #1491 Fixed per-server outbound options not taking effect\n  - #1509 `local-tun` TCP socket creation made non-blocking\n\nshadowsocks-rust (1.18.2) unstable; urgency=medium\n\n  ## Features\n\n  - `local-tun`: Support `tun_interface_destination` configuration key\n\n  ## Bug Fixes\n\n  - `local`: macOS launch activate sockets set non-blocking\n\nshadowsocks-rust (1.18.1) unstable; urgency=medium\n\n  ## Features\n\n  - Default logging framework changed to [`tracing-subscriber`](https://crates.io/crates/tracing-subscriber), which:\n    - Support libraries that log with both [`tracing`](https://crates.io/crates/tracing), and [`log`](https://crates.io/crates/log).\n    - NOTE: `--log-config` parameter will apply only to [`log4rs`](https://crates.io/crates/log4rs), which doesn't support the `tracing` framework.\n\n  ## Bug Fixes\n\n  - #1425 Enable `EDNS(0)` by default for hickory-dns resolver.\n\n  ## NOTE\n\n  - [`clap`](https://crates.io/crates/clap) upgraded MSRV (Minimal Supported Rust Version) to v1.74 since v4.5.0. This project will have to stay in v4.4 until the next major release.\n\n -- ty <zonyitoo@gmail.com> Sun, 18 Feb 2024 22:05:00 +0800\n\nshadowsocks-rust (1.18.0) unstable; urgency=medium\n\n  Mostly identical to v1.17.2, except that:\n\n  - Minimal Supported Rust Version (MSRV) upgraded from v1.64 to v1.71\n  - #1259 Fixed Snapcraft build. `base` changed to `core22`, auto-build architecture changed to [`arm64`, `amd64`, `armhf`]\n  - #1426 MIPS targets removed from release build, because MIPS targets are now downgraded to TIER 3\n\n -- ty <zonyitoo@gmail.com> Thu, 08 Feb 2024 00:00:00 +0800\n\nshadowsocks-rust (1.17.2) unstable; urgency=medium\n\n  ## Features\n\n  - `local`: `socks` local server will support SOCKS5, SOCKS4a, HTTP proxy protocols when `local-http`, `local-socks4` features are enabled\n  - `local`: Support setting `udp_mtu` in configuration file to actively reject `packet.size > MTU`\n\n  ## Bug Fixes\n\n  - #1378 dns-over-tls/https with rustls add dependencies to certs\n  - #1381 Set the incoming socket buffer sizes properly on the listen socket\n  - #1414 TUN synchronize SYN packet and Socket creation\n\nshadowsocks-rust (1.17.1) unstable; urgency=medium\n\n  ## Features\n\n  - #1330 `local`: Support macOS launch activate socket (https://developer.apple.com/documentation/xpc/1505523-launch_activate_socket)\n  - #1357 `local`: Upgrade hyper (https://crates.io/crates/hyper) to v1.0\n\n  ## Bug Fixes\n\n  - #1328 `run_as_user` aborts if any error occurs\n\n  ## Miscellaneous\n\n  - Minor improvements for `local-tun` on Windows\n  - Upgrade `shadowsocks-crypto` that supports `sm4-gcm`, `sm4-ccm` non-standard AEAD ciphers\n\nshadowsocks-rust (1.17.0) unstable; urgency=medium\n\n  ## Features\n\n  - Trust-DNS is rebranded to Hickory-DNS https://github.com/hickory-dns/hickory-dns/releases/tag/v0.24.0\n  - Experimental: Support DNS-over-H3 (Try with configuration `\"dns\": \"google_h3\"` and compile with feature `\"dns-over-h3\"`)\n  - #1319 Allow configuring `local-dns` client cache size\n  - Experimental: `local-tun` supports Windows with [Wintun](https://www.wintun.net/)\n\nshadowsocks-rust (1.16.2) unstable; urgency=medium\n\n  ## Features\n\n  - `ssurl`: #1287 Support SIP008 links\n  - `ssserver`: #1293 Disable UDP dual-stack outbound socket when IPv6 is not supported\n  - `sswinservice`: #1292 Support Windows Service\n\nshadowsocks-rust (1.16.1) unstable; urgency=medium\n\n  ## Bug Fixes\n\n  - #1285 [Regression fix] local DNS uses mode `tcp_and_udp` by default\n\nshadowsocks-rust (1.16.0) unstable; urgency=medium\n\n  ## Features\n\n  - `local-redir`: #1159 Linux Redirect (TCP) supports dual-stack listener\n  - #1156 Support Multipath-TCP\n  - DNS resolver (with `trust-dns` enabled) support outbound socket configurations, like `outbound-fwmark`, `outbound-bind-addr`, ...\n  - #1127 Support SIP003u, UDP plugins\n  - #1185 Support creating servers with builder pattern to allow users to retrieve the actual listening address of the server listeners\n  - #1204 Support reading default configuration files `local.json`, `server.json` and `manager.json`\n  - #1229 Support configuring DNS cache size with `--dns-cache-size` in command line options and `dns_cache_size` in configuration file\n  - #1266 Support Network Adapters' `FriendlyName` on Windows in `outbound_bind_interface`\n\n  ## Bug Fixes\n\n  - #1239 Fixed misaligned read in shadowsocks' socks5 protocol implementation. It may cause panics compiled by rustc newer than 1.68.\n  - #1234 PingBalancer shouldn't check TCP mode by default\n  - #1221 Compatible with Linux Kernels that doesn't support `IP6T_SO_ORIGINAL_DST`\n  - #1254 Fixed Tree-Rule detector for REGEX rules that ends with `$`\n\n  ## Miscellaneous\n\n  - Docker: #1149 Changed binary path to `/usr/bin` from `/usr/local/bin` preventing being overwritten by K8S mount\n  - Snap: Add `network-control` plug for `tun` protocol\n\n -- ty <zonyitoo@gmail.com>  Sat, 27 Aug 2023 00:20:00\n\nshadowsocks-rust (1.15.4) unstable; urgency=medium\n\n  ## Bug Fixed\n\n  - #1239 Fixed misaligned read in shadowsocks' socks5 protocol implementation. It may cause panics compiled by rustc newer than 1.68.\n\nshadowsocks-rust (1.15.3) unstable; urgency=medium\n\n  ## Features\n\n  - local-tun: Support `tun_interface_destination` for configuring Tun device's destination address\n  - Support `outbound_fwmark`, `outbound_user_cookie`, `outbound_bind_interface` and `outbound_bind_addr` in configuration file\n\n  ## Bug Fixed\n\n  - local-tun: #1138 Fixed TCP state management\n  - local-redir: #988 UDP compatible with Linux < 2.6.37 (without `IPV6_TRANSPARENT`)\n  - manager: #1101 Set missing `ipv6_first` for servers\n\n  ## Miscellaneous\n\n  - Snap: #1088 Disable Snap daemon by default\n\nshadowsocks-rust (1.15.2) unstable; urgency=medium\n\n  ## Bug Fixes\n\n  - #1060 ACL supports checking IPv4-mapped-IPv6 addresses with IPv4 rules\n\n  ## Miscellaneous\n\n  - Code style and potential bug fixes with clippy check\n\nshadowsocks-rust (1.15.0) unstable; urgency=medium\n\n  ## Features\n\n  - #811 AEAD-2022 protocol ([SIP022](https://github.com/shadowsocks/shadowsocks-org/issues/196))\n      - WARN: This is still a draft protocol, use it at your own risk.\n  - SIP002 Extended Format: Allowing unencoded user-info in URL, https://github.com/shadowsocks/shadowsocks-org/issues/27#issuecomment-1124853747\n  - #810 Manager standalone mode support bypassing ACL files\n  - #818 Allow `sslocal` run without any `servers`, which will bypass all connections and packets\n  - #838 `\"password\"` is optional for `none` / `plain` method\n  - redir-local: Enable dual-stack support on Linux (TProxy) and FreeBSD\n  - Disable `md5-asm` and `sha1-asm`: https://github.com/shadowsocks/shadowsocks-crypto/issues/16\n  - `\"acl\"` and `\"outbound_fwmark\"` are available in configuration file\n\n  ## Miscellaneous\n\n  - shadowsocks/shadowsocks-org#204 Remove `security-iv-printable-prefix` experimental feature\n  - Upgrade [clap](https://crates.io/crates/clap) to v4.0.\n  - UDP association channel size shrunk to 1024, which could save a lot of memory for each associations\n\n  ## Enhancements\n\n  - #855 Properly handle IPv4-mapped-IPv6 addresses in UDP associations\n      - `ssserver` always convert IPv4-mapped-IPv6 addresses to IPv4 in UDP respond target addresses\n      - `sslocal`\n          - `tun`, `socks5` always convert IPv4-mapped-IPv6 addresses to IPv4\n          - `redir` always use IPv6 sockets for sending back packets\n\nshadowsocks-rust (1.14.3) unstable; urgency=medium\n\n  ## Features\n\n  - Automatically bump `RLIMIT_NOFILE` on Unix (except Android)\n    - https://github.com/golang/go/issues/46279\n    - http://0pointer.net/blog/file-descriptor-limits.html\n\nshadowsocks-rust (1.14.2) unstable; urgency=medium\n\n  ## Features\n\n  - #788 `sslocal` SOCKS5 protocol supports RFC1929 Username/Password Authentication\n    - SECURITY: This is insecured because (a) shadowsocks' SOCKS5 UDP Association doesn't require a dynamic port for each authorized clients (b) Username and passwords are sent in plain text.\n  - RustCrypto/ring-compat#79 HKDF-SHA1 uses [ring](https://crates.io/crates/ring)'s assembly implementation\n\nshadowsocks-rust (1.14.1) unstable; urgency=medium\n\n  ## Miscellaneous\n\n  - `shadowsocks`, `shadowsocks-service` crates upgraded to Rust Edition 2021.\n\nshadowsocks-rust (1.14.0) unstable; urgency=medium\n\n  ## Features\n\n  - Optimization: UDP associations management removes unnecessary locks\n\n  ## Breaking Changes\n\n  - `shadowsocks_service::local::net::udp::UdpAssociationManager::new` returns clean-up interval and keep-alive receiver. It is not recommended to use this directly in your Project, because the API may change occasionally.\n\nshadowsocks-rust (1.13.5) unstable; urgency=medium\n\n  ## Features\n\n  - #773 Set environment variable `SS_SYSTEM_DNS_RESOLVER_FORCE_BUILTIN` to use system's builtin DNS resolver\n\nshadowsocks-rust (1.13.4) unstable; urgency=medium\n\n  ## Features\n\n  - Allow setting `\"system\"` in DNS configuration key `\"dns\"` to use system provided DNS API\n\n  ## BUG Fixes\n\n  - `ssservice` - fixed command line options when running it as symlink of `ssserver` and `ssmanager`\n\nshadowsocks-rust (1.13.3) unstable; urgency=medium\n\n  ## BUG Fixes\n\n  - #767 REGRESSION: `ssmanager` missing `--server-host` command line option since v1.13.0\n  - shadowsocks/shadowsocks-crypto#12 REGRESSION: `rc4-md5` method cipher IV length should be 16\n\nshadowsocks-rust (1.13.2) unstable; urgency=medium\n\n  ## Features\n\n  - (EXPERIMENTAL) Support setting `SO_USER_COOKIE` on FreeBSD\n    - Set cookie with `--outbound-user-cookie` command line option, working just like `--outbound-fwmark` on Linux\n  - (EXPERIMENTAL) Local `tun` interface refactored the `VirtDevice::poll` strategy\n    - Improve performance\n    - Still slow comparing to system's network stack\n\n  ## BUG Fixes\n\n  - #765 Updated broken Wiki URL for Plugins in command line help message\n  - #764 Regression of client blocking ACL strategy on `ssserver`\n    - Introduced since v1.9.0\n\nshadowsocks-rust (1.13.1) unstable; urgency=medium\n\n  ## Bug Fixes\n\n  - `Instant` subtraction may be overflowed in `PingBalancer`\n    - When `sslocal` has set multiple remote servers and the host system just reboots, it will crash.\n\nshadowsocks-rust (1.13.0) unstable; urgency=medium\n\n  ## Features\n\n  - #706 `balancer.check_best_interval` could let ping balancer to ping only the chosen best server in this interval\n    - Recommended: Set a shorter interval in `balancer.check_best_interval` than `balancer.check_interval` to check much frequently the best server.\n    - `balancer.check_interval` controls the interval of checking all the available servers\n    - When server start, the \"check best\" strategy starts after it receives enough data for estimating all servers' scores\n  - #744 Refactored `local-tun`, using `smoltcp` as a user-space network stack\n\n  ## Miscellaneous\n\n  - Upgrade [`clap`](https://crates.io/crates/clap) (the command-line argument handling library) to v3.0\n  - #739 Support K8S deployment\n  - [shadowsocks-crypto](https://github.com/shadowsocks/shadowsocks-crypto) switch underlying encryption library to [RustCrypto](https://github.com/RustCrypto)\n    - Able to build with stable Rust\n    - Build for target `aarch64` with nightly, features `\"armv8 neon\"` should be enabled for hardware acceleration.\n\nshadowsocks-rust (1.12.5) unstable; urgency=medium\n\n  ## Bug Fixes\n\n  - #725 High CPU consumption on Linux Kernel < 4.11 when TCP Fast Open is enabled.\n\n -- ty <zonyitoo@gmail.com>  Fri, 17 Dec 2021 00:13:26 +0800\n  \nshadowsocks-rust (1.12.4) unstable; urgency=medium\n\n  ## Features\n\n  - Configuration\n    - `ipv6_only` configuration option setting `IPV6_V6ONLY` to all listener sockets that are listening to dual-stack address (`::`)\n    - #700 Default configuration search path also includes `$PWD`\n    - Log and Runtime related options could be configured via configuration file\n  - #698 New binary `ssservice` unified features in (`sslocal`, `ssserver` and `ssmanager`)\n\n  ## Bug Fixes\n\n  - #694 UDP binds to dual-stack address (`::`) will detect `0.0.0.0` already in use automatically\n  - Transparent Proxy (redir) local client will always set `IPV6_V6ONLY` for listeners that are listening on `::`\n\n  ## Miscellaneous\n\n  - Deprecating `SS_LOG_VERBOSE_LEVEL` and `SS_LOG_WITHOUT_TIME` (introduced in [v1.12.3](https://github.com/shadowsocks/shadowsocks-rust/releases/tag/v1.12.3)) in flavor of configuring in the configuration file\n\n -- ty <zonyitoo@gmail.com>  Sun, 28 Nov 2021 15:01:54 +0800\n\nshadowsocks-rust (1.12.3) unstable; urgency=medium\n\n  ## Features\n\n  - #688 Support default configuration file path for `sslocal`, `ssserver` and `ssmanager`\n    - Linux: `$XDG_CONFIG_PATH/shadowsocks-rust/config.json` or `$HOME/.config/shadowsocks-rust/config.json`\n    - Windows: `{FOLDERID_RoamingAppData}\\shadowsocks\\shadowsocks-rust\\config\\config.json`\n    - macOS: `$HOME/Library/Application Support/org.shadowsocks.shadowsocks-rust/config.json`\n  - #691 Manipulating default logging options (command line options `-vvv` and `--log-without-time`) with environment variable `SS_LOG_VERBOSE_LEVEL` and `SS_LOG_WITHOUT_TIME`\n  - #419 Read servers' password from environment variables\n    - Server created from command line argument without `--password` will try to read it from TTY\n    - Servers' `\"password\"` field or `--password` option support `${VAR_NAME}` format to read password from environment variable `VAR_NAME`\n\n -- ty <zonyitoo@gmail.com>  Fri, 26 Nov 2021 00:12:13 +0800\n\nshadowsocks-rust (1.12.2) unstable; urgency=medium\n\n  ## BUG Fixes\n\n  - #683 local-dns command line `--remote-dns-addr` will have default port `53`\n\n  ## Miscellaneous\n\n  - Removed direct dependency to [`mio`](https://crates.io/crates/mio), sending file descriptors through UDS now with [`sendfd`](https://crates.io/crates/sendfd).\n\n -- ty <zonyitoo@gmail.com>  Tue, 16 Nov 2021 00:11:44 +0800\n\nshadowsocks-rust (1.12.1) unstable; urgency=medium\n\n  ## Features\n\n    - #669 ACL regular expression rules will try to convert to `||` (sub-domains) and `|` (exact match) rules.\n\n  ## Bug Fixes\n\n    - #674 MIPS targets in pre-built releases binaries will be compressed by `upx`\n    - #670 Servers created by command line options in `ssserver` will have mode `tcp_only`\n\n -- ty <zonyitoo@gmail.com>  Tue, 9 Nov 2021 23:27:48 +0800\n\nshadowsocks-rust (1.12.0) unstable; urgency=medium\n\n  ## Features\n\n  - TCP connects with Happy Eyeballs (RFC6555, RFC8305) strategy\n  - Local \n    - #586 Basic support of `tun` interface in `sslocal` (Experimental) Tested on macOS and Linux\n    - #620 Local server will choose remote servers based on their `\"mode\"`\n    - Local Balancer\n      - Configurable `max_server_rtt` and `check_interval`\n      - Reload configuration `\"servers\"` in runtime when receiving `SIGUSR1` signal\n  - Manager\n    - #421 `ssmanager` support `--plugin` and `--plugin-opts` as default plugin configurations\n    - #648 `ssmanager` support starting `ssserver` in standalone (independent process) mode.\n  - #627 ACL support `|` and `||` hash-set and domain-tree mode\n  - Support `--outbound-bind-interface` on Windows.\n\n  ## Bug Fixed\n\n  - #579 UDP server reply target address should be received source address\n  - TFO socket on Windows should bind to `SOCKADDR_IN6` for IPv6 targets\n  - #640 `--daemonize` will set `chdir` to current working directory\n    - [BREAKING] In the previous version `--daemonize` will call `chdir` to `/` by default, so it may change the behavior if users using relative paths in `\"plugin\"` or `\"plugin_opts\"`\n\n  ## Miscellaneous\n\n  - #596 Support Snapcraft https://snapcraft.io/shadowsocks-rust\n  - TFO on Linux queue length set to 1024 to match backlogs\n  - Completely remove Replay Attack Protection with Ping-Pong bloom filter in default build configuration\n\n -- ty <zonyitoo@gmail.com>  Tue, 2 Nov 2021 12:52:17 +0800\n\nshadowsocks-rust (1.11.2) unstable; urgency=medium\n\n  ## Features\n\n  - #570 Multi-architecture Docker image for release\n  - Replaced `futures::future::abortable` with `tokio`'s builtin `tokio::task::JoinHandle::abort`\n  - Define binaries' exit code with standard in `sysexits.h`\n  - HTTP local listener supports `TCP_NODELAY`, `SO_KEEPALIVE` and dual-stack\n\n  ## Bug Fixed\n\n  - #577 `ssmanager` and `ssserver` command line argument `-u` should overwrite `mode` to be `Mode::UdpOnly`\n  - #566 Exit with error code instead of `panic!` when loading ACL fails\n  - #555 Properly handling `EINPROGRESS` for TFO connect when falling backs\n  - #557 Properly killing UDP associations, which may cause `Future` (memory) leaks\n\n  ## Security\n\n  - #556 Remove silent dropping when replay was detected\n\n -- ty <zonyitoo@gmail.com>  Sat, 24 July 2021 11:50:00 +0800\n\nshadowsocks-rust (1.11.1) unstable; urgency=medium\n\n  ## Features\n\n  - #546 Enable TCP Keep Alive for inbound and outbound sockets\n      - Add a new `keep_alive` key in configuration for configuring keep alive timeout\n      - Default timeout is 15 seconds (like Go's `net` library's default)\n\n  - #543 Add `disabled` key for local servers in configuration\n\n  ## Bug Fixed\n\n  - #490 Try to purge half-open TCP connections when one direction is closed\n      - When one direction is closed, server will set a 5 seconds read timeout on the other half\n\n  - #542 Allow setting `method` for default encryption method when starting `ssmanager` with configuration\n\n  - #541 Fixed ACL rules for `ssmanager`\n\n -- ty <zonyitoo@gmail.com>  Sun, 6 June 2021 23:16:00 +0800\n\nshadowsocks-rust (1.11.0) unstable; urgency=medium\n\n  ## Features\n\n  - Support TFO (TCP Fast Open) on Linux, Windows, macOS (iOS), FreeBSD (https://github.com/shadowsocks/shadowsocks-rust/issues/184)\n  - Support customizing servers' weight for balancer (https://github.com/shadowsocks/shadowsocks-rust/issues/510)\n\n -- ty <zonyitoo@gmail.com>  Fri, 14 May 2021 12:31:54 +0800\n\nshadowsocks-rust (1.10.9) unstable; urgency=medium\n\n  ## Bug Fixes\n\n  - HTTP Proxy preserves headers' title case. https://github.com/shadowsocks/shadowsocks-rust/discussions/491 , https://github.com/hyperium/hyper/issues/2313\n\n -- ty <zonyitoo@gmail.com>  Fri, 23 Apr 2021 23:58:08 +0800\n\nshadowsocks-rust (1.10.8) unstable; urgency=medium\n\n  ## Bug Fixes\n\n  - Removes non-standard AEAD ciphers that have variable nonce length, including\n    - `aes-128-ocb-taglen128`, `aes-192-ocb-taglen128`, `aes-256-ocb-taglen128`\n    - `aes-siv-cmac-256`, `aes-siv-cmac-384`, `aes-siv-cmac-512`\n\n -- ty <zonyitoo@gmail.com>  Sun, 18 Apr 2021 21:00:21 +0800\n\nshadowsocks-rust (1.10.7) unstable; urgency=medium\n\n  ## Features\n\n  - Support non-standard AEAD ciphers `sm4-gcm` and `sm4-ccm`\n\n -- ty <zonyitoo@gmail.com>  Sat, 17 Apr 2021 22:46:39 +0800\n\nshadowsocks-rust (1.10.6) unstable; urgency=medium\n\n  ## Features\n\n  - [shadowsocks/shadowsocks-crypto#8](https://github.com/shadowsocks/shadowsocks-crypto/issues/8) Support non-standard AEAD ciphers with `crypto2`, could be enabled by feature `aead-cipher-extra`\n    - `aes-128-ccm`, `aes-256-ccm`\n    - `aes-128-gcm-siv`, `aes-256-gcm-siv`\n    - `aes-128-ocb-taglen128`, `aes-192-ocb-taglen128`, `aes-256-ocb-taglen128`\n    - `aes-siv-cmac-256`, `aes-siv-cmac-384`, `aes-siv-cmac-512`\n    - `xchacha20-ietf-poly1305`\n\n  ## Bug Fixes\n\n  - [shadowsocks/shadowsocks-android#2705](https://github.com/shadowsocks/shadowsocks-android/issues/2705) MD5 algorithm bug causes KDF (Key Derived Function) produces wrong key when `LEN(password) % 64 in [50, 64)`\n\n -- ty <zonyitoo@gmail.com>  Sat, 17 Apr 2021 21:45:46 +0800\n\nshadowsocks-rust (1.10.5) unstable; urgency=medium\n\n  ## BUG Fixed\n\n  - `ProxyClientStream` should keep the concatenated first packet buffer alive before asynchronous `write()` finishes\n\n -- ty <zonyitoo@gmail.com>  Sat, 10 Apr 2021 09:07:52 +0800\n\nshadowsocks-rust (1.10.4) unstable; urgency=medium\n\n  # Fixed BUG\n\n  - `ProxyClientStream::poll_write` may lose the `Address` in the packet to be sent if socket returns `EAGAIN`\n\n  # Features\n\n  - Support `protocol` in basic configuration format\n\n -- ty <zonyitoo@gmail.com>  Fri, 9 Apr 2021 17:25:04 +0800\n\nshadowsocks-rust (1.10.3) unstable; urgency=medium\n\n  ## BUG Fixed\n\n  - #472 Fixed `SO_INCOMING_CPU` when building on some Linux targets. rust-lang/socket2#213\n\n -- ty <zonyitoo@gmail.com>  Wed, 7 Apr 2021 09:55:40 +0800\n\nshadowsocks-rust (1.10.2) unstable; urgency=medium\n\n  ## BUG Fixed\n\n  - `mode` in basic configuration format doesn't work for local instance\n\n -- ty <zonyitoo@gmail.com>  Sun, 28 Mar 2021 11:13:01 +0800\n\nshadowsocks-rust (1.10.1) unstable; urgency=medium\n\n  ## BUG Fixed\n\n  - #469 Compilation error on Android\n\n  ## Miscellaneous\n\n  - `sslocal` checks new local instance's parameters dependency\n    - `--protocol`, `--forward-addr`, ... will require `--local-addr` to be specified\n\n -- ty <zonyitoo@gmail.com>  Sat, 27 Mar 2021 00:13:00 +0800\n\nshadowsocks-rust (1.10.0) unstable; urgency=medium\n\n  ## Features\n\n  - #452 `sslocal` supports starting multiple instances in the same process\n      - Add `locals` in extended configuration format for specifying multiple local server instances\n      - (Android Only) Support `unix://` schema in `dns` configuration\n      - Support `tcp://` and `udp://` in `dns`configuration for setting DNS protocol. Uses both TCP and UDP if not specified.\n  - Support `quad9_https` predefined DNS servers\n  - Updated `shadowsocks-crypto` to `v0.2`, which `Cipher` implementation uses `enum` static dispatch instead of `Box`ed Trait Object for dynamic dispatch\n\n  ## BUG Fixes\n\n  - PingBalancer 2nd check will be sent 10s after 1st initialization check.\n\n  ## Breaking Changes\n\n  - `sslocal`'s command line options are now for creating a new local instance:\n      - `--local-addr`, `--forward-addr`, `-U`, `-u`, `--protocol`, ... will only applied to the local instance specified by `--local-addr`\n  - `ssserver`'s command line options are now for creating a new server instance:\n      - `-U` and `-u` will only applied to the local instance specified by `--server-addr`\n\n -- ty <zonyitoo@gmail.com>  Thu, 25 Mar 2021 18:10:00 +0800\n\nshadowsocks-rust (1.9.2) unstable; urgency=medium\n\n  ## Features\n\n  * #442 Check repeated salt after first successful decryption\n\n  ## BUG Fixes\n\n  * Redir: setting SO_REUSEPORT, SO_MARK for UDP send-back sockets\n\n -- ty <zonyitoo@gmail.com>  Fri, 6 Mar 2021 01:15:00 +0800\n\nshadowsocks-rust (1.9.1) unstable; urgency=medium\n\n  ## BUG Fixes\n\n  * #431 UdpSocket::from_std requires sockets to be non-blocked.\n\n  ## Features\n\n  * Removed avx from the default CPU features\n\n -- ty <zonyitoo@gmail.com>  Fri, 26 Feb 2021 19:01:06 +0800\n\nshadowsocks-rust (1.9.0) unstable; urgency=medium\n\n  Complete refactored the whole implementation and splits into 3 different crates:\n\n  * shadowsocks - Core feature of shadowsocks\n  * shadowsocks-service - Service library for implementing Local Server, Remote Server, Manager Server\n  * shadowsocks-rust - Binary crate for release\n\n  Replaced libsodium and libcrypto with [crypto2](https://github.com/shadowsocks/crypto2).\n\n  ## Features\n\n  * Support setting SO_MARK, SO_BINDTODEVICE on Linux\n  * Support setting SO_SNDBUF and SO_RCVBUF for TCP sockets\n  * Support [SIP008](https://github.com/shadowsocks/shadowsocks-org/issues/89 \"Online config\") extend server fields server, server_port, remarks\n  * Local DNS Relay\n      * Support sending TCP and UDP queries simultaneously\n      * Support connection reusability\n  * Remove mostly TCP timeout setting for tunnels, connections will only be killed if clients or servers close\n  * Auto-reload DNS resolver configuration from /etc/resolv.conf on *NIX platforms.\n  * [#379](https://github.com/shadowsocks/shadowsocks-rust/issues/379 \"希望通过传递参数方式，指定多线程模式下tokio启动的线程数\") Allow customizing number of worker-threads for multi-threaded scheduler.\n  * [#401](https://github.com/shadowsocks/shadowsocks-rust/issues/401 \"Lazy server disable implementation\") Support field disabled in extended server configuration\n  * Ping Balancer\n      * Treat timeouts as failures, so requests that receive no response count as failures.\n      * Increase check timeout from 2s to 5s to avoid penalties on slow servers.\n      * Increase check interval from 6s to 10s.\n  * `--outbound-bind-interface` is now supported in both Linux and macOS\n  * [#352](https://github.com/shadowsocks/shadowsocks-rust/issues/352 \"Add command line arguments to control incoming/outgoing send/receive socket OS buffer size\") Support customizing inbound and outbound sockets' SO_SNDBUF and SO_RCVBUF by command line options\n\n  ## Library Update\n\n  * [tokio v1.0](https://tokio.rs/blog/2020-12-tokio-1-0)\n  * [shadowsocks-crypto](https://github.com/shadowsocks/shadowsocks-crypto), [crypto2](https://github.com/shadowsocks/crypto2)\n\n  ## Optimization\n\n  * UDP Relays sending respond packets directly to UdpSocket instead of channel, which will significantly improve respond latency\n  * [#408](https://github.com/shadowsocks/shadowsocks-rust/issues/408 \"using crate spin without feature \"std\" causes performance problem\") Enable std features for the spin crate to enable yielding threads when spinning on waiting.\n\n  ## BUG Fixes\n\n  * For BSD systems, set IPV6_BINDANY and SO_BINDANY on SOL_SOCKET properly\n  * `trust-dns-resolver` requires explicit enables feature `dns-over-https-rustls` for DoH [#367](https://github.com/shadowsocks/shadowsocks-rust/issues/367 \"Compile error on latest `master` branch while enabling `dns-over-tls` & `dns-over-https`\")\n  * ACL domain rules should be case insensitive. Domain names are case insensitive.\n  * [shadowsocks/shadowsocks-android#2667](https://github.com/shadowsocks/shadowsocks-android/issues/2667 \"Service is down intermittently\") set timeout for protect() call to Android's VpnService\n\n  ## Miscellaneous\n\n  * Disable HTTPS outbound connection for local HTTP proxy by default. For most use cases, HTTPS should be proxied with CONNECT method.\n  * Unified UDP relay association implementation for less duplicated code.\n  * Deprecated `single-threaded` build feature, replaced by `multi-threaded`.\n  * Disable stream ciphers by default. Could be enabled with feature `stream-cipher`.\n  * Enable IPv6 dual stack mode by default when listening on `::`.\n\n -- ty <zonyitoo@gmail.com>  Mon, 22 Feb 2021 09:28:28 +0800\n\nshadowsocks-rust (1.8.23) unstable; urgency=medium\n\n  ## BUG Fixed\n\n  * Fixed REDIR client setsockopt options, IPv6 should use IPV6_TRANSPARENT on level SOL_IPV6 or IPPROTO_IPV6\n\n -- ty <zonyitoo@gmail.com>  Tue, 3 Nov 2020 01:17:47 +0800\n\nshadowsocks-rust (1.8.22) unstable; urgency=medium\n\n  ## Features\n\n  * Load balancer uses Firefox's network detection address: http://detectportal.firefox.com/success.txt\n      * The original http://dl.google.com/generate_204 is not always available all over the world\n\n  ## BUG Fixed\n\n  * ARMv6 release target (arm-unknown-linux-gnueabihf) shouldn't enable output AES instructions\n  * Moves many connection ERROR logs to DEBUG level\n\n -- ty <zonyitoo@gmail.com>  Mon, 2 Nov 2020 01:37:24 +0800\n\nshadowsocks-rust (1.8.21) unstable; urgency=medium\n\n  ## Features\n\n  * Support [SIP008](https://github.com/shadowsocks/shadowsocks-org/issues/89 \"Online config\") multi-server configuration keys: `server`, `server_port` and `remarks`:\n\n      {\n        \"servers\": [\n          {\n            \"server\": \"your.shadowsocks.server\",\n            \"server_port\": 8388,\n            \"method\": \"aes-256-gcm\",\n            \"password\": \"password\",\n            \"remarks\": \"My Shadowsocks Server\"\n          }\n        ]\n      }\n\n  * [#308](https://github.com/shadowsocks/shadowsocks-rust/issues/308 \"没有后台运行的吗？\") Supports daemonize with command line option (`-d`, `--daemonize`) on *nix platforms\n  * Switched logging facility to [log4rs](https://crates.io/crates/log4rs) for more extensible configurations\n\n  ## BUG Fixed\n\n  * [#284](https://github.com/shadowsocks/shadowsocks-rust/issues/284 \"ssurl is broken\") Fixed conflicts in ssurl command line options\n  * [#309](https://github.com/shadowsocks/shadowsocks-rust/issues/309 \"端口占用造成插件退出\") Fixed mode in add command of ssmanager\n  * [#303](https://github.com/shadowsocks/shadowsocks-rust/issues/303 \"sslocal tries to connect to servers even when network is not yet online\") Lower proxy connection error messages to DEBUG level\n  * Call sleep() if server accept() failed\n\n -- ty <zonyitoo@gmail.com>  Mon, 19 Oct 2020 09:38:47 +0800\n\nshadowsocks-rust (1.8.20) unstable; urgency=medium\n\n  ## Features\n\n  * Updated various dependencies to their latest release\n  * Lazy creating bypassed and proxied UDP associations in ACL mode\n      * Each UDP associations that running in ACL mode would create 2 file descriptors (or HANDLEs) (one for bypassed, the other for proxied) when constructing in older version\n  * UDP associations in ssserver will try to return domain name addresses when receives packets from remotes that were requested with domain name address targets.\n\n  ## BUG Fixed\n\n  * UDP associations in sslocal handled bypassed requests incorrectly, which would try to parse response packets in shadowsocks' server protocol\n\n -- ty <zonyitoo@gmail.com>  Wed, 14 Oct 2020 00:46:08 +0800\n\nshadowsocks-rust (1.8.19) unstable; urgency=medium\n\n  ## Features\n\n  * Plugin configurations in files have a new optional field plugin_args for passing command line arguments when plugin starts\n\n      {\n        \"plugin\": \"your_plugin\",\n        \"plugin_args\": [\n          \"-p\",\n          \"arg1\"\n        ]\n      }\n\n  * increase_nonce function for AEAD ciphers is optimized if sodium feature is disabled.\n  * Add arm-unknown-linux-musleabi target in releases\n  * Optimized EncryptWriter by reusing decrypting buffers\n\n -- ty <zonyitoo@gmail.com>  Sun, 11 Oct 2020 16:34:58 +0800\n\nshadowsocks-rust (1.8.18) unstable; urgency=medium\n\n  ## BUG Fixed\n\n  * [#294](https://github.com/shadowsocks/shadowsocks-rust/pull/294 \"\") UDP relay server's associations shouldn't bind to local address, which will eventually cause EADDRINUSE\n\n -- ty <zonyitoo@gmail.com>  Tue, 15 Sep 2020 10:11:43 +0800\n\nshadowsocks-rust (1.8.17) unstable; urgency=medium\n\n  ## BUG Fixed\n\n  * [#292](https://github.com/shadowsocks/shadowsocks-rust/pull/292) Hold the TCP connection if it failed to decrypt the first packet for preventing active probing.\n  * [#293](https://github.com/shadowsocks/shadowsocks-rust/pull/293) Keep server running if it fails to create UDP associations.\n\n -- ty <zonyitoo@gmail.com>  Tue, 8 Sep 2020 23:31:20 +0800\n\nshadowsocks-rust (1.8.16) unstable; urgency=medium\n\n  ## Features\n\n  * [#290](https://github.com/shadowsocks/shadowsocks-rust/pull/290) UDP's ServerClient support split() into ReadHalf and WriteHalf\n\n  ## BUG Fixed\n\n  * [#289](https://github.com/shadowsocks/shadowsocks-rust/pull/289) Fixed UDP's ServerClient data decryption\n\n -- ty <zonyitoo@gmail.com>  Thu, 20 Aug 2020 17:11:01 +0800\n\nshadowsocks-rust (1.8.15) unstable; urgency=medium\n\n  Code base are exactly the same as v1.8.14.\n\n  ## Bug Fixed\n\n  * `x86_64-unknown-linux-gnu` release should be built by cross with GLIBC_2.15\n  * `x86_64-apple-darwin` release built with invalid format sslocal (still don't know why)\n\n -- ty <zonyitoo@gmail.com>  Mon, 10 Aug 2020 01:12:54 +0800\n\nshadowsocks-rust (1.8.14) unstable; urgency=medium\n\n  ## Features\n\n  * Support customizing memory allocator by features: tcmalloc, mimalloc, jemalloc\n\n  ## BUG Fixed\n\n  * [#273](https://github.com/shadowsocks/shadowsocks-rust/issues/273) Use AtomicUsize for maximum compatibility in flow statistics\n  * [#285](https://github.com/shadowsocks/shadowsocks-rust/issues/285) Fixed binaries command line options issue causing by conflicts_with\n\n -- ty <zonyitoo@gmail.com>  Sun, 9 Aug 2020 01:06:49 +0800\n\nshadowsocks-rust (1.8.13) unstable; urgency=medium\n\n  ## Features\n\n  * Direct send data for none ciphers, prevent unnecessary data copies\n  * Feature jemalloc for enabling jemalloc allocator (use system's default allocator by default)\n  * [#272](https://github.com/shadowsocks/shadowsocks-rust/issues/272) Support customizing manager created server's bind address\n\n  ## BUG Fixed\n\n  * Client flow reports tx and rx are swapped\n  * AEAD TCP protocol must check the reserved higher 2 bits\n\n -- ty <zonyitoo@gmail.com>  Sun, 19 Jul 2020 12:17:48 +0800\n\nshadowsocks-rust (1.8.12) unstable; urgency=medium\n\n  ## Features\n\n  * [#260](https://github.com/shadowsocks/shadowsocks-rust/issues/260) sslocal supports https protocol (HTTP Proxy over TLS)\n  * [#263](https://github.com/shadowsocks/shadowsocks-rust/issues/263) UDP Associations connect() to proxies' IP to avoid re-resolving domain names for every packets\n  * [#233](https://github.com/shadowsocks/shadowsocks-rust/issues/233) sslocal supports socks4 protocol (SOCKS4/4a)\n  * Options for LRU cache in UDP relay:\n      * udp_timeout: UDP Association will be kept up to this duration (in seconds)\n      * udp_max_associations: Maximum number of UDP Associations will be kept simultaneously\n\n  ## BUG Fixed\n\n  * Removed unnecessary UDP socket wake ups\n      * Expired Associations will be cleaned by a separated task\n\n  ## BREAKING Changes\n\n  * Manager's configurations are now wrapped into ManagerConfig\n  * timeout field in Config is removed inflavored timeout in ServerConfig\n      * DNS resolving timeout is using the default configuration (5 seconds for most cases)\n      * Bypassing TCP streams won't timeout\n\n -- ty <zonyitoo@gmail.com>  Mon, 1 Jun 2020 23:48:55 +0800\n\nshadowsocks-rust (1.8.11) unstable; urgency=medium\n\n  ## Features\n\n  * [#232](https://github.com/shadowsocks/shadowsocks-rust/issues/232) Send data along with handshake (LOCAL -> REMOTE)\n  * HTTP server supports https target with both native-tls and rustls\n      * For rustls, https connections will try to negotiate h2 with ALPN\n  * shadowsocks/shadowsocks-org#161 Support none as dummy cipher's name\n  * Adding local-tunnel feature for controlling tunnel protocol\n  * [#252](https://github.com/shadowsocks/shadowsocks-rust/issues/252) Support udp_max_associations configuration option\n  * Various updates for local-dns-relay for Android integration\n\n  ## Fixed BUGs\n\n  * [#234](https://github.com/shadowsocks/shadowsocks-rust/issues/234) Ensure plugin subprocesses are killed when server is exited\n      * On *NIX platform, SIGTERM is sent to plugins for graceful exit\n  * [#237](https://github.com/shadowsocks/shadowsocks-rust/issues/237) Increase regex memory limit for ACL host rules\n  * [#240](https://github.com/shadowsocks/shadowsocks-rust/issues/240) Wait for 10 seconds for plugins to start\n  * ssserver should start plugins with PluginMode::Server\n\n  ## BREAKING Changes\n\n  * Removed Runtime's Handle for all run entry functions\n\n -- ty <zonyitoo@gmail.com>  Sat, 16 May 2020 00:20:45 +0800\n\nshadowsocks-rust (1.8.10) unstable; urgency=medium\n\n  ## Features\n\n  * Support ACL configuration\n      * Examples could be found in [shadowsocks/shadowsocks-libev](https://github.com/shadowsocks/shadowsocks-libev/tree/master/acl)\n  * sslocal supports transparent proxy protocol (experimental)\n      * TCP\n          * Linux: iptables with REDIRECT or TPROXY rules\n          * macOS: pf\n          * FreeBSD: pf or ipfw, not tested\n          * OpenBSD: pf, not tested\n      * UDP\n          * Linux: iptables with TPROXY rules\n          * FreeBSD/OpenBSD: pf, not tested\n      * Usage: Run sslocal with --protocol redir\n  * Better command line option verifications\n\n  ## Fixed BUGs\n\n  * sslocal with HTTP protocol clears [Hop-by-Hop headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers)\n  * CryptoStream is now thread safe\n  * [#222](https://github.com/shadowsocks/shadowsocks-rust/issues/222) rc4 cipher is now working\n\n  ## Miscellaneous\n\n  * Integrate into the Android's client implementation, [shadowsocks/shadowsocks-android#2452](https://github.com/shadowsocks/shadowsocks-android/issues/2452)\n      * Not finished yet, you shouldn't use them in production environment\n  * Abort on `panic!` for release builds\n  * [#223](https://github.com/shadowsocks/shadowsocks-rust/issues/223) `--log-without-time` command line option is added back\n  * [#205](https://github.com/shadowsocks/shadowsocks-rust/issues/205) `-6` command line option to resolve host names to IPv6 addresses first\n\n  ## BREAKING Changes\n\n  * Merged sstunnel and ssredir into sslocal\n  * DNS-over-HTTPS and DNS-over-TLS are disabled by default, could be enabled by features dns-over-https and dns-over-tls\n  * [#217](https://github.com/shadowsocks/shadowsocks-rust/issues/217) Logging output uses local datetime instead of UTC\n      * Logging output is now in customized format\n\n -- ty <zonyitoo@gmail.com>  Fri, 10 Apr 2020 19:39:14 +0800\n\nshadowsocks-rust (1.8.9) unstable; urgency=medium\n\n  ## Features\n\n  * ssmanager - Supports Manage Multiple Users APIs\n      * Create / Remove servers in the same tokio runtime dynamically\n  * Fallback to tokio's builtin DNS resolver (currently it is libstd's builtin) if trust-dns's resolver initialize failed\n\n  ## Fixed BUGs\n\n  * Ping tasks will panic if remote servers fail to connect for the first time\n\n -- ty <zonyitoo@gmail.com>  Thu, 13 Feb 2020 01:13:07 +0800\n\nshadowsocks-rust (1.8.8) unstable; urgency=medium\n\n  ## Features\n\n  * ssredir - (Experimental) Transparent Proxy. Currently only supports the following platforms:\n      * Linux - TCP: REDIRECT and TPROXY, UDP: TPROXY\n      * FreeBSD - TCP, UDP: ipfw\n\n  ## BUG Fixed\n\n  * Enable TCP_NODELAY for better handshaking performance, for\n      * sslocal's socks5 protocol handshaking\n      * Local and Remote server shadowsocks' IV/nonce exchanging\n  * Ensure plugins starts before listening for sslocal\n      * Eliminated those connection failures while sslocal server just started\n  * [#191](https://github.com/shadowsocks/shadowsocks-rust/issues/191) Skip IV/nonce duplication check for plain cipher\n\n  ## Miscellaneous\n\n  * Nightly builds on CircleCI: https://circleci.com/gh/shadowsocks/shadowsocks-rust\n      * Obtain release binaries in #Artifacts, for example:\n          * https://circleci.com/gh/shadowsocks/shadowsocks-rust/151#artifacts/containers/0\n\n -- ty <zonyitoo@gmail.com>  Thu, 6 Feb 2020 20:14:57 +0800\n\nshadowsocks-rust (1.8.7) unstable; urgency=medium\n\n  ## Features\n\n  * Set RLIMIT_NOFILE on *nix systems by\n      * -r, --nofile command line argument\n      * nofile key in configuration file\n\n  ## BUG Fixed\n\n  * ssserver shouldn't use local_port in configuration to bind() before connect() or sendto()\n      * Command line argument --bind-addr or -b should only accept IP or Domain\n\n -- ty <zonyitoo@gmail.com>  Mon, 13 Jan 2020 10:45:54 +0800\n\nshadowsocks-rust (1.8.6) unstable; urgency=medium\n\n  Basically the same as v1.8.5, but prints the actual error while handshaking with clients. Useful if server received a repeated IV and salt (probably replay attacks).\n\n -- ty <zonyitoo@gmail.com>  Sun, 12 Jan 2020 09:44:18 +0800\n\nshadowsocks-rust (1.8.5) unstable; urgency=medium\n\n  ## Features\n\n  * Add feature trust-dns to allow disable depending on [trust-dns-resolver](https://crates.io/crates/trust-dns-resolver)\n      * Disabling trust-dns would significantly shrink the size of binaries\n  * [#26](https://github.com/shadowsocks/shadowsocks-rust/issues/26) UDP servers will also bind() to local_address and local_port\n  * Check repeated IV / Salt for defending against replay attacks\n      * [Defend against replay attack](https://github.com/shadowsocks/shadowsocks-org/issues/44)\n\n -- ty <zonyitoo@gmail.com>  Sun, 12 Jan 2020 00:09:18 +0800\n\nshadowsocks-rust (1.8.4) unstable; urgency=medium\n\n  ## Features\n\n  * ssserver supports bind before connect to remote addresses. Can be configured by\n      * local_address and local_port in config.json\n      * -b or --bind-address in command line parameter\n      * Suggestion: Port should be set to 0 otherwise you will get EADDRINUSE\n\n  ## Breaking Changes\n\n  * ssserver won't ignore local_address and local_port in config.json\n\n -- ty <zonyitoo@gmail.com>  Thu, 9 Jan 2020 23:35:59 +0800\n\nshadowsocks-rust (1.8.3) unstable; urgency=medium\n\n  ## Enhancements\n\n  * Refactored PingBalancer for supporting customized Server Configuration structure\n      * For Example: HTTP sslocal can stores HttpClients into the ServerScore structure instead of putting them into a HashMap.\n  * Removed trust-dns feature gate, set as default.\n\n -- ty <zonyitoo@gmail.com>  Wed, 8 Jan 2020 13:42:45 +0800\n\nshadowsocks-rust (1.8.2) unstable; urgency=medium\n\n  ## Enhancements\n\n  * Refactored PingBalancer for supporting customized Server Configuration structure\n      * For Example: HTTP sslocal can stores HttpClients into the ServerScore structure instead of putting them into a HashMap.\n  * Removed trust-dns feature gate, set as default.\n\n -- ty <zonyitoo@gmail.com>  Tue, 7 Jan 2020 09:16:50 +0800\n\nshadowsocks-rust (1.8.1) unstable; urgency=medium\n\n  ## BUG Fixed\n\n  * Send crypto IV (Stream Ciphers) / Nonce (AEAD Ciphers) with the first payload in one packet.\n      * Reduced 1 RTT while handshaking with servers\n  * HTTP Proxy client Handles IPv6 URI host properly\n      * RFC 2732\n\n -- ty <zonyitoo@gmail.com>  Sun, 5 Jan 2020 16:40:19 +0800\n\nshadowsocks-rust (1.8.0) unstable; urgency=medium\n\n  ## Features\n\n  * A new binary `sstunnel`. Establish TCP and UDP tunnels to remote. Discussion: #177\n      ```\n      # Establish an UDP tunnel to 8.8.8.8:53 (just like what ssdns did in the past)\n      sstunnel -c config.json -f '8.8.8.8:53' -u\n      ```\n  * Uses `async/await` syntax (requires `rustc` version >= `v1.40.0`)\n  * Dependencies\n      * `tokio` - `v0.2`\n      * `trust-dns-resolver` - `v0.18`\n      * `libsodium-sys` (switched from `libsodium-ffi` for better build process)\n  * Ping balancer\n      * Calculate scores not only with servers' latency, but also availability\n      * Supports UDP relay\n  * Retry 3 times if it connects failed to remote proxy server automatically\n\n  ## Bug Resolved\n\n  * Refactored UDP relay. Now it works just like NAT. Discussion: #168\n  * Temporary workaround for UdpSocket `WSAECONNRESET`. Discussion: #179\n      * Ref: https://stackoverflow.com/questions/30749423/is-winsock-error-10054-wsaeconnreset-normal-with-udp-to-from-localhost\n\n  ## Breaking Changes\n\n  * Removed `ssdns`. `sstunnel` can fulfill its job.\n\n  ## Releases\n\n  * `shadowsocks-v1.8.0-stable.x86_64-unknown-linux-musl.tar.xz`\n      * SHA256 `5ec41d5a306715e455b1012de0ddaa33273970689b6df48ffbb0da5fb6083531`\n  * `shadowsocks-v1.8.0-stable.x86_64-pc-windows-gnu.zip`\n      * SHA256 `f7e23a145ca42a0ce73349263650256c9cc3e05caf637c2396699d72801d6966`\n\n -- ty <zonyitoo@gmail.com>  Sat, 28 Dec 2019 00:00:00 +0800\n\nshadowsocks-rust (1.7.0) unstable; urgency=medium\n\n  ## Refactors\n\n  * #141 Build with Rust 2018.\n  * #100 Migrated to Tokio Runtime.\n  * #139 Refactor for using as a library. Move signal monitor outside of shadowsocks library.\n\n  ## Dependencies\n\n  * Replaced `ToSocketAddrs` with `trust-dns`\n  * #111 Upgrade rand to v0.5 and use `ThreadRng`\n  * #132 Feature gate RC4 cipher\n  * `--feature miscreant` is now can be built with stable.\n\n  ## Configurations\n\n  * Support timeout key in the outer object in configuration ( `{ \"timeout\": 30 }` )\n  * UDP relay sets timeout with separated key `udp_timeout`\n  * #123 `set_nodelay` and `set_keepalive`, `no_delay` is configurable in configuration\n  * [Breaking] Replace `enable_udp` with `mode`, possible values are: `tcp_and_udp`, `tcp_only`, `udp_only`.\n\n  ## Bugfix\n\n  * [BUG-FIXED] #105 Fixed \"Too many open files\" in UDP relay.\n  * [BUG-FIXED] Fixed bug while starting UDP relay. While starting server with plugins, it should not change the listening addresses for UDP relay, which are only for TCP relay.\n  * [BUG-FIXED] #106 Server should not panic if accepted socket closed right after `accept()`.\n  * Implemented a new `ssdns` server, which can serve as a DNS server and proxy DNS queries via ShadowSocks' UDP relay.\n  * [FIXED-BUG] #118 #122 Fixed DNS resolving issue. It may failed to resolve remote server's address if you haven't configured any IP addresses in forbidden_ip section.\n\n  ## New features\n\n  * Uses `impl Trait` for functions\n  * #113 Supported `xchacha20-ietf-poly1305` encrypt method\n  * Removed all global states in client and servers, which will allow starting multiple ShadowSocks instances in one process.\n  * Uses `json5` to parse config file.\n  * #85 Support `ss-manager` report protocol. (Can co-operate with `ss-manager`)\n\n -- ty <zonyitoo@gmail.com>  Wed, 20 Jan 2019 01:14:55 +0800\n\nshadowsocks-rust (1.6.11) unstable; urgency=medium\n\n  * Updated dependencies\n\n -- ty <zonyitoo@gmail.com>  Sat, 20 Jan 2018 20:45:59 +0800\n\nshadowsocks-rust (1.6.10) unstable; urgency=medium\n\n  * Check AEAD packet length before actually reading it.\n\n -- ty <zonyitoo@gmail.com>  Sat, 2 Dec 2017 11:56:00 +0800\n\nshadowsocks-rust (1.6.9) unstable; urgency=medium\n\n  * Fixed increase_nonce without libsodium\n\n -- ty <zonyitoo@gmail.com>  Sun, 26 Nov 2017 10:28:13 UTC\n\nshadowsocks-rust (1.6.8) unstable; urgency=medium\n\n  * Upstream bump version.\n\n -- Simon Shi <simonsmh@gmail.com>  Wed, 08 Nov 2017 14:27:18 +0800\n\nshadowsocks-rust (1.6.6+deb1) unstable; urgency=medium\n\n  * Add debian files.\n  * Add systemd files and default config.\n\n -- Simon Shi <simonsmh@gmail.com>  Tue, 10 Oct 2017 10:01:14 +0800\n\nshadowsocks-rust (1.6.6) stable; urgency=medium\n\n  * Removed aes-128-ctr cipher\n\n -- ty <zonyitoo@gmail.com>  Wed, 4 Oct 2017 04:11:55 +0800\n\nshadowsocks-rust (1.6.5) unstable; urgency=medium\n\n  * Initial Release.\n\n -- Shigure Moe <feng591892871@gmail.com>  Sat, 30 Sep 2017 16:21:42 +0800\n"
  },
  {
    "path": "debian/compat",
    "content": "10\n"
  },
  {
    "path": "debian/config.json",
    "content": "{\n    \"server\": \"0.0.0.0\",\n    \"server_port\": 8388,\n    \"local_address\": \"127.0.0.1\",\n    \"local_port\": 1080,\n    \"password\": \"barfoo\",\n    \"timeout\": 300,\n    \"method\": \"chacha20-ietf-poly1305\"\n}\n"
  },
  {
    "path": "debian/control",
    "content": "Source: shadowsocks-rust\nSection: net\nPriority: optional\nMaintainer: Y. T. Chung <zonyitoo@gmail.com>\nBuild-Depends: debhelper (>=9), rustc, cargo\nStandards-Version: 3.9.6\nHomepage: https://github.com/shadowsocks/shadowsocks-rust\n\nPackage: shadowsocks-rust\nArchitecture: any\nDepends: ${shlibs:Depends}, ${misc:Depends}, lsb-base\nConflicts: shadowsocks\nDescription: Rust port of shadowsocks, a secure socks5 proxy\n Shadowsocks is a fast tunnel proxy that helps you bypass firewalls.\n Shadowsocks-rust was inspired by Shadowsocks (in Python). It's rewritten\n in rust.\n"
  },
  {
    "path": "debian/copyright",
    "content": "Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/\nUpstream-Name: shadowsocks-rust\nSource: https://github.com/shadowsocks/shadowsocks-rust\n\nFiles: *\nCopyright: 2014 Y. T. CHUNG <zonyitoo@gmail.com>\nLicense: MIT\n\nFiles: debian/*\nCopyright: 2017 Simon Shi <simonsmh@gmail.com>\nLicense: MIT\n\nLicense: MIT\n Permission is hereby granted, free of charge, to any person obtaining a\n copy of this software and associated documentation files (the \"Software\"),\n to deal in the Software without restriction, including without limitation\n the rights to use, copy, modify, merge, publish, distribute, sublicense,\n and/or sell copies of the Software, and to permit persons to whom the\n Software is furnished to do so, subject to the following conditions:\n .\n The above copyright notice and this permission notice shall be included\n in all copies or substantial portions of the Software.\n .\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, \n TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE \n SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n"
  },
  {
    "path": "debian/install",
    "content": "debian/config.json usr/share/shadowsocks-rust\ndebian/shadowsocks-rust-*.service lib/systemd/system\n\n"
  },
  {
    "path": "debian/rules",
    "content": "#!/usr/bin/make -f\n\noverride_dh_auto_build:\n\tdh_auto_build -- TARGET=release\n\noverride_dh_auto_install:\n\tdh_auto_install -- TARGET=release PREFIX=/usr/bin\n\n%:\n\tdh $@\n"
  },
  {
    "path": "debian/shadowsocks-rust-local@.service",
    "content": "#  This file is part of shadowsocks-rust.\n#\n#  This is a template unit file. Users may copy and rename the file into\n#  config directories to make new service instances. See systemd.unit(5)\n#  for details.\n\n[Unit]\nDescription=Shadowsocks-rust Custom Client Service for %I\nDocumentation=https://github.com/shadowsocks/shadowsocks-rust\nAfter=network.target\n\n[Service]\nType=simple\nCapabilityBoundingSet=CAP_NET_BIND_SERVICE\nAmbientCapabilities=CAP_NET_BIND_SERVICE\nDynamicUser=yes\nExecStart=/usr/bin/ssservice local --log-without-time -c /etc/shadowsocks-rust/%i.json\n\n[Install]\nWantedBy=multi-user.target\n\n"
  },
  {
    "path": "debian/shadowsocks-rust-server@.service",
    "content": "#  This file is part of shadowsocks-rust.\n#\n#  This is a template unit file. Users may copy and rename the file into\n#  config directories to make new service instances. See systemd.unit(5)\n#  for details.\n\n[Unit]\nDescription=Shadowsocks-rust Custom Server Service for %I\nDocumentation=https://github.com/shadowsocks/shadowsocks-rust\nAfter=network.target\n\n[Service]\nType=simple\nCapabilityBoundingSet=CAP_NET_BIND_SERVICE\nAmbientCapabilities=CAP_NET_BIND_SERVICE\nDynamicUser=yes\nExecStart=/usr/bin/ssservice server --log-without-time -c /etc/shadowsocks-rust/%i.json\n\n[Install]\nWantedBy=multi-user.target\n\n"
  },
  {
    "path": "debian/shadowsocks-rust.default",
    "content": "# Defaults for shadowsocks initscript\n# sourced by /etc/init.d/shadowsocks-rust\n# installed at /etc/default/shadowsocks-rust by the maintainer scripts\n\n#\n# This is a POSIX shell fragment\n#\n# Note: `START', `GROUP' and `MAXFD' options are not recognized by systemd.\n# Please change those settings in the corresponding systemd unit file.\n\n# Enable during startup?\nSTART=yes\n\n# Configuration file\nCONFFILE=\"/etc/shadowsocks-rust/config.json\"\n\n# Extra command line arguments\nDAEMON_ARGS=\"--log-without-time\"\n\n# User and group to run the server as\nUSER=nobody\nGROUP=nogroup\n\n# Number of maximum file descriptors\nMAXFD=32768\n"
  },
  {
    "path": "debian/shadowsocks-rust.init",
    "content": "#!/bin/sh\n### BEGIN INIT INFO\n# Provides:          shadowsocks-rust\n# Required-Start:    $network $local_fs $remote_fs\n# Required-Stop:     $remote_fs\n# Default-Start:     2 3 4 5\n# Default-Stop:      0 1 6\n# Short-Description: lightweight secured socks5 proxy\n# Description:       Rust port of shadowsocks.\n#                    shadowsocks is a fast tunnel proxy that helps you bypass firewalls.\n### END INIT INFO\n\n# Author: Simon Shi <simonsmh@gmail.com>\n\n# PATH should only include /usr/ if it runs after the mountnfs.sh script\nPATH=/sbin:/usr/sbin:/bin:/usr/bin\nDESC=shadowsocks-rust        # Introduce a short description here\nNAME=shadowsocks-rust        # Introduce the short server's name here\nDAEMON=/usr/bin/ssservice    # Introduce the server's location here\nDAEMON_ARGS=\"--log-without-time\" # Arguments to run the daemon with\nPIDFILE=/var/run/$NAME/$NAME.pid\nSCRIPTNAME=/etc/init.d/$NAME\n\n# Exit if the package is not installed\n[ -x $DAEMON ] || exit 0\n\n# Read configuration variable file if it is present\n[ -r /etc/default/$NAME ] && . /etc/default/$NAME\n\n[ \"$START\" = \"yes\" ] || exit 0\n\n: ${USER:=\"nobody\"}\n: ${GROUP:=\"nogroup\"}\n\n# Load the VERBOSE setting and other rcS variables\n. /lib/init/vars.sh\n\n# Define LSB log_* functions.\n# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.\n. /lib/lsb/init-functions\n\n#\n# Function that starts the daemon/service\n#\ndo_start()\n{\n    # Modify the file descriptor limit\n    ulimit -n ${MAXFD}\n\n    # Take care of pidfile permissions\n    mkdir /var/run/$NAME 2>/dev/null || true\n    chown \"$USER:$GROUP\" /var/run/$NAME\n\n    # Return\n    #   0 if daemon has been started\n    #   1 if daemon was already running\n    #   2 if daemon could not be started\n    start-stop-daemon --start --quiet --pidfile $PIDFILE --chuid $USER:$GROUP --exec $DAEMON server \\\n        -c \"$CONFFILE\" -f $PIDFILE $DAEMON_ARGS \\\n        || return 2\n}\n\n#\n# Function that stops the daemon/service\n#\ndo_stop()\n{\n    # Return\n    #   0 if daemon has been stopped\n    #   1 if daemon was already stopped\n    #   2 if daemon could not be stopped\n    #   other if a failure occurred\n    start-stop-daemon --stop --quiet --retry=TERM/5 --pidfile $PIDFILE --exec $DAEMON\n    RETVAL=\"$?\"\n    [ \"$RETVAL\" = 2 ] && return 2\n    # Wait for children to finish too if this is a daemon that forks\n    # and if the daemon is only ever run from this initscript.\n    # If the above conditions are not satisfied then add some other code\n    # that waits for the process to drop all resources that could be\n    # needed by services started subsequently.  A last resort is to\n    # sleep for some time.\n    start-stop-daemon --stop --quiet --oknodo --retry=KILL/5 --exec $DAEMON\n    [ \"$?\" = 2 ] && return 2\n    # Many daemons don't delete their pidfiles when they exit.\n    rm -f $PIDFILE\n    return \"$RETVAL\"\n}\n\n\ncase \"$1\" in\n    start)\n        [ \"$VERBOSE\" != no ] && log_daemon_msg \"Starting $DESC \" \"$NAME\"\n        do_start\n        case \"$?\" in\n            0|1) [ \"$VERBOSE\" != no ] && log_end_msg 0 ;;\n        2) [ \"$VERBOSE\" != no ] && log_end_msg 1 ;;\n    esac\n    ;;\nstop)\n    [ \"$VERBOSE\" != no ] && log_daemon_msg \"Stopping $DESC\" \"$NAME\"\n    do_stop\n    case \"$?\" in\n        0|1) [ \"$VERBOSE\" != no ] && log_end_msg 0 ;;\n    2) [ \"$VERBOSE\" != no ] && log_end_msg 1 ;;\nesac\n;;\n  status)\n      status_of_proc \"$DAEMON\" \"$NAME\" && exit 0 || exit $?\n      ;;\n  restart|force-reload)\n      log_daemon_msg \"Restarting $DESC\" \"$NAME\"\n      do_stop\n      case \"$?\" in\n          0|1)\n              do_start\n              case \"$?\" in\n                  0) log_end_msg 0 ;;\n              1) log_end_msg 1 ;; # Old process is still running\n          *) log_end_msg 1 ;; # Failed to start\n      esac\n      ;;\n  *)\n      # Failed to stop\n      log_end_msg 1\n      ;;\n    esac\n    ;;\n*)\n    echo \"Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}\" >&2\n    exit 3\n    ;;\nesac\n\n:\n"
  },
  {
    "path": "debian/shadowsocks-rust.postinst",
    "content": "#!/bin/sh\n\nset -e\n\n# POSIX-compliant maint function recommend by devref\n# to check for the existence of a command\n# https://www.debian.org/doc/manuals/developers-reference/ch06.html#bpp-debian-maint-scripts\npathfind() {\n\tOLDIFS=\"$IFS\"\n\tIFS=:\n\tfor p in $PATH; do\n\t\tif [ -x \"$p/$*\" ]; then\n\t\tIFS=\"$OLDIFS\"\n\t\treturn 0\n\t\tfi\n\tdone\n\tIFS=\"$OLDIFS\"\n\treturn 1\n}\n\ncase \"$1\" in\n\tconfigure|reconfigure)\n\t\tpathfind setcap && setcap \\\n\t\t\tcap_net_bind_service+ep /usr/bin/ssservice \\\n\t\t\tcap_net_bind_service+ep /usr/bin/sslocal \\\n\t\t\tcap_net_bind_service+ep /usr/bin/ssserver\n\t\tif [ ! -f /etc/shadowsocks-rust/config.json ]; then\n\t\t\tset +e\n\t\t\tpasswd=$(/usr/bin/ssservice genkey -m \"chacha20-ietf-poly1305\")\n\t\t\tpasswd=$(echo $passwd | sed \"s/+/\\\\\\\\+/g\" | sed \"s/\\\\//\\\\\\\\\\\\//g\")\n\t\t\tset -e\n\t\t\tmkdir -p /etc/shadowsocks-rust\n\t\t\tsed \"s/barfoo/$passwd/\" /usr/share/shadowsocks-rust/config.json \\\n\t\t\t\t> /etc/shadowsocks-rust/config.json\n\t\tfi\n\t\t;;\n\tabort-upgrade|abort-remove|abort-deconfigure)\n\t\texit 0\n\t\t;;\n\t*)\n\t\techo \"postinst called with unknown argument \\`$1'\" >&2\n\t\texit 0\n\t\t;;\nesac\n\n#DEBHELPER#\n\nexit 0\n"
  },
  {
    "path": "debian/shadowsocks-rust.service",
    "content": "#  This file is part of shadowsocks-rust.\n#\n#  This file is default for Debian packaging. See also\n#  /etc/default/shadowsocks-rust for environment variables.\n\n[Unit]\nDescription=Shadowsocks-rust Default Server Service\nDocumentation=https://github.com/shadowsocks/shadowsocks-rust\nAfter=network.target\n\n[Service]\nType=simple\nEnvironmentFile=/etc/default/shadowsocks-rust\nDynamicUser=yes\nLimitNOFILE=32768\nExecStart=/usr/bin/ssservice server -c ${CONFFILE} ${DAEMON_ARGS}\n\n[Install]\nWantedBy=multi-user.target\n\n"
  },
  {
    "path": "debian/source/format",
    "content": "3.0 (native)\n"
  },
  {
    "path": "deny.toml",
    "content": "# This template contains all of the possible sections and their default values\n\n# Note that all fields that take a lint level have these possible values:\n# * deny - An error will be produced and the check will fail\n# * warn - A warning will be produced, but the check will not fail\n# * allow - No warning or error will be produced, though in some cases a note\n# will be\n\n# The values provided in this template are the default values that will be used\n# when any section or field is not specified in your own configuration\n\n# Root options\n\n# The graph table configures how the dependency graph is constructed and thus\n# which crates the checks are performed against\n[graph]\n# If 1 or more target triples (and optionally, target_features) are specified,\n# only the specified targets will be checked when running `cargo deny check`.\n# This means, if a particular package is only ever used as a target specific\n# dependency, such as, for example, the `nix` crate only being used via the\n# `target_family = \"unix\"` configuration, that only having windows targets in\n# this list would mean the nix crate, as well as any of its exclusive\n# dependencies not shared by any other crates, would be ignored, as the target\n# list here is effectively saying which targets you are building for.\ntargets = [\n    # The triple can be any string, but only the target triples built in to\n    # rustc (as of 1.40) can be checked against actual config expressions\n    #\"x86_64-unknown-linux-musl\",\n    # You can also specify which target_features you promise are enabled for a\n    # particular target. target_features are currently not validated against\n    # the actual valid features supported by the target architecture.\n    #{ triple = \"wasm32-unknown-unknown\", features = [\"atomics\"] },\n]\n# When creating the dependency graph used as the source of truth when checks are\n# executed, this field can be used to prune crates from the graph, removing them\n# from the view of cargo-deny. This is an extremely heavy hammer, as if a crate\n# is pruned from the graph, all of its dependencies will also be pruned unless\n# they are connected to another crate in the graph that hasn't been pruned,\n# so it should be used with care. The identifiers are [Package ID Specifications]\n# (https://doc.rust-lang.org/cargo/reference/pkgid-spec.html)\n#exclude = []\n# If true, metadata will be collected with `--all-features`. Note that this can't\n# be toggled off if true, if you want to conditionally enable `--all-features` it\n# is recommended to pass `--all-features` on the cmd line instead\nall-features = false\n# If true, metadata will be collected with `--no-default-features`. The same\n# caveat with `all-features` applies\nno-default-features = false\n# If set, these feature will be enabled when collecting metadata. If `--features`\n# is specified on the cmd line they will take precedence over this option.\nfeatures = [\"full-extra\"]\n\n# The output table provides options for how/if diagnostics are outputted\n[output]\n# When outputting inclusion graphs in diagnostics that include features, this\n# option can be used to specify the depth at which feature edges will be added.\n# This option is included since the graphs can be quite large and the addition\n# of features from the crate(s) to all of the graph roots can be far too verbose.\n# This option can be overridden via `--feature-depth` on the cmd line\nfeature-depth = 1\n\n# This section is considered when running `cargo deny check advisories`\n# More documentation for the advisories section can be found here:\n# https://embarkstudios.github.io/cargo-deny/checks/advisories/cfg.html\n[advisories]\n# The path where the advisory databases are cloned/fetched into\n#db-path = \"$CARGO_HOME/advisory-dbs\"\n# The url(s) of the advisory databases to use\n#db-urls = [\"https://github.com/rustsec/advisory-db\"]\n# A list of advisory IDs to ignore. Note that ignored advisories will still\n# output a note when they are encountered.\nignore = [\n    #\"RUSTSEC-0000-0000\",\n    #{ id = \"RUSTSEC-0000-0000\", reason = \"you can specify a reason the advisory is ignored\" },\n    #\"a-crate-that-is-yanked@0.1.1\", # you can also ignore yanked crate versions if you wish\n    #{ crate = \"a-crate-that-is-yanked@0.1.1\", reason = \"you can specify why you are ignoring the yanked crate\" },\n]\n# If this is true, then cargo deny will use the git executable to fetch advisory database.\n# If this is false, then it uses a built-in git library.\n# Setting this to true can be helpful if you have special authentication requirements that cargo-deny does not support.\n# See Git Authentication for more information about setting up git authentication.\n#git-fetch-with-cli = true\n\n# This section is considered when running `cargo deny check licenses`\n# More documentation for the licenses section can be found here:\n# https://embarkstudios.github.io/cargo-deny/checks/licenses/cfg.html\n[licenses]\n# List of explicitly allowed licenses\n# See https://spdx.org/licenses/ for list of possible licenses\n# [possible values: any SPDX 3.11 short identifier (+ optional exception)].\nallow = [\n    \"MIT\",\n    \"Apache-2.0\",\n    \"Apache-2.0 WITH LLVM-exception\",\n    \"ISC\",\n    \"BSD-2-Clause\",\n    \"BSD-3-Clause\",\n    \"Unicode-3.0\",\n    \"MPL-2.0\",\n    \"CDLA-Permissive-2.0\",\n    \"CC0-1.0\",\n    \"0BSD\",\n    \"OpenSSL\",\n]\n# The confidence threshold for detecting a license from license text.\n# The higher the value, the more closely the license text must be to the\n# canonical license text of a valid SPDX license file.\n# [possible values: any between 0.0 and 1.0].\nconfidence-threshold = 0.8\n# Allow 1 or more licenses on a per-crate basis, so that particular licenses\n# aren't accepted for every possible crate as with the normal allow list\nexceptions = [\n    # Each entry is the crate and version constraint, and its specific allow\n    # list\n    #{ allow = [\"Zlib\"], crate = \"adler32\" },\n    { allow = [\"WTFPL\"], crate = \"tun\" },\n]\n\n# Some crates don't have (easily) machine readable licensing information,\n# adding a clarification entry for it allows you to manually specify the\n# licensing information\n#[[licenses.clarify]]\n# The package spec the clarification applies to\n#crate = \"ring\"\n# The SPDX expression for the license requirements of the crate\n#expression = \"MIT AND ISC AND OpenSSL\"\n# One or more files in the crate's source used as the \"source of truth\" for\n# the license expression. If the contents match, the clarification will be used\n# when running the license check, otherwise the clarification will be ignored\n# and the crate will be checked normally, which may produce warnings or errors\n# depending on the rest of your configuration\n#license-files = [\n# Each entry is a crate relative path, and the (opaque) hash of its contents\n#{ path = \"LICENSE\", hash = 0xbd0eed23 }\n#]\n\n[[licenses.clarify]]\nname = \"ring\"\nexpression = \"LicenseRef-ring\"\nlicense-files = [{ path = \"LICENSE\", hash = 0xbd0eed23 }]\n\n[licenses.private]\n# If true, ignores workspace crates that aren't published, or are only\n# published to private registries.\n# To see how to mark a crate as unpublished (to the official registry),\n# visit https://doc.rust-lang.org/cargo/reference/manifest.html#the-publish-field.\nignore = false\n# One or more private registries that you might publish crates to, if a crate\n# is only published to private registries, and ignore is true, the crate will\n# not have its license(s) checked\nregistries = [\n    #\"https://sekretz.com/registry\n]\n\n# This section is considered when running `cargo deny check bans`.\n# More documentation about the 'bans' section can be found here:\n# https://embarkstudios.github.io/cargo-deny/checks/bans/cfg.html\n[bans]\n# Lint level for when multiple versions of the same crate are detected\nmultiple-versions = \"warn\"\n# Lint level for when a crate version requirement is `*`\nwildcards = \"deny\"\n# The graph highlighting used when creating dotgraphs for crates\n# with multiple versions\n# * lowest-version - The path to the lowest versioned duplicate is highlighted\n# * simplest-path - The path to the version with the fewest edges is highlighted\n# * all - Both lowest-version and simplest-path are used\nhighlight = \"all\"\n# The default lint level for `default` features for crates that are members of\n# the workspace that is being checked. This can be overridden by allowing/denying\n# `default` on a crate-by-crate basis if desired.\nworkspace-default-features = \"allow\"\n# The default lint level for `default` features for external crates that are not\n# members of the workspace. This can be overridden by allowing/denying `default`\n# on a crate-by-crate basis if desired.\nexternal-default-features = \"allow\"\n# List of crates that are allowed. Use with care!\nallow = [\n    #\"ansi_term@0.11.0\",\n    #{ crate = \"ansi_term@0.11.0\", reason = \"you can specify a reason it is allowed\" },\n]\n# List of crates to deny\ndeny = [\n    #\"ansi_term@0.11.0\",\n    #{ crate = \"ansi_term@0.11.0\", reason = \"you can specify a reason it is banned\" },\n    # Wrapper crates can optionally be specified to allow the crate when it\n    # is a direct dependency of the otherwise banned crate\n    #{ crate = \"ansi_term@0.11.0\", wrappers = [\"this-crate-directly-depends-on-ansi_term\"] },\n]\n\n# List of features to allow/deny\n# Each entry the name of a crate and a version range. If version is\n# not specified, all versions will be matched.\n#[[bans.features]]\n#crate = \"reqwest\"\n# Features to not allow\n#deny = [\"json\"]\n# Features to allow\n#allow = [\n#    \"rustls\",\n#    \"__rustls\",\n#    \"__tls\",\n#    \"hyper-rustls\",\n#    \"rustls\",\n#    \"rustls-pemfile\",\n#    \"rustls-tls-webpki-roots\",\n#    \"tokio-rustls\",\n#    \"webpki-roots\",\n#]\n# If true, the allowed features must exactly match the enabled feature set. If\n# this is set there is no point setting `deny`\n#exact = true\n\n# Certain crates/versions that will be skipped when doing duplicate detection.\nskip = [\n    #\"ansi_term@0.11.0\",\n    #{ crate = \"ansi_term@0.11.0\", reason = \"you can specify a reason why it can't be updated/removed\" },\n]\n# Similarly to `skip` allows you to skip certain crates during duplicate\n# detection. Unlike skip, it also includes the entire tree of transitive\n# dependencies starting at the specified crate, up to a certain depth, which is\n# by default infinite.\nskip-tree = [\n    #\"ansi_term@0.11.0\", # will be skipped along with _all_ of its direct and transitive dependencies\n    #{ crate = \"ansi_term@0.11.0\", depth = 20 },\n]\n\n# This section is considered when running `cargo deny check sources`.\n# More documentation about the 'sources' section can be found here:\n# https://embarkstudios.github.io/cargo-deny/checks/sources/cfg.html\n[sources]\n# Lint level for what to happen when a crate from a crate registry that is not\n# in the allow list is encountered\nunknown-registry = \"deny\"\n# Lint level for what to happen when a crate from a git repository that is not\n# in the allow list is encountered\nunknown-git = \"deny\"\n# List of URLs for allowed crate registries. Defaults to the crates.io index\n# if not specified. If it is specified but empty, no registries are allowed.\nallow-registry = [\"https://github.com/rust-lang/crates.io-index\"]\n# List of URLs for allowed Git repositories\nallow-git = []\n\n[sources.allow-org]\n# github.com organizations to allow git sources for\ngithub = []\n# gitlab.com organizations to allow git sources for\ngitlab = []\n# bitbucket.org organizations to allow git sources for\nbitbucket = []\n"
  },
  {
    "path": "docker/Dockerfile.v2ray",
    "content": "FROM ghcr.io/shadowsocks/ssserver-rust:latest\n\nUSER root\n\nRUN cd /tmp && \\\n    TAG=$(wget -qO- https://api.github.com/repos/shadowsocks/v2ray-plugin/releases/latest | grep tag_name | cut -d '\"' -f4) && \\\n    wget https://github.com/shadowsocks/v2ray-plugin/releases/download/$TAG/v2ray-plugin-linux-amd64-$TAG.tar.gz && \\\n    tar -xf *.gz && \\\n    rm *.gz && \\\n    mv v2ray* /usr/bin/v2ray-plugin && \\\n    chmod +x /usr/bin/v2ray-plugin\n\nUSER nobody\n\nENTRYPOINT [ \"/docker-entrypoint.sh\" ]\nCMD [ \"ssserver\", \"--log-without-time\", \"-c\", \"/etc/shadowsocks-rust/config.json\" ]\n"
  },
  {
    "path": "docker/docker-entrypoint.sh",
    "content": "#!/bin/sh\n# vim:sw=4:ts=4:et\n\nset -e\n\nif [ -z \"${SS_ENTRYPOINT_QUIET_LOGS:-}\" ]; then\n    exec 3>&1\nelse\n    exec 3>/dev/null\nfi\n\nif [ \"$1\" = \"sslocal\" -o \"$1\" = \"ssserver\" -o \"$1\" = \"ssmanager\" -o \"$1\" = \"ssservice\" ]; then\n    if [ -f \"/etc/shadowsocks-rust/config.json\" ]; then\n        echo >&3 \"$0: Configuration complete; ready for start up\"\n    else\n        echo >&3 \"$0: No configuration files found in /etc/shadowsocks-rust, skipping configuration\"\n    fi\nfi\n\nexec \"$@\""
  },
  {
    "path": "docker/linux-cross/Dockerfile",
    "content": "ARG CROSS_BASE_IMAGE\nFROM $CROSS_BASE_IMAGE\n\nARG DEBIAN_FRONTEND=noninteractive\n\nRUN apt-get update && \\\n    apt-get install --assume-yes --no-install-recommends build-essential cmake nasm llvm-8-dev libclang-8-dev clang-8 && \\\n    git config --global --add safe.directory '*' && \\\n    rm -rf /tmp/*\n\nENV GOCACHE=/tmp\n"
  },
  {
    "path": "examples/config.json",
    "content": "{\r\n    \"server\": \"127.0.0.1\",\r\n    \"server_port\": 8388,\r\n    \"local_port\": 1080,\r\n    \"local_address\": \"127.0.0.1\",\r\n    \"password\": \"password\",\r\n    \"timeout\": 300,\r\n    \"method\": \"aes-256-gcm\"\r\n}\r\n"
  },
  {
    "path": "examples/config_ext.json",
    "content": "{\r\n    \"locals\": [\r\n        {\r\n            \"local_address\": \"127.0.0.1\",\r\n            \"local_port\": 1080\r\n        },\r\n        {\r\n            \"local_address\": \"127.0.0.1\",\r\n            \"local_port\": 3128,\r\n            \"protocol\": \"http\"\r\n        },\r\n        {\r\n            \"local_address\": \"127.0.0.1\",\r\n            \"local_port\": 53,\r\n            \"protocol\": \"tunnel\",\r\n            \"forward_address\": \"8.8.8.8\",\r\n            \"forward_port\": 53\r\n        }\r\n    ],\r\n    \"servers\": [\r\n        {\r\n            \"server\": \"127.0.0.1\",\r\n            \"server_port\": 8384,\r\n            \"password\": \"password-svr2\",\r\n            \"method\": \"chacha20-ietf-poly1305\"\r\n        },\r\n        {\r\n            \"server\": \"127.0.0.1\",\r\n            \"server_port\": 8385,\r\n            \"password\": \"password-svr3\",\r\n            \"method\": \"aes-128-gcm\"\r\n        }\r\n    ]\r\n}\r\n"
  },
  {
    "path": "homebrew/shadowsocks-rust.rb",
    "content": "class ShadowsocksRust < Formula\n  desc \"Rust port of Shadowsocks\"\n  homepage \"https://github.com/shadowsocks/shadowsocks-rust\"\n  url \"https://github.com/shadowsocks/shadowsocks-rust/archive/v1.17.2.tar.gz\"\n  sha256 \"79d3d5204fad725bd2712f29066e71d14a329c3ea956b708cb6ea64bb0316a0b\"\n  license \"MIT\"\n  head \"https://github.com/shadowsocks/shadowsocks-rust.git\", branch: \"master\"\n\n  depends_on \"rust\" => :build\n\n  def install\n    system \"cargo\", \"install\", *std_cargo_args\n    (buildpath/\"shadowsocks-rust.json\").write <<~EOS\n      {\n          \"server\":\"localhost\",\n          \"server_port\":8388,\n          \"password\":\"barfoo!\",\n          \"timeout\":600,\n          \"acl\": \"/usr/local/etc/chn.acl\",\n          \"locals\": [\n              {\n                  \"protocol\": \"socks\",\n                  \"local_address\": \"127.0.0.1\",\n                  \"local_port\": 1080\n              },\n              {\n                  \"protocol\": \"http\",\n                  \"local_address\": \"127.0.0.1\",\n                  \"local_port\": 3128\n              }\n          ]\n      }\n    EOS\n    etc.install \"shadowsocks-rust.json\"\n  end\n\n  service do\n    run [opt_bin/\"sslocal\", \"--config\", etc/\"shadowsocks-rust.json\"]\n    keep_alive true\n  end\n\n  test do\n    server_port = free_port\n    local_port = free_port\n\n    (testpath/\"server.json\").write <<~EOS\n      {\n          \"server\":\"127.0.0.1\",\n          \"server_port\":#{server_port},\n          \"password\":\"mypassword\",\n          \"method\":\"aes-256-gcm\"\n      }\n    EOS\n    (testpath/\"local.json\").write <<~EOS\n      {\n          \"server\":\"127.0.0.1\",\n          \"server_port\":#{server_port},\n          \"password\":\"mypassword\",\n          \"method\":\"aes-256-gcm\",\n          \"local_address\":\"127.0.0.1\",\n          \"local_port\":#{local_port}\n      }\n    EOS\n    fork { exec bin/\"ssserver\", \"-c\", testpath/\"server.json\" }\n    fork { exec bin/\"sslocal\", \"-c\", testpath/\"local.json\" }\n    sleep 3\n\n    output = shell_output \"curl --socks5 127.0.0.1:#{local_port} https://example.com\"\n    assert_match \"Example Domain\", output\n  end\nend\n"
  },
  {
    "path": "k8s/chart/.helmignore",
    "content": "# Patterns to ignore when building packages.\n# This supports shell glob matching, relative path matching, and\n# negation (prefixed with !). Only one pattern per line.\n.DS_Store\n# Common VCS dirs\n.git/\n.gitignore\n.bzr/\n.bzrignore\n.hg/\n.hgignore\n.svn/\n# Common backup files\n*.swp\n*.bak\n*.tmp\n*.orig\n*~\n# Various IDEs\n.project\n.idea/\n*.tmproj\n.vscode/\n"
  },
  {
    "path": "k8s/chart/Chart.yaml",
    "content": "apiVersion: v2\nname: shadowsocks-rust\ndescription: A Helm chart for shadowsocks-rust\n\n# A chart can be either an 'application' or a 'library' chart.\n#\n# Application charts are a collection of templates that can be packaged into versioned archives\n# to be deployed.\n#\n# Library charts provide useful utilities or functions for the chart developer. They're included as\n# a dependency of application charts to inject those utilities and functions into the rendering\n# pipeline. Library charts do not define any templates and therefore cannot be deployed.\ntype: application\n\n# This is the chart version. This version number should be incremented each time you make changes\n# to the chart and its templates, including the app version.\n# Versions are expected to follow Semantic Versioning (https://semver.org/)\nversion: 0.1.0\n\n# This is the version number of the application being deployed. This version number should be\n# incremented each time you make changes to the application. Versions are not expected to\n# follow Semantic Versioning. They should reflect the version the application is using.\n# It is recommended to use it with quotes.\nappVersion: \"1.x.x\"\n"
  },
  {
    "path": "k8s/chart/templates/NOTES.txt",
    "content": "{{- $port := \"<port>\" -}}\n{{- if not .Values.configMapName -}}\n{{- $port = (.Values.servers | first).server_port -}}\n{{- end -}}\n1. Get the shadowsocks URL by running these commands:\n{{- if contains \"NodePort\" .Values.service.type }}\n  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath=\"{.spec.ports[0].nodePort}\" services {{ include \"shadowsocks-rust.fullname\" . }})\n  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath=\"{.items[0].status.addresses[0].address}\")\n  echo http://$NODE_IP:$NODE_PORT\n{{- else if contains \"LoadBalancer\" .Values.service.type }}\n     NOTE: It may take a few minutes for the LoadBalancer IP to be available.\n           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include \"shadowsocks-rust.fullname\" . }}'\n  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include \"shadowsocks-rust.fullname\" . }} --template \"{{\"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}\"}}\")\n  echo http://$SERVICE_IP:{{ $port }}\n{{- else if contains \"ClusterIP\" .Values.service.type }}\n  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l \"app.kubernetes.io/name={{ include \"shadowsocks-rust.name\" . }},app.kubernetes.io/instance={{ .Release.Name }}\" -o jsonpath=\"{.items[0].metadata.name}\")\n  export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath=\"{.spec.containers[0].ports[0].containerPort}\")\n  echo \"Visit http://127.0.0.1:8080 to use your application\"\n  kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT\n{{- end }}\n"
  },
  {
    "path": "k8s/chart/templates/_helpers.tpl",
    "content": "{{/*\nExpand the name of the chart.\n*/}}\n{{- define \"shadowsocks-rust.name\" -}}\n{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix \"-\" }}\n{{- end }}\n\n{{/*\nCreate a default fully qualified app name.\nWe truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).\nIf release name contains chart name it will be used as a full name.\n*/}}\n{{- define \"shadowsocks-rust.fullname\" -}}\n{{- if .Values.fullnameOverride }}\n{{- .Values.fullnameOverride | trunc 63 | trimSuffix \"-\" }}\n{{- else }}\n{{- $name := default .Chart.Name .Values.nameOverride }}\n{{- if contains $name .Release.Name }}\n{{- .Release.Name | trunc 63 | trimSuffix \"-\" }}\n{{- else }}\n{{- printf \"%s-%s\" .Release.Name $name | trunc 63 | trimSuffix \"-\" }}\n{{- end }}\n{{- end }}\n{{- end }}\n\n{{/*\nCreate chart name and version as used by the chart label.\n*/}}\n{{- define \"shadowsocks-rust.chart\" -}}\n{{- printf \"%s-%s\" .Chart.Name .Chart.Version | replace \"+\" \"_\" | trunc 63 | trimSuffix \"-\" }}\n{{- end }}\n\n{{/*\nCommon labels\n*/}}\n{{- define \"shadowsocks-rust.labels\" -}}\nhelm.sh/chart: {{ include \"shadowsocks-rust.chart\" . }}\n{{ include \"shadowsocks-rust.selectorLabels\" . }}\n{{- if .Chart.AppVersion }}\napp.kubernetes.io/version: {{ .Chart.AppVersion | quote }}\n{{- end }}\napp.kubernetes.io/managed-by: {{ .Release.Service }}\n{{- end }}\n\n{{/*\nSelector labels\n*/}}\n{{- define \"shadowsocks-rust.selectorLabels\" -}}\napp.kubernetes.io/name: {{ include \"shadowsocks-rust.name\" . }}\napp.kubernetes.io/instance: {{ .Release.Name }}\n{{- end }}\n\n{{/*\nCreate the name of the service account to use\n*/}}\n{{- define \"shadowsocks-rust.serviceAccountName\" -}}\n{{- if .Values.serviceAccount.create }}\n{{- default (include \"shadowsocks-rust.fullname\" .) .Values.serviceAccount.name }}\n{{- else }}\n{{- default \"default\" .Values.serviceAccount.name }}\n{{- end }}\n{{- end }}\n\n{{- define \"shadowsocks-rust.portName\" -}}\n{{- if .name -}}\n{{- .name -}}\n{{- else -}}\n{{- printf \"ss-%d\" (.server_port | int) -}} \n{{- end -}}\n{{- end -}}"
  },
  {
    "path": "k8s/chart/templates/config.yaml",
    "content": "{{- if not .Values.configMapName -}}\nkind: ConfigMap\napiVersion: v1\nmetadata:\n  name: {{ include \"shadowsocks-rust.fullname\" . }}\n  labels:\n    {{- include \"shadowsocks-rust.labels\" . | nindent 4 }}\ndata:\n  config.json: |\n    {\n      \"servers\": {{- .Values.servers | toPrettyJson | nindent 8 }}\n    }\n{{- end -}}"
  },
  {
    "path": "k8s/chart/templates/deployment.yaml",
    "content": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: {{ include \"shadowsocks-rust.fullname\" . }}\n  labels:\n    {{- include \"shadowsocks-rust.labels\" . | nindent 4 }}\nspec:\n  {{- if not .Values.autoscaling.enabled }}\n  replicas: {{ .Values.replicaCount }}\n  {{- end }}\n  selector:\n    matchLabels:\n      {{- include \"shadowsocks-rust.selectorLabels\" . | nindent 6 }}\n  template:\n    metadata:\n      {{- with .Values.podAnnotations }}\n      annotations:\n        {{- toYaml . | nindent 8 }}\n      {{- end }}\n      labels:\n        {{- include \"shadowsocks-rust.selectorLabels\" . | nindent 8 }}\n    spec:\n      {{- with .Values.imagePullSecrets }}\n      imagePullSecrets:\n        {{- toYaml . | nindent 8 }}\n      {{- end }}\n      serviceAccountName: {{ include \"shadowsocks-rust.serviceAccountName\" . }}\n      securityContext:\n        {{- toYaml .Values.podSecurityContext | nindent 8 }}\n      volumes:\n      - name: config\n        configMap:\n          name: {{ default (include \"shadowsocks-rust.fullname\" .) .Values.configMapName }}\n      - name: plugins\n        emptyDir: {}\n      {{- if .Values.downloadPlugins }}\n      initContainers:\n      - name: plugin-downloader\n        image: busybox\n        command:\n        - sh\n        - -c\n        - |\n          TAG=$(wget -qO- https://api.github.com/repos/shadowsocks/v2ray-plugin/releases/latest | grep tag_name | cut -d '\"' -f4)\n          wget https://github.com/shadowsocks/v2ray-plugin/releases/download/$TAG/v2ray-plugin-linux-amd64-$TAG.tar.gz\n          tar -xf *.gz\n          rm *.gz\n          mv v2ray* /usr/local/bin/v2ray-plugin\n          chmod +x /usr/local/bin/v2ray-plugin\n\n          TAG=$(wget -qO- https://api.github.com/repos/teddysun/xray-plugin/releases/latest | grep tag_name | cut -d '\"' -f4)\n          wget https://github.com/teddysun/xray-plugin/releases/download/$TAG/xray-plugin-linux-amd64-$TAG.tar.gz\n          tar -xf *.gz\n          rm *.gz\n          mv xray* /usr/local/bin/xray-plugin\n          chmod +x /usr/local/bin/xray-plugin\n        volumeMounts:\n        - name: plugins\n          mountPath: /usr/local/bin\n      {{- end }}\n      containers:\n      - name: {{ .Chart.Name }}\n        securityContext:\n          {{- toYaml .Values.securityContext | nindent 10 }}\n        image: \"{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}\"\n        imagePullPolicy: {{ .Values.image.pullPolicy }}\n        volumeMounts:\n        - name: config\n          mountPath: /etc/shadowsocks-rust\n          readOnly: true\n        - name: plugins\n          mountPath: /usr/local/bin\n        ports:\n        {{- $hostPort := .Values.hostPort -}}\n        {{- range $i, $svr := .Values.servers }}\n        - name: {{ include \"shadowsocks-rust.portName\" $svr }}\n          containerPort: {{ $svr.server_port }}\n          {{- if $hostPort }}\n          hostPort: {{ $svr.server_port }}\n          {{- end }}\n          protocol: TCP\n        {{ end -}}\n        {{- /* use the first port for health check */ -}}\n        {{- $defaultPort := (.Values.servers | first).server_port -}}\n        livenessProbe:\n          tcpSocket:\n            port: {{ $defaultPort }}\n          failureThreshold: 3\n          initialDelaySeconds: 1\n          timeoutSeconds: 1\n        readinessProbe:\n          tcpSocket:\n            port: {{ $defaultPort }}\n          initialDelaySeconds: 2\n        resources:\n          {{- toYaml .Values.resources | nindent 10 }}\n      {{- with .Values.nodeSelector }}\n      nodeSelector:\n        {{- toYaml . | nindent 8 }}\n      {{- end }}\n      {{- with .Values.affinity }}\n      affinity:\n        {{- toYaml . | nindent 8 }}\n      {{- end }}\n      {{- with .Values.tolerations }}\n      tolerations:\n        {{- toYaml . | nindent 8 }}\n      {{- end }}\n"
  },
  {
    "path": "k8s/chart/templates/hpa.yaml",
    "content": "{{- if .Values.autoscaling.enabled }}\napiVersion: autoscaling/v2beta1\nkind: HorizontalPodAutoscaler\nmetadata:\n  name: {{ include \"shadowsocks-rust.fullname\" . }}\n  labels:\n    {{- include \"shadowsocks-rust.labels\" . | nindent 4 }}\nspec:\n  scaleTargetRef:\n    apiVersion: apps/v1\n    kind: Deployment\n    name: {{ include \"shadowsocks-rust.fullname\" . }}\n  minReplicas: {{ .Values.autoscaling.minReplicas }}\n  maxReplicas: {{ .Values.autoscaling.maxReplicas }}\n  metrics:\n    {{- if .Values.autoscaling.targetCPUUtilizationPercentage }}\n    - type: Resource\n      resource:\n        name: cpu\n        targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}\n    {{- end }}\n    {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}\n    - type: Resource\n      resource:\n        name: memory\n        targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}\n    {{- end }}\n{{- end }}\n"
  },
  {
    "path": "k8s/chart/templates/service.yaml",
    "content": "apiVersion: v1\nkind: Service\nmetadata:\n  name: {{ include \"shadowsocks-rust.fullname\" . }}\n  labels:\n    {{- include \"shadowsocks-rust.labels\" . | nindent 4 }}\n  annotations:\n    {{- range $key, $value := .Values.service.annotations }}\n      {{ $key }}: {{ $value | quote }}\n    {{- end }}\nspec:\n  type: {{ .Values.service.type }}\n  ports:\n  {{- range $i, $svr := .Values.servers }}\n  - name: {{ include \"shadowsocks-rust.portName\" $svr }}\n    targetPort: {{ $svr.server_port }}\n    protocol: TCP\n    port: {{ default $svr.server_port $svr.service_port }}\n  {{ end -}}\n  selector:\n    {{- include \"shadowsocks-rust.selectorLabels\" . | nindent 4 }}\n"
  },
  {
    "path": "k8s/chart/templates/serviceaccount.yaml",
    "content": "{{- if .Values.serviceAccount.create -}}\napiVersion: v1\nkind: ServiceAccount\nmetadata:\n  name: {{ include \"shadowsocks-rust.serviceAccountName\" . }}\n  labels:\n    {{- include \"shadowsocks-rust.labels\" . | nindent 4 }}\n  {{- with .Values.serviceAccount.annotations }}\n  annotations:\n    {{- toYaml . | nindent 4 }}\n  {{- end }}\n{{- end }}\n"
  },
  {
    "path": "k8s/chart/templates/tests/test-connection.yaml",
    "content": "apiVersion: v1\nkind: Pod\nmetadata:\n  name: \"{{ include \"shadowsocks-rust.fullname\" . }}-test-connection\"\n  labels:\n    {{- include \"shadowsocks-rust.labels\" . | nindent 4 }}\n  annotations:\n    \"helm.sh/hook\": test\nspec:\n  containers:\n    - name: wget\n      image: busybox\n      command: ['wget']\n      args: ['{{ include \"shadowsocks-rust.fullname\" . }}:{{ .Values.service.port }}']\n  restartPolicy: Never\n"
  },
  {
    "path": "k8s/chart/values.yaml",
    "content": "# Default values for shadowsocks-rust.\n# This is a YAML-formatted file.\n# Declare variables to be passed into your templates.\n\n# This is the shadowsocks config which will be mount to /etc/shadowocks-rust.\n# You can put arbitrary yaml here, and it will be translated to json before mounting.\nservers:\n- server: \"::\"\n  server_port: 8388\n  service_port: 80 # the k8s service port, default to server_port\n  password: mypassword\n  method: aes-256-gcm\n  fast_open: true\n  mode: tcp_and_udp\n  # plugin: v2ray-plugin\n  # plugin_opts: server;tls;host=github.com\n\n# Whether to download v2ray and xray plugin.\ndownloadPlugins: false\n\n# Name of the ConfigMap with config.json configuration for shadowsocks-rust.\nconfigMapName: \"\"\n\nservice:\n  # Change to LoadBalancer if you are behind a cloud provider like aws, gce, or tke.\n  type: ClusterIP\n  # external-dns.alpha.kubernetes.io/hostname: socks.example.com\n  annotations: {}\n\n# Bind shadowsocks port port to host, i.e., we can use host:port to access shawdowsocks server.\nhostPort: false\n\nreplicaCount: 1\n\nimage:\n  repository: ghcr.io/shadowsocks/ssserver-rust\n  pullPolicy: IfNotPresent\n  # Overrides the image tag whose default is the chart appVersion.\n  tag: \"latest\"\n\nimagePullSecrets: []\nnameOverride: \"\"\nfullnameOverride: \"\"\n\nserviceAccount:\n  # Specifies whether a service account should be created\n  create: true\n  # Annotations to add to the service account\n  annotations: {}\n  # The name of the service account to use.\n  # If not set and create is true, a name is generated using the fullname template\n  name: \"\"\n\npodAnnotations: {}\n\npodSecurityContext:\n  {}\n  # fsGroup: 2000\n\nsecurityContext:\n  {}\n  # capabilities:\n  #   drop:\n  #   - ALL\n  # readOnlyRootFilesystem: true\n  # runAsNonRoot: true\n  # runAsUser: 1000\n\nresources:\n  # We usually recommend not to specify default resources and to leave this as a conscious\n  # choice for the user. This also increases chances charts run on environments with little\n  # resources, such as Minikube. If you do want to specify resources, uncomment the following\n  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.\n  limits:\n    cpu: 100m\n    memory: 128Mi\n  requests:\n    cpu: 20m\n    memory: 32Mi\n\nautoscaling:\n  enabled: false\n  minReplicas: 1\n  maxReplicas: 100\n  targetCPUUtilizationPercentage: 80\n  # targetMemoryUtilizationPercentage: 80\n\nnodeSelector: {}\n\ntolerations: []\n\naffinity: {}\n"
  },
  {
    "path": "k8s/shadowsocks-rust.yaml",
    "content": "---\n# Source: shadowsocks-rust/templates/serviceaccount.yaml\napiVersion: v1\nkind: ServiceAccount\nmetadata:\n  name: shadowsocks-rust\n  labels:\n    helm.sh/chart: shadowsocks-rust-0.1.0\n    app.kubernetes.io/name: shadowsocks-rust\n    app.kubernetes.io/instance: shadowsocks-rust\n    app.kubernetes.io/version: \"1.x.x\"\n    app.kubernetes.io/managed-by: Helm\n---\n# Source: shadowsocks-rust/templates/config.yaml\nkind: ConfigMap\napiVersion: v1\nmetadata:\n  name: shadowsocks-rust\n  labels:\n    helm.sh/chart: shadowsocks-rust-0.1.0\n    app.kubernetes.io/name: shadowsocks-rust\n    app.kubernetes.io/instance: shadowsocks-rust\n    app.kubernetes.io/version: \"1.x.x\"\n    app.kubernetes.io/managed-by: Helm\ndata:\n  config.json: |\n    {\n      \"servers\":\n        [\n          {\n            \"fast_open\": true,\n            \"method\": \"aes-256-gcm\",\n            \"mode\": \"tcp_and_udp\",\n            \"password\": \"mypassword\",\n            \"server\": \"::\",\n            \"server_port\": 8388,\n            \"service_port\": 80\n          }\n        ]\n    }\n---\n# Source: shadowsocks-rust/templates/service.yaml\napiVersion: v1\nkind: Service\nmetadata:\n  name: shadowsocks-rust\n  labels:\n    helm.sh/chart: shadowsocks-rust-0.1.0\n    app.kubernetes.io/name: shadowsocks-rust\n    app.kubernetes.io/instance: shadowsocks-rust\n    app.kubernetes.io/version: \"1.x.x\"\n    app.kubernetes.io/managed-by: Helm\nspec:\n  type: ClusterIP\n  ports:\n  - name: ss-8388\n    targetPort: 8388\n    protocol: TCP\n    port: 80\n  selector:\n    app.kubernetes.io/name: shadowsocks-rust\n    app.kubernetes.io/instance: shadowsocks-rust\n---\n# Source: shadowsocks-rust/templates/deployment.yaml\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: shadowsocks-rust\n  labels:\n    helm.sh/chart: shadowsocks-rust-0.1.0\n    app.kubernetes.io/name: shadowsocks-rust\n    app.kubernetes.io/instance: shadowsocks-rust\n    app.kubernetes.io/version: \"1.x.x\"\n    app.kubernetes.io/managed-by: Helm\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app.kubernetes.io/name: shadowsocks-rust\n      app.kubernetes.io/instance: shadowsocks-rust\n  template:\n    metadata:\n      labels:\n        app.kubernetes.io/name: shadowsocks-rust\n        app.kubernetes.io/instance: shadowsocks-rust\n    spec:\n      serviceAccountName: shadowsocks-rust\n      securityContext:\n        {}\n      volumes:\n      - name: config\n        configMap:\n          name: shadowsocks-rust\n      - name: plugins\n        emptyDir: {}\n      containers:\n      - name: shadowsocks-rust\n        securityContext:\n          {}\n        image: \"ghcr.io/shadowsocks/ssserver-rust:latest\"\n        imagePullPolicy: IfNotPresent\n        volumeMounts:\n        - name: config\n          mountPath: /etc/shadowsocks-rust\n          readOnly: true\n        - name: plugins\n          mountPath: /usr/local/bin\n        ports:\n        - name: ss-8388\n          containerPort: 8388\n          protocol: TCP\n        livenessProbe:\n          tcpSocket:\n            port: 8388\n          failureThreshold: 3\n          initialDelaySeconds: 1\n          timeoutSeconds: 1\n        readinessProbe:\n          tcpSocket:\n            port: 8388\n          initialDelaySeconds: 2\n        resources:\n          limits:\n            cpu: 100m\n            memory: 128Mi\n          requests:\n            cpu: 20m\n            memory: 32Mi\n---\n# Source: shadowsocks-rust/templates/tests/test-connection.yaml\napiVersion: v1\nkind: Pod\nmetadata:\n  name: \"shadowsocks-rust-test-connection\"\n  labels:\n    helm.sh/chart: shadowsocks-rust-0.1.0\n    app.kubernetes.io/name: shadowsocks-rust\n    app.kubernetes.io/instance: shadowsocks-rust\n    app.kubernetes.io/version: \"1.x.x\"\n    app.kubernetes.io/managed-by: Helm\n  annotations:\n    \"helm.sh/hook\": test\nspec:\n  containers:\n    - name: wget\n      image: busybox\n      command: ['wget']\n      args: ['shadowsocks-rust:']\n  restartPolicy: Never\n"
  },
  {
    "path": "rustfmt.toml",
    "content": "edition = \"2021\"\nmax_width = 120\n#indent_style = \"Visual\"\n#fn_call_width = 120\nreorder_imports = true\nreorder_modules = true\n#reorder_imports_in_group = true\n#reorder_imported_names = true\ncondense_wildcard_suffixes = true\n#fn_args_layout = \"Visual\"\n#fn_call_style = \"Visual\"\n#chain_indent = \"Visual\"\nnormalize_comments = true\nuse_try_shorthand = true\nreorder_impl_items = true\n#use_small_heuristics = \"Max\"\nimports_layout = \"HorizontalVertical\"\n#imports_granularity = \"Crate\"\n"
  },
  {
    "path": "selinux/README.md",
    "content": "# Shadowsocks SELinux Policy\n\n## Prerequisites\n\nInstall required SELinux development tools:\n```bash\ndnf upgrade && dnf install setools-console policycoreutils-python-utils selinux-policy-devel make\n```\n\n## Creating SELinux Policy\n\n### 1. Compile the policy\n\n```bash\nmake -f /usr/share/selinux/devel/Makefile shadowsocks.pp\n```\n\n### 2. Install the policy module\n\n```bash\nsemodule -i shadowsocks.pp\n```\n\n## Apply File Contexts\n\n### 1. Add file context mappings\n\n```bash\nsemanage fcontext -a -t shadowsocks_exec_t \"/usr/bin/ssservice\"\nsemanage fcontext -a -t shadowsocks_conf_t \"/etc/shadowsocks(/.*)?\"\nsemanage fcontext -a -t shadowsocks_unit_file_t \"/usr/lib/systemd/system/ss-server@.*\\.service\"\n```\n\n### 2. Apply contexts to files\n\n```bash\nrestorecon -v /etc/systemd/system/ss-server@.service\nrestorecon -R /usr/bin/ssservice /etc/shadowsocks\n```\n\n### 3. Start the service\n\n```bash\nsystemctl start ss-server@main\n```\n\n### 4. Verify the policy is working\n\n```bash\n# Check that shadowsocks is running in the correct domain\nps -eZ | grep ssservice\n# Should show: system_u:system_r:shadowsocks_t:s0 (not unconfined_service_t)\n```\n\n## Troubleshooting\n### Check for SELinux denials\n\n```bash\n# View recent AVC denials\nausearch -m avc -ts recent | grep denied\n\n# Generate additional policy rules if needed\nausearch -m avc -ts recent | grep shadowsocks | audit2allow\n```\n\n### Update policy if needed\n\nIf you need to add more permissions:\n\n```bash\n# Edit shadowsocks.te file\n# Recompile and update\nmake -f /usr/share/selinux/devel/Makefile shadowsocks.pp\nsemodule -u shadowsocks.pp\n```\n\n### Remove policy (if needed)\n\n```bash\n# Remove file contexts first\nsemanage fcontext -d \"/usr/bin/ssservice\"\nsemanage fcontext -d \"/etc/shadowsocks(/.*)?\"\nsemanage fcontext -d \"/usr/lib/systemd/system/ss-server@.*\\.service\"\n\n# Reset file labels\nrestorecon -F /usr/bin/ssservice\nrestorecon -RF /etc/shadowsocks\n\n# Remove the policy module\nsemodule -r shadowsocks\n```\n\n## Security Benefits\n\nThis policy provides several security improvements over running shadowsocks as `unconfined_service_t`:\n\n- **Principle of least privilege**: Only grants necessary permissions\n- **Network isolation**: Controls which ports and connections are allowed\n- **File system protection**: Restricts file access to configuration and required system files\n- **Process isolation**: Runs in a dedicated SELinux domain\n- **Audit trail**: All access attempts are logged for security monitoring\n\n## Notes\n\n- The policy includes optional monitoring features (cgroup access, DNS watching)\n- File contexts use equivalency rules between `/etc/systemd/system` and `/usr/lib/systemd/system`\n"
  },
  {
    "path": "selinux/shadowsocks.fc",
    "content": "/usr/bin/ssservice              --      gen_context(system_u:object_r:shadowsocks_exec_t,s0)\n/etc/shadowsocks(/.*)?          --      gen_context(system_u:object_r:shadowsocks_conf_t,s0)\n/usr/lib/systemd/system/ss-server@.*\\.service  --      gen_context(system_u:object_r:shadowsocks_unit_file_t,s0)\n"
  },
  {
    "path": "selinux/shadowsocks.te",
    "content": "policy_module(shadowsocks, 1.0.0)\n\n########################################\n#\n# Declarations\n#\n\ntype shadowsocks_t;\ntype shadowsocks_exec_t;\ninit_daemon_domain(shadowsocks_t, shadowsocks_exec_t)\n\ntype shadowsocks_conf_t;\nfiles_config_file(shadowsocks_conf_t)\n\ntype shadowsocks_unit_file_t;\nsystemd_unit_file(shadowsocks_unit_file_t)\n\n########################################\n#\n# shadowsocks local policy\n#\n\n# Domain transition rules\ndomain_auto_trans(init_t, shadowsocks_exec_t, shadowsocks_t)\nallow init_t shadowsocks_t:process2 nnp_transition;\n\n# Allow shadowsocks to use its own executable as entrypoint\nallow shadowsocks_t shadowsocks_exec_t:file { entrypoint ioctl lock };\n\n# Network sockets\nallow shadowsocks_t self:tcp_socket create_stream_socket_perms;\nallow shadowsocks_t self:udp_socket create_socket_perms;\nallow shadowsocks_t self:process signal_perms;\n\n# Configuration files\nallow shadowsocks_t shadowsocks_conf_t:file read_file_perms;\nallow shadowsocks_t shadowsocks_conf_t:dir list_dir_perms;\n\n# Network access\ncorenet_tcp_bind_generic_node(shadowsocks_t)\ncorenet_udp_bind_generic_node(shadowsocks_t)\ncorenet_tcp_connect_all_ports(shadowsocks_t)\ncorenet_tcp_bind_all_ports(shadowsocks_t)\ncorenet_udp_bind_all_ports(shadowsocks_t)\n\n# System access\nkernel_read_system_state(shadowsocks_t)\ndev_read_urand(shadowsocks_t)\nfiles_read_etc_files(shadowsocks_t)\nmiscfiles_read_localization(shadowsocks_t)\nlogging_send_syslog_msg(shadowsocks_t)\n\n# Network configuration and DNS resolution\nsysnet_read_config(shadowsocks_t)\nsysnet_dns_name_resolve(shadowsocks_t)\nallow shadowsocks_t net_conf_t:file { read_file_perms watch };\n\n# Cgroup access for resource monitoring\nfs_search_cgroup_dirs(shadowsocks_t)\nfs_getattr_cgroup(shadowsocks_t)\nallow shadowsocks_t cgroup_t:file { getattr open read };\nallow shadowsocks_t cgroup_t:dir { search getattr };\n"
  },
  {
    "path": "snap/snapcraft.yaml",
    "content": "name: shadowsocks-rust\nadopt-info: shadowsocks-rust\nsummary: Rust port of Shadowsocks\ndescription: |\n  Shadowsocks Client & Server, written in Rust.\nbase: core22\ngrade: stable\nconfinement: strict\narchitectures:\n  - build-on: amd64\n  - build-on: arm64\n  - build-on: armhf\n  - build-on: ppc64el\n  - build-on: s390x\n  - build-on: riscv64\nlicense: MIT\nsource-code: https://github.com/shadowsocks/shadowsocks-rust\n\napps:\n  sslocal:\n    command: bin/sslocal\n    plugs: [network, network-bind, network-control, home]\n    aliases: [sslocal]\n\n  sslocal-daemon:\n    command: bin/sslocal\n    daemon: simple\n    install-mode: disable\n    plugs: [network, network-bind, network-control, home]\n\n  ssserver:\n    command: bin/ssserver\n    plugs: [network, network-bind, home]\n    aliases: [ssserver]\n\n  ssserver-daemon:\n    command: bin/ssserver\n    daemon: simple\n    install-mode: disable\n    plugs: [network, network-bind, home]\n\n  ssservice:\n    command: bin/ssservice\n    plugs: [network, network-bind, network-control, home]\n    aliases: [ssservice]\n\n  ssurl:\n    command: bin/ssurl\n    aliases: [ssurl]\n\n  ssmanager:\n    command: bin/ssmanager\n    plugs: [network, network-bind, home]\n    aliases: [ssmanager]\n\npassthrough:\n  layout:\n    /etc/shadowsocks-rust:\n      bind: $SNAP_COMMON/etc/shadowsocks-rust\n\nparts:\n  shadowsocks-rust:\n    plugin: rust\n    source: https://github.com/shadowsocks/shadowsocks-rust.git\n    rust-channel: stable\n    rust-features: [full]\n    override-pull: |\n      craftctl default\n      craftctl set version=`git describe --tags --long | sed 's/\\([^-]*-g\\)/r\\1/;s/-/./g'`\n    build-packages:\n      - rustc\n      - cargo\n      - cmake\n      - bindgen\n      - llvm-dev\n      - libclang-dev\n      - clang\n"
  },
  {
    "path": "src/allocator/mod.rs",
    "content": "//! Memory allocator\n\n#[cfg(feature = \"jemalloc\")]\n#[global_allocator]\nstatic ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;\n\n#[cfg(feature = \"tcmalloc\")]\n#[global_allocator]\nstatic ALLOC: tcmalloc::TCMalloc = tcmalloc::TCMalloc;\n\n#[cfg(feature = \"mimalloc\")]\n#[global_allocator]\nstatic ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc;\n\n#[cfg(feature = \"snmalloc\")]\n#[global_allocator]\nstatic ALLOC: snmalloc_rs::SnMalloc = snmalloc_rs::SnMalloc;\n\n#[cfg(feature = \"rpmalloc\")]\n#[global_allocator]\nstatic ALLOC: rpmalloc::RpMalloc = rpmalloc::RpMalloc;\n"
  },
  {
    "path": "src/config.rs",
    "content": "//! Common configuration utilities\n\nuse std::{\n    env,\n    fs::OpenOptions,\n    io::{self, Read},\n    path::{Path, PathBuf},\n};\n\nuse clap::ArgMatches;\nuse directories::ProjectDirs;\nuse serde::Deserialize;\n\n/// Default configuration file path\npub fn get_default_config_path(config_file: &str) -> Option<PathBuf> {\n    // config.json in the current working directory ($PWD)\n    let config_files = vec![config_file, \"config.json\"];\n    if let Ok(mut path) = env::current_dir() {\n        for filename in &config_files {\n            path.push(filename);\n            if path.exists() {\n                return Some(path);\n            }\n            path.pop();\n        }\n    } else {\n        // config.json in the current working directory (relative path)\n        for filename in &config_files {\n            let relative_path = PathBuf::from(filename);\n            if relative_path.exists() {\n                return Some(relative_path);\n            }\n        }\n    }\n\n    // System standard directories\n    if let Some(project_dirs) = ProjectDirs::from(\"org\", \"shadowsocks\", \"shadowsocks-rust\") {\n        // Linux: $XDG_CONFIG_HOME/shadowsocks-rust/config.json\n        //        $HOME/.config/shadowsocks-rust/config.json\n        // macOS: $HOME/Library/Application Support/org.shadowsocks.shadowsocks-rust/config.json\n        // Windows: {FOLDERID_RoamingAppData}/shadowsocks/shadowsocks-rust/config/config.json\n\n        let mut config_path = project_dirs.config_dir().to_path_buf();\n        for filename in &config_files {\n            config_path.push(filename);\n            if config_path.exists() {\n                return Some(config_path);\n            }\n            config_path.pop();\n        }\n    }\n\n    // UNIX systems, XDG Base Directory\n    // https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html\n    #[cfg(unix)]\n    {\n        let base_directories = xdg::BaseDirectories::with_prefix(\"shadowsocks-rust\");\n        // $XDG_CONFIG_HOME/shadowsocks-rust/config.json\n        // for dir in $XDG_CONFIG_DIRS; $dir/shadowsocks-rust/config.json\n        for filename in &config_files {\n            if let Some(config_path) = base_directories.find_config_file(filename) {\n                return Some(config_path);\n            }\n        }\n    }\n\n    // UNIX global configuration file\n    #[cfg(unix)]\n    {\n        let mut global_config_path = PathBuf::from(\"/etc/shadowsocks-rust\");\n        for filename in &config_files {\n            global_config_path.push(filename);\n            if global_config_path.exists() {\n                return Some(global_config_path.to_path_buf());\n            }\n            global_config_path.pop();\n        }\n    }\n\n    None\n}\n\n/// Error while reading `Config`\n#[derive(thiserror::Error, Debug)]\npub enum ConfigError {\n    /// Input/Output error\n    #[error(\"{0}\")]\n    IoError(#[from] io::Error),\n    /// JSON parsing error\n    #[error(\"{0}\")]\n    JsonError(#[from] json5::Error),\n    /// Invalid value\n    #[error(\"Invalid value: {0}\")]\n    InvalidValue(String),\n}\n\n/// Configuration Options for shadowsocks service runnables\n#[derive(Deserialize, Debug, Clone, Default)]\n#[serde(default)]\npub struct Config {\n    /// Logger configuration\n    #[cfg(feature = \"logging\")]\n    pub log: LogConfig,\n\n    /// Runtime configuration\n    pub runtime: RuntimeConfig,\n}\n\nimpl Config {\n    /// Load `Config` from file\n    pub fn load_from_file<P: AsRef<Path>>(filename: &P) -> Result<Self, ConfigError> {\n        let filename = filename.as_ref();\n\n        let mut reader = OpenOptions::new().read(true).open(filename)?;\n        let mut content = String::new();\n        reader.read_to_string(&mut content)?;\n\n        Self::load_from_str(&content)\n    }\n\n    /// Load `Config` from string\n    pub fn load_from_str(s: &str) -> Result<Self, ConfigError> {\n        json5::from_str(s).map_err(ConfigError::from)\n    }\n\n    /// Set by command line options\n    pub fn set_options(&mut self, matches: &ArgMatches) {\n        #[cfg(feature = \"logging\")]\n        {\n            let debug_level = matches.get_count(\"VERBOSE\");\n            if debug_level > 0 {\n                self.log.level = debug_level as u32;\n            }\n\n            if matches.get_flag(\"LOG_WITHOUT_TIME\") {\n                self.log.format.without_time = true;\n            }\n\n            if let Some(log_config) = matches.get_one::<PathBuf>(\"LOG_CONFIG\").cloned() {\n                self.log.config_path = Some(log_config);\n            }\n        }\n\n        #[cfg(feature = \"multi-threaded\")]\n        if matches.get_flag(\"SINGLE_THREADED\") {\n            self.runtime.mode = RuntimeMode::SingleThread;\n        }\n\n        #[cfg(feature = \"multi-threaded\")]\n        if let Some(worker_count) = matches.get_one::<usize>(\"WORKER_THREADS\") {\n            self.runtime.worker_count = Some(*worker_count);\n        }\n\n        // suppress unused warning\n        let _ = matches;\n    }\n}\n\n/// Logger configuration\n#[cfg(feature = \"logging\")]\n#[derive(Deserialize, Debug, Clone)]\n#[serde(default)]\npub struct LogConfig {\n    /// Default log level for all writers, [0, 3]\n    pub level: u32,\n    /// Default format configuration for all writers\n    pub format: LogFormatConfig,\n    /// Log writers configuration\n    pub writers: Vec<LogWriterConfig>,\n    /// Deprecated: Path to the `log4rs` config file\n    pub config_path: Option<PathBuf>,\n}\n\n#[cfg(feature = \"logging\")]\nimpl Default for LogConfig {\n    fn default() -> Self {\n        LogConfig {\n            level: 0,\n            format: LogFormatConfig::default(),\n            writers: vec![LogWriterConfig::Console(LogConsoleWriterConfig::default())],\n            config_path: None,\n        }\n    }\n}\n\n/// Logger format configuration\n#[cfg(feature = \"logging\")]\n#[derive(Deserialize, Debug, Clone, Default, Eq, PartialEq)]\n#[serde(default)]\npub struct LogFormatConfig {\n    pub without_time: bool,\n}\n\n/// Holds writer-specific configuration for logging\n#[cfg(feature = \"logging\")]\n#[derive(Deserialize, Debug, Clone)]\n#[serde(rename_all = \"snake_case\")]\npub enum LogWriterConfig {\n    Console(LogConsoleWriterConfig),\n    File(LogFileWriterConfig),\n    #[cfg(unix)]\n    Syslog(LogSyslogWriterConfig),\n}\n\n/// Console appender configuration for logging\n#[cfg(feature = \"logging\")]\n#[derive(Deserialize, Debug, Clone, Default)]\npub struct LogConsoleWriterConfig {\n    /// Level override\n    #[serde(default)]\n    pub level: Option<u32>,\n    /// Format override\n    #[serde(default)]\n    pub format: LogFormatConfigOverride,\n}\n\n/// Logger format override\n#[cfg(feature = \"logging\")]\n#[derive(Deserialize, Debug, Clone, Default)]\n#[serde(default)]\npub struct LogFormatConfigOverride {\n    pub without_time: Option<bool>,\n}\n\n/// File appender configuration for logging\n#[cfg(feature = \"logging\")]\n#[derive(Deserialize, Debug, Clone)]\npub struct LogFileWriterConfig {\n    /// Level override\n    #[serde(default)]\n    pub level: Option<u32>,\n    /// Format override\n    #[serde(default)]\n    pub format: LogFormatConfigOverride,\n\n    /// Directory to store log files\n    pub directory: PathBuf,\n    /// Rotation strategy for log files. Default is `Rotation::NEVER`.\n    #[serde(default)]\n    pub rotation: LogRotation,\n    /// Prefix for log file names. Default is the binary name.\n    #[serde(default)]\n    pub prefix: Option<String>,\n    /// Suffix for log file names. Default is \"log\".\n    #[serde(default)]\n    pub suffix: Option<String>,\n    /// Maximum number of log files to keep. Default is `None`, meaning no limit.\n    #[serde(default)]\n    pub max_files: Option<usize>,\n}\n\n/// Log rotation frequency\n#[cfg(feature = \"logging\")]\n#[derive(Deserialize, Debug, Copy, Clone, Default, Eq, PartialEq)]\n#[serde(rename_all = \"snake_case\")]\npub enum LogRotation {\n    #[default]\n    Never,\n    Hourly,\n    Daily,\n}\n\n#[cfg(feature = \"logging\")]\nimpl From<LogRotation> for tracing_appender::rolling::Rotation {\n    fn from(rotation: LogRotation) -> Self {\n        match rotation {\n            LogRotation::Never => Self::NEVER,\n            LogRotation::Hourly => Self::HOURLY,\n            LogRotation::Daily => Self::DAILY,\n        }\n    }\n}\n\n/// File appender configuration for logging\n#[cfg(all(feature = \"logging\", unix))]\n#[derive(Deserialize, Debug, Clone)]\npub struct LogSyslogWriterConfig {\n    /// Level override\n    #[serde(default)]\n    pub level: Option<u32>,\n    /// Format override\n    #[serde(default)]\n    pub format: LogFormatConfigOverride,\n\n    /// syslog identity, process name by default\n    #[serde(default)]\n    pub identity: Option<String>,\n    /// Facility, 1 (USER) by default\n    #[serde(default)]\n    pub facility: Option<i32>,\n}\n\n/// Runtime mode (Tokio)\n#[derive(Deserialize, Debug, Clone, Copy, Default, Eq, PartialEq)]\n#[serde(rename_all = \"snake_case\")]\npub enum RuntimeMode {\n    /// Single-Thread Runtime\n    #[cfg_attr(not(feature = \"multi-threaded\"), default)]\n    SingleThread,\n    /// Multi-Thread Runtime\n    #[cfg(feature = \"multi-threaded\")]\n    #[cfg_attr(feature = \"multi-threaded\", default)]\n    MultiThread,\n}\n\n/// Runtime configuration\n#[derive(Deserialize, Debug, Clone, Default)]\n#[serde(default)]\npub struct RuntimeConfig {\n    /// Multithread runtime worker count, CPU count if not configured\n    #[cfg(feature = \"multi-threaded\")]\n    pub worker_count: Option<usize>,\n    /// Runtime Mode, single-thread, multi-thread\n    pub mode: RuntimeMode,\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn test_deser_empty() {\n        // empty config should load successfully\n        let config: Config = Config::load_from_str(\"{}\").unwrap();\n        assert_eq!(config.runtime.mode, RuntimeMode::default());\n        #[cfg(feature = \"multi-threaded\")]\n        {\n            assert!(config.runtime.worker_count.is_none());\n        }\n        #[cfg(feature = \"logging\")]\n        {\n            assert_eq!(config.log.level, 0);\n            assert!(!config.log.format.without_time);\n            // default writer configuration should contain a stdout writer\n            assert_eq!(config.log.writers.len(), 1);\n            if let LogWriterConfig::Console(stdout_config) = &config.log.writers[0] {\n                assert_eq!(stdout_config.level, None);\n                assert_eq!(stdout_config.format.without_time, None);\n            } else {\n                panic!(\"Expected a stdout writer configuration\");\n            }\n        }\n    }\n\n    #[test]\n    fn test_deser_disable_logging() {\n        // allow user explicitly disable logging by providing an empty writers array\n        let config_str = r#\"\n            {\n                \"log\": {\n                    \"writers\": []\n                }\n            }\n        \"#;\n        let config: Config = Config::load_from_str(config_str).unwrap();\n        #[cfg(feature = \"logging\")]\n        {\n            assert_eq!(config.log.level, 0);\n            assert!(!config.log.format.without_time);\n            assert!(config.log.writers.is_empty());\n        }\n    }\n\n    #[test]\n    fn test_deser_file_writer_full() {\n        let config_str = r#\"\n            {\n                \"log\": {\n                    \"writers\": [\n                        {\n                            \"file\": {\n                                \"level\": 2,\n                                \"format\": {\n                                    \"without_time\": true\n                                },\n                                \"directory\": \"/var/log/shadowsocks\",\n                                \"rotation\": \"daily\",\n                                \"prefix\": \"ss-rust\",\n                                \"suffix\": \"log\",\n                                \"max_files\": 5\n                            }\n                        }\n                    ]\n                }\n            }\n        \"#;\n        let config: Config = Config::load_from_str(config_str).unwrap();\n        #[cfg(feature = \"logging\")]\n        {\n            assert_eq!(config.log.writers.len(), 1);\n            if let LogWriterConfig::File(file_config) = &config.log.writers[0] {\n                assert_eq!(file_config.level, Some(2));\n                assert_eq!(file_config.format.without_time, Some(true));\n                assert_eq!(file_config.directory, PathBuf::from(\"/var/log/shadowsocks\"));\n                assert_eq!(file_config.rotation, LogRotation::Daily);\n                assert_eq!(file_config.prefix.as_deref(), Some(\"ss-rust\"));\n                assert_eq!(file_config.suffix.as_deref(), Some(\"log\"));\n                assert_eq!(file_config.max_files, Some(5));\n            } else {\n                panic!(\"Expected a file writer configuration\");\n            }\n        }\n    }\n\n    #[test]\n    fn test_deser_file_writer_minimal() {\n        // Minimal valid file writer configuration\n        let config_str = r#\"\n            {\n                \"log\": {\n                    \"writers\": [\n                        {\n                            \"file\": {\n                                \"directory\": \"/var/log/shadowsocks\"\n                            }\n                        }\n                    ]\n                }\n            }\n        \"#;\n        let config: Config = Config::load_from_str(config_str).unwrap();\n        #[cfg(feature = \"logging\")]\n        {\n            assert_eq!(config.log.writers.len(), 1);\n            if let LogWriterConfig::File(file_config) = &config.log.writers[0] {\n                assert_eq!(file_config.level, None);\n                assert_eq!(file_config.format.without_time, None);\n                assert_eq!(file_config.directory, PathBuf::from(\"/var/log/shadowsocks\"));\n                assert_eq!(file_config.rotation, LogRotation::Never);\n                assert!(file_config.prefix.is_none());\n                assert!(file_config.suffix.is_none());\n                assert!(file_config.max_files.is_none());\n            } else {\n                panic!(\"Expected a file writer configuration\");\n            }\n        }\n    }\n    #[test]\n    fn test_deser_console_writer_full() {\n        let config_str = r#\"\n            {\n                \"log\": {\n                    \"writers\": [\n                        {\n                            \"console\": {\n                                \"level\": 1,\n                                \"format\": {\n                                    \"without_time\": false\n                                }\n                            }\n                        }\n                    ]\n                }\n            }\n        \"#;\n        let config: Config = Config::load_from_str(config_str).unwrap();\n        #[cfg(feature = \"logging\")]\n        {\n            assert_eq!(config.log.writers.len(), 1);\n            if let LogWriterConfig::Console(stdout_config) = &config.log.writers[0] {\n                assert_eq!(stdout_config.level, Some(1));\n                assert_eq!(stdout_config.format.without_time, Some(false));\n            } else {\n                panic!(\"Expected a console writer configuration\");\n            }\n        }\n    }\n\n    #[test]\n    fn test_deser_console_writer_minimal() {\n        // Minimal valid console writer configuration\n        let config_str = r#\"\n            {\n                \"log\": {\n                    \"writers\": [\n                        {\n                            \"console\": {}\n                        }\n                    ]\n                }\n            }\n        \"#;\n        let config: Config = Config::load_from_str(config_str).unwrap();\n        #[cfg(feature = \"logging\")]\n        {\n            assert_eq!(config.log.writers.len(), 1);\n            if let LogWriterConfig::Console(stdout_config) = &config.log.writers[0] {\n                assert_eq!(stdout_config.level, None);\n                assert_eq!(stdout_config.format.without_time, None);\n            } else {\n                panic!(\"Expected a console writer configuration\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/daemonize/daemonize/error.rs",
    "content": "pub type Errno = libc::c_int;\n\n/// This error type for `Daemonize` `start` method.\n#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]\npub struct Error {\n    kind: ErrorKind,\n}\n\n/// This error type for `Daemonize` `start` method.\n#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]\npub enum ErrorKind {\n    Fork(Errno),\n    Wait(Errno),\n    DetachSession(Errno),\n    GroupNotFound,\n    GroupContainsNul,\n    SetGroup(Errno),\n    UserNotFound,\n    UserContainsNul,\n    SetUser(Errno),\n    ChangeDirectory(Errno),\n    PathContainsNul,\n    OpenPidfile(Errno),\n    GetPidfileFlags(Errno),\n    SetPidfileFlags(Errno),\n    LockPidfile(Errno),\n    ChownPidfile(Errno),\n    OpenDevnull(Errno),\n    RedirectStreams(Errno),\n    CloseDevnull(Errno),\n    TruncatePidfile(Errno),\n    WritePid(Errno),\n    WritePidUnspecifiedError,\n    Chroot(Errno),\n}\n\nimpl ErrorKind {\n    fn description(&self) -> &str {\n        match self {\n            ErrorKind::Fork(_) => \"unable to fork\",\n            ErrorKind::Wait(_) => \"wait failed\",\n            ErrorKind::DetachSession(_) => \"unable to create new session\",\n            ErrorKind::GroupNotFound => \"unable to resolve group name to group id\",\n            ErrorKind::GroupContainsNul => \"group option contains NUL\",\n            ErrorKind::SetGroup(_) => \"unable to set group\",\n            ErrorKind::UserNotFound => \"unable to resolve user name to user id\",\n            ErrorKind::UserContainsNul => \"user option contains NUL\",\n            ErrorKind::SetUser(_) => \"unable to set user\",\n            ErrorKind::ChangeDirectory(_) => \"unable to change directory\",\n            ErrorKind::PathContainsNul => \"pid_file option contains NUL\",\n            ErrorKind::OpenPidfile(_) => \"unable to open pid file\",\n            ErrorKind::GetPidfileFlags(_) => \"unable get pid file flags\",\n            ErrorKind::SetPidfileFlags(_) => \"unable set pid file flags\",\n            ErrorKind::LockPidfile(_) => \"unable to lock pid file\",\n            ErrorKind::ChownPidfile(_) => \"unable to chown pid file\",\n            ErrorKind::OpenDevnull(_) => \"unable to open /dev/null\",\n            ErrorKind::RedirectStreams(_) => \"unable to redirect standard streams to /dev/null\",\n            ErrorKind::CloseDevnull(_) => \"unable to close /dev/null\",\n            ErrorKind::TruncatePidfile(_) => \"unable to truncate pid file\",\n            ErrorKind::WritePid(_) => \"unable to write self pid to pid file\",\n            ErrorKind::WritePidUnspecifiedError => \"unable to write self pid to pid file due to unknown reason\",\n            ErrorKind::Chroot(_) => \"unable to chroot into directory\",\n        }\n    }\n\n    fn errno(&self) -> Option<Errno> {\n        match self {\n            ErrorKind::Fork(errno) => Some(*errno),\n            ErrorKind::Wait(errno) => Some(*errno),\n            ErrorKind::DetachSession(errno) => Some(*errno),\n            ErrorKind::GroupNotFound => None,\n            ErrorKind::GroupContainsNul => None,\n            ErrorKind::SetGroup(errno) => Some(*errno),\n            ErrorKind::UserNotFound => None,\n            ErrorKind::UserContainsNul => None,\n            ErrorKind::SetUser(errno) => Some(*errno),\n            ErrorKind::ChangeDirectory(errno) => Some(*errno),\n            ErrorKind::PathContainsNul => None,\n            ErrorKind::OpenPidfile(errno) => Some(*errno),\n            ErrorKind::GetPidfileFlags(errno) => Some(*errno),\n            ErrorKind::SetPidfileFlags(errno) => Some(*errno),\n            ErrorKind::LockPidfile(errno) => Some(*errno),\n            ErrorKind::ChownPidfile(errno) => Some(*errno),\n            ErrorKind::OpenDevnull(errno) => Some(*errno),\n            ErrorKind::RedirectStreams(errno) => Some(*errno),\n            ErrorKind::CloseDevnull(errno) => Some(*errno),\n            ErrorKind::TruncatePidfile(errno) => Some(*errno),\n            ErrorKind::WritePid(errno) => Some(*errno),\n            ErrorKind::WritePidUnspecifiedError => None,\n            ErrorKind::Chroot(errno) => Some(*errno),\n        }\n    }\n}\n\nimpl std::fmt::Display for ErrorKind {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        f.write_str(self.description())?;\n        if let Some(errno) = self.errno() {\n            write!(f, \", errno {}\", errno)?\n        }\n        Ok(())\n    }\n}\n\nimpl std::error::Error for ErrorKind {}\n\nimpl std::fmt::Display for Error {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"{}\", self.kind)\n    }\n}\n\nimpl std::error::Error for Error {}\n\nimpl From<ErrorKind> for Error {\n    fn from(kind: ErrorKind) -> Self {\n        Self { kind }\n    }\n}\n\npub trait Num {\n    fn is_err(&self) -> bool;\n}\n\nimpl Num for i8 {\n    fn is_err(&self) -> bool {\n        *self == -1\n    }\n}\n\nimpl Num for i16 {\n    fn is_err(&self) -> bool {\n        *self == -1\n    }\n}\n\nimpl Num for i32 {\n    fn is_err(&self) -> bool {\n        *self == -1\n    }\n}\n\nimpl Num for i64 {\n    fn is_err(&self) -> bool {\n        *self == -1\n    }\n}\n\nimpl Num for isize {\n    fn is_err(&self) -> bool {\n        *self == -1\n    }\n}\n\npub fn check_err<N: Num, F: FnOnce(Errno) -> ErrorKind>(ret: N, f: F) -> Result<N, ErrorKind> {\n    if ret.is_err() { Err(f(errno())) } else { Ok(ret) }\n}\n\npub fn errno() -> Errno {\n    std::io::Error::last_os_error().raw_os_error().expect(\"errno\")\n}\n"
  },
  {
    "path": "src/daemonize/daemonize/mod.rs",
    "content": "// Copyright (c) 2016 Fedor Gogolev <knsd@knsd.net>\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! daemonize is a library for writing system daemons. Inspired by the Python library [thesharp/daemonize](https://github.com/thesharp/daemonize).\n//!\n//! The respository is located at <https://github.com/knsd/daemonize/>.\n//!\n//! Usage example:\n//!\n//! ```rust,ignore\n//! use std::fs::File;\n//!\n//! use Daemonize;\n//!\n//! fn main() {\n//!     let stdout = File::create(\"/tmp/daemon.out\").unwrap();\n//!     let stderr = File::create(\"/tmp/daemon.err\").unwrap();\n//!\n//!     let daemonize = Daemonize::new()\n//!         .pid_file(\"/tmp/test.pid\") // Every method except `new` and `start`\n//!         .chown_pid_file(true)      // is optional, see `Daemonize` documentation\n//!         .working_directory(\"/tmp\") // for default behaviour.\n//!         .user(\"nobody\")\n//!         .group(\"daemon\") // Group name\n//!         .group(2)        // or group id.\n//!         .umask(0o777)    // Set umask, `0o027` by default.\n//!         .stdout(stdout)  // Redirect stdout to `/tmp/daemon.out`.\n//!         .stderr(stderr)  // Redirect stderr to `/tmp/daemon.err`.\n//!         .privileged_action(|| \"Executed before drop privileges\");\n//!\n//!     match daemonize.start() {\n//!         Ok(_) => println!(\"Success, daemonized\"),\n//!         Err(e) => eprintln!(\"Error, {}\", e),\n//!     }\n//! }\n//! ```\n\nmod error;\n\nuse std::env::set_current_dir;\nuse std::ffi::CString;\nuse std::fmt;\nuse std::fs::File;\nuse std::os::unix::ffi::OsStringExt;\nuse std::os::unix::io::AsRawFd;\nuse std::path::{Path, PathBuf};\nuse std::process::exit;\n\nuse self::error::{ErrorKind, check_err, errno};\n\npub use self::error::Error;\n\n#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]\nenum UserImpl {\n    Name(String),\n    Id(libc::uid_t),\n}\n\n/// Expects system user id or name. If name is provided it will be resolved to id later.\n#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]\npub struct User {\n    inner: UserImpl,\n}\n\nimpl From<&str> for User {\n    fn from(t: &str) -> User {\n        User {\n            inner: UserImpl::Name(t.to_owned()),\n        }\n    }\n}\n\nimpl From<u32> for User {\n    fn from(t: u32) -> User {\n        User {\n            inner: UserImpl::Id(t as libc::uid_t),\n        }\n    }\n}\n\n#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]\nenum GroupImpl {\n    Name(String),\n    Id(libc::gid_t),\n}\n\n/// Expects system group id or name. If name is provided it will be resolved to id later.\n#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]\npub struct Group {\n    inner: GroupImpl,\n}\n\nimpl From<&str> for Group {\n    fn from(t: &str) -> Group {\n        Group {\n            inner: GroupImpl::Name(t.to_owned()),\n        }\n    }\n}\n\nimpl From<u32> for Group {\n    fn from(t: u32) -> Group {\n        Group {\n            inner: GroupImpl::Id(t as libc::gid_t),\n        }\n    }\n}\n\n/// File mode creation mask.\n#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]\npub struct Mask {\n    inner: libc::mode_t,\n}\n\nimpl From<u32> for Mask {\n    fn from(inner: u32) -> Mask {\n        Mask {\n            inner: inner as libc::mode_t,\n        }\n    }\n}\n\n#[derive(Debug)]\nenum StdioImpl {\n    Devnull,\n    RedirectToFile(File),\n    Keep,\n}\n\n/// Describes what to do with a standard I/O stream for a child process.\n#[derive(Debug)]\npub struct Stdio {\n    inner: StdioImpl,\n}\n\nimpl Stdio {\n    pub fn devnull() -> Self {\n        Self {\n            inner: StdioImpl::Devnull,\n        }\n    }\n\n    pub fn keep() -> Self {\n        Self { inner: StdioImpl::Keep }\n    }\n}\n\nimpl From<File> for Stdio {\n    fn from(file: File) -> Self {\n        Self {\n            inner: StdioImpl::RedirectToFile(file),\n        }\n    }\n}\n\n/// Parent process execution outcome.\n#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]\n#[non_exhaustive]\npub struct Parent {\n    pub first_child_exit_code: i32,\n}\n\n/// Child process execution outcome.\n#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]\n#[non_exhaustive]\npub struct Child<T> {\n    pub privileged_action_result: T,\n}\n\n/// Daemonization process outcome. Can be matched to check is it a parent process or a child\n/// process.\n#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]\npub enum Outcome<T> {\n    Parent(Result<Parent, Error>),\n    Child(Result<Child<T>, Error>),\n}\n\nimpl<T> Outcome<T> {\n    pub fn is_parent(&self) -> bool {\n        match self {\n            Outcome::Parent(_) => true,\n            Outcome::Child(_) => false,\n        }\n    }\n\n    pub fn is_child(&self) -> bool {\n        match self {\n            Outcome::Parent(_) => false,\n            Outcome::Child(_) => true,\n        }\n    }\n}\n\n/// Daemonization options.\n///\n/// Fork the process in the background, disassociate from its process group and the control terminal.\n/// Change umask value to `0o027`, redirect all standard streams to `/dev/null`. Change working\n/// directory to `/` or provided value.\n///\n/// Optionally:\n///\n///   * maintain and lock the pid-file;\n///   * drop user privileges;\n///   * drop group privileges;\n///   * change root directory;\n///   * change the pid-file ownership to provided user (and/or) group;\n///   * execute any provided action just before dropping privileges.\npub struct Daemonize<T> {\n    directory: PathBuf,\n    pid_file: Option<PathBuf>,\n    chown_pid_file: bool,\n    user: Option<User>,\n    group: Option<Group>,\n    umask: Mask,\n    root: Option<PathBuf>,\n    privileged_action: Box<dyn FnOnce() -> T>,\n    stdin: Stdio,\n    stdout: Stdio,\n    stderr: Stdio,\n}\n\nimpl<T> fmt::Debug for Daemonize<T> {\n    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {\n        fmt.debug_struct(\"Daemonize\")\n            .field(\"directory\", &self.directory)\n            .field(\"pid_file\", &self.pid_file)\n            .field(\"chown_pid_file\", &self.chown_pid_file)\n            .field(\"user\", &self.user)\n            .field(\"group\", &self.group)\n            .field(\"umask\", &self.umask)\n            .field(\"root\", &self.root)\n            .field(\"stdin\", &self.stdin)\n            .field(\"stdout\", &self.stdout)\n            .field(\"stderr\", &self.stderr)\n            .finish()\n    }\n}\n\nimpl Default for Daemonize<()> {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nimpl Daemonize<()> {\n    pub fn new() -> Self {\n        Daemonize {\n            directory: Path::new(\"/\").to_owned(),\n            pid_file: None,\n            chown_pid_file: false,\n            user: None,\n            group: None,\n            umask: 0o027.into(),\n            privileged_action: Box::new(|| ()),\n            root: None,\n            stdin: Stdio::devnull(),\n            stdout: Stdio::devnull(),\n            stderr: Stdio::devnull(),\n        }\n    }\n}\n\nimpl<T> Daemonize<T> {\n    /// Create pid-file at `path`, lock it exclusive and write daemon pid.\n    pub fn pid_file<F: AsRef<Path>>(mut self, path: F) -> Self {\n        self.pid_file = Some(path.as_ref().to_owned());\n        self\n    }\n\n    /// If `chown` is true, daemonize will change the pid-file ownership, if user or group are provided\n    pub fn chown_pid_file(mut self, chown: bool) -> Self {\n        self.chown_pid_file = chown;\n        self\n    }\n\n    /// Change working directory to `path` or `/` by default.\n    pub fn working_directory<F: AsRef<Path>>(mut self, path: F) -> Self {\n        self.directory = path.as_ref().to_owned();\n        self\n    }\n\n    /// Drop privileges to `user`.\n    pub fn user<U: Into<User>>(mut self, user: U) -> Self {\n        self.user = Some(user.into());\n        self\n    }\n\n    /// Drop privileges to `group`.\n    pub fn group<G: Into<Group>>(mut self, group: G) -> Self {\n        self.group = Some(group.into());\n        self\n    }\n\n    /// Change umask to `mask` or `0o027` by default.\n    pub fn umask<M: Into<Mask>>(mut self, mask: M) -> Self {\n        self.umask = mask.into();\n        self\n    }\n\n    /// Change root to `path`\n    pub fn chroot<F: AsRef<Path>>(mut self, path: F) -> Self {\n        self.root = Some(path.as_ref().to_owned());\n        self\n    }\n\n    /// Execute `action` just before dropping privileges. Most common use case is to open\n    /// listening socket. Result of `action` execution will be returned by `start` method.\n    pub fn privileged_action<N, F: FnOnce() -> N + 'static>(self, action: F) -> Daemonize<N> {\n        Daemonize {\n            directory: self.directory,\n            pid_file: self.pid_file,\n            chown_pid_file: self.chown_pid_file,\n            user: self.user,\n            group: self.group,\n            umask: self.umask,\n            root: self.root,\n            privileged_action: Box::new(action),\n            stdin: self.stdin,\n            stdout: self.stdout,\n            stderr: self.stderr,\n        }\n    }\n\n    /// Configuration for the child process's standard output stream.\n    pub fn stdout<S: Into<Stdio>>(mut self, stdio: S) -> Self {\n        self.stdout = stdio.into();\n        self\n    }\n\n    /// Configuration for the child process's standard error stream.\n    pub fn stderr<S: Into<Stdio>>(mut self, stdio: S) -> Self {\n        self.stderr = stdio.into();\n        self\n    }\n\n    /// Start daemonization process, terminate parent after first fork, returns privileged action\n    /// result to the child.\n    pub fn start(self) -> Result<T, Error> {\n        match self.execute() {\n            Outcome::Parent(Ok(Parent { first_child_exit_code })) => exit(first_child_exit_code),\n            Outcome::Parent(Err(err)) => Err(err),\n            Outcome::Child(Ok(child)) => Ok(child.privileged_action_result),\n            Outcome::Child(Err(err)) => Err(err),\n        }\n    }\n\n    /// Execute daemonization process, don't terminate parent after first fork.\n    pub fn execute(self) -> Outcome<T> {\n        unsafe {\n            match perform_fork() {\n                Ok(Some(first_child_pid)) => Outcome::Parent(match waitpid(first_child_pid) {\n                    Err(err) => Err(err.into()),\n                    // return value of `waitpid` may not be i32 on all platforms.\n                    #[allow(clippy::unnecessary_cast)]\n                    Ok(first_child_exit_code) => Ok(Parent {\n                        first_child_exit_code: first_child_exit_code as i32,\n                    }),\n                }),\n                Err(err) => Outcome::Parent(Err(err.into())),\n                Ok(None) => match self.execute_child() {\n                    Ok(privileged_action_result) => Outcome::Child(Ok(Child {\n                        privileged_action_result,\n                    })),\n                    Err(err) => Outcome::Child(Err(err.into())),\n                },\n            }\n        }\n    }\n\n    fn execute_child(self) -> Result<T, ErrorKind> {\n        unsafe {\n            set_current_dir(&self.directory).map_err(|_| ErrorKind::ChangeDirectory(errno()))?;\n            set_sid()?;\n            libc::umask(self.umask.inner);\n\n            let pid_file_fd = self\n                .pid_file\n                .clone()\n                .map(|pid_file| create_pid_file(pid_file))\n                .transpose()?;\n\n            if perform_fork()?.is_some() {\n                exit(0)\n            };\n\n            redirect_standard_streams(self.stdin, self.stdout, self.stderr)?;\n\n            let uid = self.user.map(|user| get_user(user)).transpose()?;\n            let gid = self.group.map(|group| get_group(group)).transpose()?;\n\n            if self.chown_pid_file {\n                let args: Option<(PathBuf, libc::uid_t, libc::gid_t)> = match (self.pid_file, uid, gid) {\n                    (Some(pid), Some(uid), Some(gid)) => Some((pid, uid, gid)),\n                    (Some(pid), None, Some(gid)) => Some((pid, libc::getuid(), gid)),\n                    (Some(pid), Some(uid), None) => Some((pid, uid, libc::getgid())),\n                    // Or pid file is not provided, or both user and group\n                    _ => None,\n                };\n\n                if let Some((pid, uid, gid)) = args {\n                    chown_pid_file(pid, uid, gid)?;\n                }\n            }\n\n            if let Some(pid_file_fd) = pid_file_fd {\n                set_cloexec_pid_file(pid_file_fd)?;\n            }\n\n            let privileged_action_result = (self.privileged_action)();\n\n            if let Some(root) = self.root {\n                change_root(root)?;\n            }\n\n            if let Some(gid) = gid {\n                set_group(gid)?;\n            }\n\n            if let Some(uid) = uid {\n                set_user(uid)?;\n            }\n\n            if let Some(pid_file_fd) = pid_file_fd {\n                write_pid_file(pid_file_fd)?;\n            }\n\n            Ok(privileged_action_result)\n        }\n    }\n}\n\nunsafe fn perform_fork() -> Result<Option<libc::pid_t>, ErrorKind> {\n    let pid = check_err(libc::fork(), ErrorKind::Fork)?;\n    if pid == 0 { Ok(None) } else { Ok(Some(pid)) }\n}\n\nunsafe fn waitpid(pid: libc::pid_t) -> Result<libc::c_int, ErrorKind> {\n    let mut child_stat = 0;\n    check_err(libc::waitpid(pid, &mut child_stat, 0), ErrorKind::Wait)?;\n    Ok(libc::WEXITSTATUS(child_stat))\n}\n\nunsafe fn set_sid() -> Result<(), ErrorKind> {\n    check_err(libc::setsid(), ErrorKind::DetachSession)?;\n    Ok(())\n}\n\nunsafe fn redirect_standard_streams(stdin: Stdio, stdout: Stdio, stderr: Stdio) -> Result<(), ErrorKind> {\n    let devnull_fd = check_err(\n        libc::open(b\"/dev/null\\0\" as *const [u8; 10] as _, libc::O_RDWR),\n        ErrorKind::OpenDevnull,\n    )?;\n\n    let process_stdio = |fd, stdio: Stdio| {\n        match stdio.inner {\n            StdioImpl::Devnull => {\n                check_err(libc::dup2(devnull_fd, fd), ErrorKind::RedirectStreams)?;\n            }\n            StdioImpl::RedirectToFile(file) => {\n                let raw_fd = file.as_raw_fd();\n                check_err(libc::dup2(raw_fd, fd), ErrorKind::RedirectStreams)?;\n            }\n            StdioImpl::Keep => (),\n        };\n        Ok(())\n    };\n\n    process_stdio(libc::STDIN_FILENO, stdin)?;\n    process_stdio(libc::STDOUT_FILENO, stdout)?;\n    process_stdio(libc::STDERR_FILENO, stderr)?;\n\n    check_err(libc::close(devnull_fd), ErrorKind::CloseDevnull)?;\n\n    Ok(())\n}\n\nunsafe fn get_group(group: Group) -> Result<libc::gid_t, ErrorKind> {\n    match group.inner {\n        GroupImpl::Id(id) => Ok(id),\n        GroupImpl::Name(name) => {\n            let s = CString::new(name).map_err(|_| ErrorKind::GroupContainsNul)?;\n            match get_gid_by_name(&s) {\n                Some(id) => get_group(id.into()),\n                None => Err(ErrorKind::GroupNotFound),\n            }\n        }\n    }\n}\n\nunsafe fn set_group(group: libc::gid_t) -> Result<(), ErrorKind> {\n    check_err(libc::setregid(group, group), ErrorKind::SetGroup)?;\n    Ok(())\n}\n\nunsafe fn get_user(user: User) -> Result<libc::uid_t, ErrorKind> {\n    match user.inner {\n        UserImpl::Id(id) => Ok(id),\n        UserImpl::Name(name) => {\n            let s = CString::new(name).map_err(|_| ErrorKind::UserContainsNul)?;\n            match get_uid_by_name(&s) {\n                Some(id) => get_user(id.into()),\n                None => Err(ErrorKind::UserNotFound),\n            }\n        }\n    }\n}\n\nunsafe fn set_user(user: libc::uid_t) -> Result<(), ErrorKind> {\n    check_err(libc::setreuid(user, user), ErrorKind::SetUser)?;\n    Ok(())\n}\n\nunsafe fn create_pid_file(path: PathBuf) -> Result<libc::c_int, ErrorKind> {\n    let path_c = pathbuf_into_cstring(path)?;\n\n    let fd = check_err(\n        libc::open(path_c.as_ptr(), libc::O_WRONLY | libc::O_CREAT, 0o666),\n        ErrorKind::OpenPidfile,\n    )?;\n\n    check_err(libc::flock(fd, libc::LOCK_EX | libc::LOCK_NB), ErrorKind::LockPidfile)?;\n    Ok(fd)\n}\n\nunsafe fn chown_pid_file(path: PathBuf, uid: libc::uid_t, gid: libc::gid_t) -> Result<(), ErrorKind> {\n    let path_c = pathbuf_into_cstring(path)?;\n    check_err(libc::chown(path_c.as_ptr(), uid, gid), ErrorKind::ChownPidfile)?;\n    Ok(())\n}\n\nunsafe fn write_pid_file(fd: libc::c_int) -> Result<(), ErrorKind> {\n    let pid = libc::getpid();\n    let pid_buf = format!(\"{}\\n\", pid).into_bytes();\n    let pid_length = pid_buf.len();\n    let pid_c = CString::new(pid_buf).unwrap();\n    check_err(libc::ftruncate(fd, 0), ErrorKind::TruncatePidfile)?;\n\n    let written = check_err(\n        libc::write(fd, pid_c.as_ptr() as *const libc::c_void, pid_length),\n        ErrorKind::WritePid,\n    )?;\n\n    if written < pid_length as isize {\n        return Err(ErrorKind::WritePidUnspecifiedError);\n    }\n\n    Ok(())\n}\n\nunsafe fn set_cloexec_pid_file(fd: libc::c_int) -> Result<(), ErrorKind> {\n    if cfg!(not(target_os = \"redox\")) {\n        let flags = check_err(libc::fcntl(fd, libc::F_GETFD), ErrorKind::GetPidfileFlags)?;\n\n        check_err(\n            libc::fcntl(fd, libc::F_SETFD, flags | libc::FD_CLOEXEC),\n            ErrorKind::SetPidfileFlags,\n        )?;\n    } else {\n        check_err(libc::ioctl(fd, libc::FIOCLEX), ErrorKind::SetPidfileFlags)?;\n    }\n    Ok(())\n}\n\nunsafe fn change_root(path: PathBuf) -> Result<(), ErrorKind> {\n    let path_c = pathbuf_into_cstring(path)?;\n    check_err(libc::chroot(path_c.as_ptr()), ErrorKind::Chroot)?;\n    Ok(())\n}\n\nunsafe fn get_gid_by_name(name: &CString) -> Option<libc::gid_t> {\n    let ptr = libc::getgrnam(name.as_ptr() as *const libc::c_char);\n    if ptr.is_null() {\n        None\n    } else {\n        let s = &*ptr;\n        Some(s.gr_gid)\n    }\n}\n\nunsafe fn get_uid_by_name(name: &CString) -> Option<libc::uid_t> {\n    let ptr = libc::getpwnam(name.as_ptr() as *const libc::c_char);\n    if ptr.is_null() {\n        None\n    } else {\n        let s = &*ptr;\n        Some(s.pw_uid)\n    }\n}\n\nfn pathbuf_into_cstring(path: PathBuf) -> Result<CString, ErrorKind> {\n    CString::new(path.into_os_string().into_vec()).map_err(|_| ErrorKind::PathContainsNul)\n}\n"
  },
  {
    "path": "src/daemonize/mod.rs",
    "content": "//! Daemonize server process\n\nuse cfg_if::cfg_if;\n\ncfg_if! {\n    if #[cfg(unix)] {\n        mod unix;\n        #[allow(unsafe_op_in_unsafe_fn, unused)]\n        #[allow(clippy::module_inception)]\n        mod daemonize;\n        pub use self::unix::daemonize;\n    } else {\n        compile_error!(\"Process daemonization is not supported by the current platform\");\n    }\n}\n"
  },
  {
    "path": "src/daemonize/unix.rs",
    "content": "use std::{env::current_dir, path::Path};\n\nuse super::daemonize::Daemonize;\nuse log::error;\n\n/// Daemonize a server process in a *nix standard way\n///\n/// This function will redirect `stdout`, `stderr` to `/dev/null`,\n/// and follow the exact behavior in shadowsocks-libev\npub fn daemonize<F: AsRef<Path>>(pid_path: Option<F>) {\n    let pwd = current_dir()\n        .unwrap_or_else(|err| panic!(\"cannot get current working directory, {err:?}\"))\n        .canonicalize()\n        .unwrap_or_else(|err| panic!(\"cannot get absolute path to working directory, {err:?}\"));\n    let mut d = Daemonize::new().umask(0).working_directory(pwd);\n\n    if let Some(p) = pid_path {\n        d = d.pid_file(p);\n    }\n\n    if let Err(err) = d.start() {\n        error!(\"failed to daemonize, {:?} ({})\", err, err);\n    }\n}\n"
  },
  {
    "path": "src/error.rs",
    "content": "//! Shadowsocks-specific error encoding.\n\n/// A result with a shadowsocks-specific error.\npub type ShadowsocksResult<T = ()> = Result<T, ShadowsocksError>;\n\n/// A generic error class which encodes all possible ways the application can\n/// fail, along with debug information.\n#[derive(Clone, Debug)]\npub enum ShadowsocksError {\n    ServerExitUnexpectedly(String),\n    ServerAborted(String),\n    LoadConfigFailure(String),\n    LoadAclFailure(String),\n    InsufficientParams(String),\n}\n\nimpl ShadowsocksError {\n    /// The corresponding `sysexits::ExitCode` for this error.\n    pub fn exit_code(&self) -> sysexits::ExitCode {\n        match self {\n            Self::ServerExitUnexpectedly(_) | Self::ServerAborted(_) => sysexits::ExitCode::Software,\n            Self::LoadConfigFailure(_) | Self::LoadAclFailure(_) => sysexits::ExitCode::Config,\n            Self::InsufficientParams(_) => sysexits::ExitCode::Usage,\n        }\n    }\n}\n\nimpl std::fmt::Display for ShadowsocksError {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            Self::ServerExitUnexpectedly(msg)\n            | Self::ServerAborted(msg)\n            | Self::LoadConfigFailure(msg)\n            | Self::LoadAclFailure(msg)\n            | Self::InsufficientParams(msg) => write!(f, \"{msg}\"),\n        }\n    }\n}\n\nimpl std::error::Error for ShadowsocksError {}\n"
  },
  {
    "path": "src/lib.rs",
    "content": "//! Shadowsocks service command line utilities\n\npub mod allocator;\npub mod config;\n#[cfg(unix)]\npub mod daemonize;\npub mod error;\n#[cfg(feature = \"logging\")]\npub mod logging;\npub mod monitor;\npub mod password;\npub mod service;\npub mod sys;\npub mod vparser;\n\n/// Build timestamp in UTC\npub const BUILD_TIME: &str = build_time::build_time_utc!();\n\n/// shadowsocks version\npub const VERSION: &str = env!(\"CARGO_PKG_VERSION\");\n"
  },
  {
    "path": "src/logging/log4rs.rs",
    "content": "//! Logging facilities with log4rs\n\nuse std::path::Path;\n\nuse log::LevelFilter;\nuse log4rs::{\n    append::console::{ConsoleAppender, Target},\n    config::{Appender, Config, Logger, Root},\n    encode::pattern::PatternEncoder,\n};\n\nuse crate::config::LogConfig;\n\n/// Initialize logger ([log4rs](https://crates.io/crates/log4rs)) from yaml configuration file\npub fn init_with_file<P>(path: P)\nwhere\n    P: AsRef<Path>,\n{\n    log4rs::init_file(path, Default::default()).expect(\"init logging with file\");\n}\n\n/// Initialize logger with provided configuration\n#[allow(dead_code)]\npub fn init_with_config(bin_name: &str, config: &LogConfig) {\n    let debug_level = config.level;\n    let without_time = config.format.without_time;\n\n    let mut pattern = String::new();\n    if !without_time {\n        pattern += \"{d} \";\n    }\n    pattern += \"{h({l}):<5} \";\n    if debug_level >= 1 {\n        pattern += \"[{P}:{I}] [{M}] \";\n    }\n    pattern += \"{m}{n}\";\n\n    let logging_builder = Config::builder().appender(\n        Appender::builder().build(\n            \"console\",\n            Box::new(\n                ConsoleAppender::builder()\n                    .encoder(Box::new(PatternEncoder::new(&pattern)))\n                    .target(Target::Stderr)\n                    .build(),\n            ),\n        ),\n    );\n\n    let (l1, l2) = match debug_level {\n        0 => (LevelFilter::Info, LevelFilter::Off),\n        1 => (LevelFilter::Debug, LevelFilter::Off),\n        2 => (LevelFilter::Trace, LevelFilter::Off),\n        3 => (LevelFilter::Trace, LevelFilter::Debug),\n        _ => (LevelFilter::Off, LevelFilter::Trace),\n    };\n\n    let config = match debug_level {\n        0..=3 => logging_builder\n            .logger(Logger::builder().build(bin_name, l1))\n            .logger(Logger::builder().build(\"shadowsocks_rust\", l1))\n            .logger(Logger::builder().build(\"shadowsocks\", l1))\n            .logger(Logger::builder().build(\"shadowsocks_service\", l1)),\n        _ => logging_builder,\n    }\n    .build(Root::builder().appender(\"console\").build(l2))\n    .expect(\"logging\");\n\n    log4rs::init_config(config).expect(\"logging\");\n}\n"
  },
  {
    "path": "src/logging/mod.rs",
    "content": "//! Logging facilities\n\nuse std::path::Path;\n\nuse log::warn;\n\nuse crate::config::LogConfig;\n\nmod log4rs;\nmod tracing;\n\n/// Initialize [log4rs](https://crates.io/crates/log4rs) from yaml configuration file\npub fn init_with_file<P>(path: P)\nwhere\n    P: AsRef<Path>,\n{\n    log4rs::init_with_file(path);\n\n    warn!(\n        \"log4rs doesn't support the tracing (https://crates.io/crates/tracing) framework, \n         so it would be removed in the future. Consider configure logging with RUST_LOG environment variable. \n         Check more configuration detail in https://docs.rs/tracing-subscriber/latest/tracing_subscriber/fmt/index.html#filtering-events-with-environment-variables .\"\n    );\n}\n\n/// Initialize logger with provided configuration\npub fn init_with_config(bin_name: &str, config: &LogConfig) {\n    tracing::init_with_config(bin_name, config);\n}\n\n/// Init a default logger\npub fn init_with_default(bin_name: &str) {\n    init_with_config(bin_name, &LogConfig::default());\n}\n"
  },
  {
    "path": "src/logging/tracing.rs",
    "content": "//! Logging facilities with tracing\n\nuse std::io::{self, IsTerminal};\n\n#[cfg(unix)]\nuse syslog_tracing::Syslog;\nuse time::{UtcOffset, format_description::well_known::Rfc3339};\nuse tracing::level_filters::LevelFilter;\nuse tracing_appender::rolling::{InitError, RollingFileAppender};\nuse tracing_subscriber::{\n    fmt::{MakeWriter, time::OffsetTime},\n    layer::SubscriberExt,\n    util::SubscriberInitExt,\n    {EnvFilter, Layer, Registry, fmt},\n};\n\n#[cfg(unix)]\nuse crate::config::LogSyslogWriterConfig;\nuse crate::config::{\n    LogConfig, LogConsoleWriterConfig, LogFileWriterConfig, LogFormatConfig, LogFormatConfigOverride, LogWriterConfig,\n};\n\n/// Initialize logger with provided configuration\npub fn init_with_config(bin_name: &str, config: &LogConfig) {\n    let layers: Vec<BoxedLayer> = config\n        .writers\n        .iter()\n        .map(|writer| writer.make_layer(bin_name, config))\n        .collect();\n    tracing_subscriber::registry().with(layers).init();\n}\n\ntype BoxedLayer = Box<dyn Layer<Registry> + Send + Sync + 'static>;\n\ntrait MakeLayer {\n    fn make_layer(&self, bin_name: &str, global: &LogConfig) -> BoxedLayer;\n}\n\nimpl MakeLayer for LogWriterConfig {\n    fn make_layer(&self, bin_name: &str, global: &LogConfig) -> BoxedLayer {\n        match self {\n            LogWriterConfig::Console(console_config) => console_config.make_layer(bin_name, global),\n            LogWriterConfig::File(file_config) => file_config.make_layer(bin_name, global),\n            #[cfg(unix)]\n            LogWriterConfig::Syslog(syslog_config) => syslog_config.make_layer(bin_name, global),\n        }\n    }\n}\n\nimpl MakeLayer for LogConsoleWriterConfig {\n    fn make_layer(&self, bin_name: &str, global: &LogConfig) -> BoxedLayer {\n        let level = self.level.unwrap_or(global.level);\n        let format = apply_override(&global.format, &self.format);\n        let ansi = io::stdout().is_terminal();\n        make_fmt_layer(bin_name, level, &format, ansi, io::stdout)\n    }\n}\n\nimpl MakeLayer for LogFileWriterConfig {\n    fn make_layer(&self, bin_name: &str, global: &LogConfig) -> BoxedLayer {\n        let level = self.level.unwrap_or(global.level);\n        let format = apply_override(&global.format, &self.format);\n\n        let file_writer = make_file_writer(bin_name, self)\n            // don't have the room for a more graceful error handling here\n            .expect(\"Failed to create file writer for logging\");\n        make_fmt_layer(bin_name, level, &format, false, file_writer)\n    }\n}\n\n#[cfg(unix)]\nimpl MakeLayer for LogSyslogWriterConfig {\n    fn make_layer(&self, bin_name: &str, global: &LogConfig) -> BoxedLayer {\n        let level = self.level.unwrap_or(global.level);\n        let format = apply_override(&global.format, &self.format);\n\n        let syslog_writer = make_syslog_writer(bin_name, self);\n        make_fmt_layer(bin_name, level, &format, false, syslog_writer)\n    }\n}\n\n/// Boilerplate for configuring a `fmt::Layer` with `level` and `format` for different writers.\nfn make_fmt_layer<W>(bin_name: &str, level: u32, format: &LogFormatConfig, ansi: bool, writer: W) -> BoxedLayer\nwhere\n    W: for<'a> MakeWriter<'a> + Send + Sync + 'static,\n{\n    let mut layer = fmt::layer().with_level(true);\n\n    // NOTE: ansi is enabled by default.\n    // Could be disabled by `NO_COLOR` environment variable.\n    // https://no-color.org/\n    if !ansi {\n        layer = layer.with_ansi(false);\n    }\n\n    if level >= 1 {\n        layer = layer.with_target(true).with_thread_ids(true).with_thread_names(true);\n\n        if level >= 3 {\n            layer = layer.with_file(true).with_line_number(true);\n        }\n    } else {\n        layer = layer.with_target(false).with_thread_ids(false).with_thread_names(false);\n    }\n\n    let layer = layer.with_writer(writer);\n\n    let boxed_layer = if format.without_time {\n        layer.without_time().boxed()\n    } else {\n        layer\n            .with_timer(OffsetTime::local_rfc_3339()\n                // Fallback to UTC. Eagerly evaluate because it is cheap to create.\n                .unwrap_or(OffsetTime::new(UtcOffset::UTC, Rfc3339)))\n            .boxed()\n    };\n\n    let filter = make_env_filter(bin_name, level);\n    boxed_layer.with_filter(filter).boxed()\n}\n\nfn make_env_filter(bin_name: &str, level: u32) -> EnvFilter {\n    match EnvFilter::try_from_default_env() {\n        Ok(f) => f,\n        Err(_) => match level {\n            0 => EnvFilter::builder()\n                .with_regex(true)\n                .with_default_directive(LevelFilter::ERROR.into())\n                .parse_lossy(format!(\n                    \"warn,{}=info,shadowsocks_rust=info,shadowsocks_service=info,shadowsocks=info\",\n                    bin_name\n                )),\n            1 => EnvFilter::builder()\n                .with_regex(true)\n                .with_default_directive(LevelFilter::ERROR.into())\n                .parse_lossy(format!(\n                    \"warn,{}=debug,shadowsocks_rust=debug,shadowsocks_service=debug,shadowsocks=debug\",\n                    bin_name\n                )),\n            2 => EnvFilter::builder()\n                .with_regex(true)\n                .with_default_directive(LevelFilter::ERROR.into())\n                .parse_lossy(format!(\n                    \"warn,{}=trace,shadowsocks_rust=trace,shadowsocks_service=trace,shadowsocks=trace\",\n                    bin_name\n                )),\n            _ => EnvFilter::builder()\n                .with_default_directive(LevelFilter::TRACE.into())\n                .parse_lossy(\"\"),\n        },\n    }\n}\n\nfn make_file_writer(bin_name: &str, config: &LogFileWriterConfig) -> Result<RollingFileAppender, InitError> {\n    // We provide default values here because we don't have access to the\n    // `bin_name` elsewhere.\n    let prefix = config.prefix.as_deref().unwrap_or(bin_name);\n    let suffix = config.suffix.as_deref().unwrap_or(\"log\");\n\n    let mut builder = RollingFileAppender::builder()\n        .rotation(config.rotation.into())\n        .filename_prefix(prefix)\n        .filename_suffix(suffix);\n\n    if let Some(max_files) = config.max_files {\n        // setting `max_files` to `0` will cause panicking due to\n        // integer underflow in the `tracing_appender` crate.\n        if max_files > 0 {\n            builder = builder.max_log_files(max_files);\n        }\n    }\n\n    builder.build(&config.directory)\n}\n\nfn apply_override(global: &LogFormatConfig, override_config: &LogFormatConfigOverride) -> LogFormatConfig {\n    LogFormatConfig {\n        without_time: override_config.without_time.unwrap_or(global.without_time),\n    }\n}\n\n#[cfg(unix)]\nfn make_syslog_writer(bin_name: &str, config: &LogSyslogWriterConfig) -> Syslog {\n    use std::ffi::CString;\n\n    use syslog_tracing::{Facility, Options};\n\n    let identity = config.identity.as_deref().unwrap_or(bin_name);\n    let facility = match config.facility {\n        None => Facility::default(),\n        Some(f) => match f {\n            1 => Facility::User,\n            2 => Facility::Mail,\n            3 => Facility::Daemon,\n            4 => Facility::Auth,\n            6 => Facility::Lpr,\n            7 => Facility::News,\n            8 => Facility::Uucp,\n            9 => Facility::Cron,\n            10 => Facility::AuthPriv,\n            16 => Facility::Local0,\n            17 => Facility::Local1,\n            18 => Facility::Local2,\n            19 => Facility::Local3,\n            20 => Facility::Local4,\n            21 => Facility::Local5,\n            22 => Facility::Local6,\n            23 => Facility::Local7,\n            _ => panic!(\"unsupported syslog facility: {}\", f),\n        },\n    };\n    let options = Options::default();\n    let identity = CString::new(identity).expect(\"syslog identity contains null-byte ('\\\\0')\");\n\n    match Syslog::new(identity, options, facility) {\n        Some(l) => l,\n        None => panic!(\"syslog is already initialized\"),\n    }\n}\n"
  },
  {
    "path": "src/monitor/mod.rs",
    "content": "//! Signal monitor\n\n#[cfg(unix)]\n#[path = \"unix.rs\"]\nmod imp;\n\n#[cfg(windows)]\n#[path = \"windows.rs\"]\nmod imp;\n\n#[cfg(not(any(windows, unix)))]\n#[path = \"other.rs\"]\nmod imp;\n\npub use self::imp::create_signal_monitor;\n"
  },
  {
    "path": "src/monitor/other.rs",
    "content": "use futures;\nuse std::io;\n\n/// Create a monitor future for signals\n///\n/// This is a dummy future in the current platform.\npub async fn create_signal_monitor() -> io::Result<()> {\n    // FIXME: What can I do ...\n    // Blocks forever\n    futures::empty::<(), io::Error>().await\n}\n"
  },
  {
    "path": "src/monitor/unix.rs",
    "content": "use futures::future::{self, Either, FutureExt};\nuse log::info;\nuse std::io;\nuse tokio::signal::unix::{SignalKind, signal};\n\n/// Create a monitor future for signals\n///\n/// It will exit when received `SIGTERM` or `SIGINT`.\npub async fn create_signal_monitor() -> io::Result<()> {\n    // Future resolving to two signal streams. Can fail if setting up signal monitoring fails\n    let mut sigterm = signal(SignalKind::terminate())?;\n    let mut sigint = signal(SignalKind::interrupt())?;\n\n    let signal_name = match future::select(sigterm.recv().boxed(), sigint.recv().boxed()).await {\n        Either::Left(..) => \"SIGTERM\",\n        Either::Right(..) => \"SIGINT\",\n    };\n\n    info!(\"received {}, exiting\", signal_name);\n\n    Ok(())\n}\n"
  },
  {
    "path": "src/monitor/windows.rs",
    "content": "use log::info;\nuse std::io;\nuse tokio::signal::ctrl_c;\n\n/// Create a monitor future for signals\n///\n/// It will exit when received Ctrl-C.\npub async fn create_signal_monitor() -> io::Result<()> {\n    let _ = ctrl_c().await;\n    info!(\"received CTRL-C, exiting\");\n\n    Ok(())\n}\n"
  },
  {
    "path": "src/password.rs",
    "content": "//! Common password utilities\n\nuse std::{env, io};\n\nuse log::debug;\n\n/// Read server's password from environment variable or TTY\npub fn read_server_password(server_name: &str) -> io::Result<String> {\n    // common SS_SERVER_PASSWORD\n    if let Ok(pwd) = env::var(\"SS_SERVER_PASSWORD\") {\n        debug!(\n            \"got server {} password from environment variable SS_SERVER_PASSWORD\",\n            server_name\n        );\n        return Ok(pwd);\n    }\n\n    // read from TTY\n    let tty_prompt = format!(\"({server_name}) Password: \");\n    if let Ok(pwd) = rpassword::prompt_password(tty_prompt) {\n        debug!(\"got server {} password from tty prompt\", server_name);\n        return Ok(pwd);\n    }\n\n    Err(io::Error::other(\"no server password found\"))\n}\n"
  },
  {
    "path": "src/service/genkey.rs",
    "content": "//! Generate sufficient key for method\n\nuse std::process::ExitCode;\n\nuse base64::Engine as _;\nuse clap::{Arg, ArgAction, ArgMatches, Command, builder::PossibleValuesParser};\n\nuse shadowsocks_service::shadowsocks::crypto::{CipherKind, available_ciphers};\n\n/// Defines command line options\npub fn define_command_line_options(mut app: Command) -> Command {\n    app = app.arg(\n        Arg::new(\"ENCRYPT_METHOD\")\n            .short('m')\n            .long(\"encrypt-method\")\n            .num_args(1)\n            .action(ArgAction::Set)\n            .required(true)\n            .value_parser(PossibleValuesParser::new(available_ciphers()))\n            .help(\"Server's encryption method\"),\n    );\n\n    app\n}\n\n/// Program entrance `main`\npub fn main(matches: &ArgMatches) -> ExitCode {\n    let method = matches\n        .get_one::<String>(\"ENCRYPT_METHOD\")\n        .map(|x| x.parse::<CipherKind>().expect(\"method\"))\n        .expect(\"`method` is required\");\n\n    let key_len = method.key_len();\n    if key_len > 0 {\n        let mut key = vec![0u8; key_len];\n        rand::fill(key.as_mut_slice());\n\n        let encoded_key = base64::engine::general_purpose::STANDARD.encode(&key);\n        println!(\"{encoded_key}\");\n    }\n\n    ExitCode::SUCCESS\n}\n"
  },
  {
    "path": "src/service/local.rs",
    "content": "//! Local server launchers\n\n#[cfg(unix)]\nuse std::sync::Arc;\nuse std::{\n    future::Future,\n    net::IpAddr,\n    path::PathBuf,\n    process::ExitCode,\n    time::{Duration, Instant},\n};\n\nuse clap::{Arg, ArgAction, ArgGroup, ArgMatches, Command, ValueHint, builder::PossibleValuesParser};\nuse futures::future::{self, FutureExt};\nuse log::{error, info, trace};\nuse tokio::{\n    self,\n    runtime::{Builder, Runtime},\n};\n\n#[cfg(feature = \"local-redir\")]\nuse shadowsocks_service::config::RedirType;\n#[cfg(feature = \"local-tunnel\")]\nuse shadowsocks_service::shadowsocks::relay::socks5::Address;\nuse shadowsocks_service::{\n    acl::AccessControl,\n    config::{\n        Config, ConfigType, LocalConfig, LocalInstanceConfig, ProtocolType, ServerInstanceConfig,\n        read_variable_field_value,\n    },\n    local::{Server, loadbalancing::PingBalancer},\n    shadowsocks::{\n        config::{Mode, ServerAddr, ServerConfig, ServerSource},\n        crypto::{CipherKind, available_ciphers},\n        plugin::PluginConfig,\n    },\n};\n\n#[cfg(feature = \"logging\")]\nuse crate::logging;\nuse crate::{\n    config::{Config as ServiceConfig, RuntimeMode},\n    error::{ShadowsocksError, ShadowsocksResult},\n    monitor, vparser,\n};\n\n#[cfg(feature = \"local-dns\")]\nmod local_value_parser {\n    use std::{\n        net::{IpAddr, SocketAddr},\n        str::FromStr,\n    };\n\n    use shadowsocks_service::shadowsocks::relay::socks5::{Address, AddressError};\n\n    #[derive(Debug, Clone)]\n    pub struct RemoteDnsAddress(pub Address);\n\n    impl FromStr for RemoteDnsAddress {\n        type Err = AddressError;\n\n        fn from_str(a: &str) -> Result<Self, Self::Err> {\n            if let Ok(ip) = a.parse::<IpAddr>() {\n                return Ok(Self(Address::SocketAddress(SocketAddr::new(ip, 53))));\n            }\n\n            if let Ok(saddr) = a.parse::<SocketAddr>() {\n                return Ok(Self(Address::SocketAddress(saddr)));\n            }\n\n            if a.find(':').is_some() {\n                a.parse::<Address>().map(RemoteDnsAddress)\n            } else {\n                Ok(Self(Address::DomainNameAddress(a.to_owned(), 53)))\n            }\n        }\n    }\n\n    #[inline]\n    pub fn parse_remote_dns_address(s: &str) -> Result<RemoteDnsAddress, AddressError> {\n        s.parse::<RemoteDnsAddress>()\n    }\n}\n\n/// Defines command line options\npub fn define_command_line_options(mut app: Command) -> Command {\n    app = app.arg(\n        Arg::new(\"CONFIG\")\n            .short('c')\n            .long(\"config\")\n            .num_args(1)\n            .action(ArgAction::Set)\n            .value_parser(clap::value_parser!(PathBuf))\n            .value_hint(ValueHint::FilePath)\n            .help(\"Shadowsocks configuration file (https://shadowsocks.org/doc/configs.html)\"),\n    )\n    .arg(\n        Arg::new(\"LOCAL_ADDR\")\n            .short('b')\n            .long(\"local-addr\")\n            .num_args(1)\n            .action(ArgAction::Set)\n            .value_parser(vparser::parse_server_addr)\n            .help(\"Local address, listen only to this address if specified\"),\n    )\n    .arg(\n        Arg::new(\"UDP_ONLY\")\n            .short('u')\n            .action(ArgAction::SetTrue)\n            .conflicts_with(\"TCP_AND_UDP\")\n            .requires(\"LOCAL_ADDR\")\n            .help(\"Server mode UDP_ONLY\"),\n    )\n    .arg(\n        Arg::new(\"TCP_AND_UDP\")\n            .short('U')\n            .action(ArgAction::SetTrue)\n            .help(\"Server mode TCP_AND_UDP\"),\n    )\n    .arg(\n        Arg::new(\"PROTOCOL\")\n            .long(\"protocol\")\n            .num_args(1)\n            .action(ArgAction::Set)\n            .value_parser(PossibleValuesParser::new(ProtocolType::available_protocols()))\n            .help(\"Protocol for communicating with clients (SOCKS5 by default)\"),\n    )\n    .arg(\n        Arg::new(\"UDP_BIND_ADDR\")\n            .long(\"udp-bind-addr\")\n            .num_args(1)\n            .action(ArgAction::Set)\n            .value_parser(vparser::parse_server_addr)\n            .help(\"UDP relay's bind address, default is the same as local-addr\"),\n    )\n    .arg(\n        Arg::new(\"UDP_ASSOCIATE_ADDR\")\n        .long(\"udp-associate-addr\")\n        .num_args(1)\n        .action(ArgAction::Set)\n        .value_parser(vparser::parse_server_addr)\n        .help(\"UDP relay's externally visible address return in UDP Associate responses\"),\n    )\n    .arg(\n        Arg::new(\"SERVER_ADDR\")\n            .short('s')\n            .long(\"server-addr\")\n            .num_args(1)\n            .action(ArgAction::Set)\n            .requires(\"ENCRYPT_METHOD\")\n            .help(\"Server address\"),\n    )\n    .arg(\n        Arg::new(\"PASSWORD\")\n            .short('k')\n            .long(\"password\")\n            .num_args(1)\n            .action(ArgAction::Set)\n            .requires(\"SERVER_ADDR\")\n            .help(\"Server's password\"),\n    )\n    .arg(\n        Arg::new(\"ENCRYPT_METHOD\")\n            .short('m')\n            .long(\"encrypt-method\")\n            .num_args(1)\n            .action(ArgAction::Set)\n            .requires(\"SERVER_ADDR\")\n            .value_parser(PossibleValuesParser::new(available_ciphers()))\n            .help(\"Server's encryption method\"),\n    )\n    .arg(\n        Arg::new(\"TIMEOUT\")\n            .long(\"timeout\")\n            .num_args(1)\n            .action(ArgAction::Set)\n            .value_parser(clap::value_parser!(u64))\n            .requires(\"SERVER_ADDR\")\n            .help(\"Server's timeout seconds for TCP relay\"),\n    )\n    .arg(\n        Arg::new(\"PLUGIN\")\n            .long(\"plugin\")\n            .num_args(1)\n            .action(ArgAction::Set)\n            .value_hint(ValueHint::CommandName)\n            .requires(\"SERVER_ADDR\")\n            .help(\"SIP003 (https://shadowsocks.org/doc/sip003.html) plugin\"),\n    )\n    .arg(\n        Arg::new(\"PLUGIN_MODE\")\n            .long(\"plugin-mode\")\n            .num_args(1)\n            .action(ArgAction::Set)\n            .requires(\"PLUGIN\")\n            .help(\"SIP003/SIP003u plugin mode, must be one of `tcp_only` (default), `udp_only` and `tcp_and_udp`\"),\n    )\n    .arg(\n        Arg::new(\"PLUGIN_OPT\")\n            .long(\"plugin-opts\")\n            .num_args(1)\n            .action(ArgAction::Set)\n            .requires(\"PLUGIN\")\n            .help(\"Set SIP003 plugin options\"),\n    )\n    .arg(\n        Arg::new(\"SERVER_URL\")\n            .long(\"server-url\")\n            .num_args(1)\n            .action(ArgAction::Set)\n            .value_hint(ValueHint::Url)\n            .value_parser(vparser::parse_server_url)\n            .help(\"Server address in SIP002 (https://shadowsocks.org/doc/sip002.html) URL\"),\n    )\n    .group(ArgGroup::new(\"SERVER_CONFIG\")\n        .arg(\"SERVER_ADDR\").arg(\"SERVER_URL\").multiple(true))\n    .arg(\n        Arg::new(\"ACL\")\n            .long(\"acl\")\n            .num_args(1)\n            .action(ArgAction::Set)\n            .value_hint(ValueHint::FilePath)\n            .help(\"Path to ACL (Access Control List)\"),\n    )\n    .arg(Arg::new(\"DNS\").long(\"dns\").num_args(1).action(ArgAction::Set).help(\"DNS nameservers, formatted like [(tcp|udp)://]host[:port][,host[:port]]..., or unix:///path/to/dns, or predefined keys like \\\"google\\\", \\\"cloudflare\\\"\"))\n    .arg(Arg::new(\"DNS_CACHE_SIZE\").long(\"dns-cache-size\").num_args(1).action(ArgAction::Set).value_parser(clap::value_parser!(usize)).help(\"DNS cache size in number of records. Works when trust-dns DNS backend is enabled.\"))\n    .arg(Arg::new(\"TCP_NO_DELAY\").long(\"tcp-no-delay\").alias(\"no-delay\").action(ArgAction::SetTrue).help(\"Set TCP_NODELAY option for sockets\"))\n    .arg(Arg::new(\"TCP_FAST_OPEN\").long(\"tcp-fast-open\").alias(\"fast-open\").action(ArgAction::SetTrue).help(\"Enable TCP Fast Open (TFO)\"))\n    .arg(Arg::new(\"TCP_KEEP_ALIVE\").long(\"tcp-keep-alive\").num_args(1).action(ArgAction::Set).value_parser(clap::value_parser!(u64)).help(\"Set TCP keep alive timeout seconds\"))\n    .arg(Arg::new(\"TCP_MULTIPATH\").long(\"tcp-multipath\").alias(\"mptcp\").action(ArgAction::SetTrue).help(\"Enable Multipath-TCP (MPTCP)\"))\n    .arg(Arg::new(\"UDP_TIMEOUT\").long(\"udp-timeout\").num_args(1).action(ArgAction::Set).value_parser(clap::value_parser!(u64)).help(\"Timeout seconds for UDP relay\"))\n    .arg(Arg::new(\"UDP_MAX_ASSOCIATIONS\").long(\"udp-max-associations\").num_args(1).action(ArgAction::Set).value_parser(clap::value_parser!(usize)).help(\"Maximum associations to be kept simultaneously for UDP relay\"))\n    .arg(Arg::new(\"INBOUND_SEND_BUFFER_SIZE\").long(\"inbound-send-buffer-size\").num_args(1).action(ArgAction::Set).value_parser(clap::value_parser!(u32)).help(\"Set inbound sockets' SO_SNDBUF option\"))\n    .arg(Arg::new(\"INBOUND_RECV_BUFFER_SIZE\").long(\"inbound-recv-buffer-size\").num_args(1).action(ArgAction::Set).value_parser(clap::value_parser!(u32)).help(\"Set inbound sockets' SO_RCVBUF option\"))\n    .arg(Arg::new(\"OUTBOUND_SEND_BUFFER_SIZE\").long(\"outbound-send-buffer-size\").num_args(1).action(ArgAction::Set).value_parser(clap::value_parser!(u32)).help(\"Set outbound sockets' SO_SNDBUF option\"))\n    .arg(Arg::new(\"OUTBOUND_RECV_BUFFER_SIZE\").long(\"outbound-recv-buffer-size\").num_args(1).action(ArgAction::Set).value_parser(clap::value_parser!(u32)).help(\"Set outbound sockets' SO_RCVBUF option\"))\n    .arg(Arg::new(\"OUTBOUND_BIND_ADDR\").long(\"outbound-bind-addr\").num_args(1).alias(\"bind-addr\").action(ArgAction::Set).value_parser(vparser::parse_ip_addr).help(\"Bind address, outbound socket will bind this address\"))\n    .arg(Arg::new(\"OUTBOUND_BIND_INTERFACE\").long(\"outbound-bind-interface\").num_args(1).action(ArgAction::Set).help(\"Set SO_BINDTODEVICE / IP_BOUND_IF / IP_UNICAST_IF option for outbound socket\"))\n    .arg(\n        Arg::new(\"IPV6_FIRST\")\n            .short('6')\n            .action(ArgAction::SetTrue)\n            .help(\"Resolve hostname to IPv6 address first\"),\n    );\n\n    #[cfg(feature = \"logging\")]\n    {\n        app = app\n            .arg(\n                Arg::new(\"VERBOSE\")\n                    .short('v')\n                    .action(ArgAction::Count)\n                    .help(\"Set log level\"),\n            )\n            .arg(\n                Arg::new(\"LOG_WITHOUT_TIME\")\n                    .long(\"log-without-time\")\n                    .action(ArgAction::SetTrue)\n                    .help(\"Log without datetime prefix\"),\n            )\n            .arg(\n                Arg::new(\"LOG_CONFIG\")\n                    .long(\"log-config\")\n                    // deprecated for removal\n                    .hide(true)\n                    .num_args(1)\n                    .action(ArgAction::Set)\n                    .value_parser(clap::value_parser!(PathBuf))\n                    .value_hint(ValueHint::FilePath)\n                    .help(\"log4rs configuration file\"),\n            );\n    }\n\n    #[cfg(feature = \"local-tunnel\")]\n    {\n        app = app.arg(\n            Arg::new(\"FORWARD_ADDR\")\n                .short('f')\n                .long(\"forward-addr\")\n                .num_args(1)\n                .action(ArgAction::Set)\n                .requires(\"LOCAL_ADDR\")\n                .value_parser(vparser::parse_address)\n                .required_if_eq(\"PROTOCOL\", \"tunnel\")\n                .help(\"Forwarding data directly to this address (for tunnel)\"),\n        );\n    }\n\n    #[cfg(all(unix, not(target_os = \"android\")))]\n    {\n        app = app.arg(\n            Arg::new(\"NOFILE\")\n                .short('n')\n                .long(\"nofile\")\n                .num_args(1)\n                .action(ArgAction::Set)\n                .value_parser(clap::value_parser!(u64))\n                .help(\"Set RLIMIT_NOFILE with both soft and hard limit\"),\n        );\n    }\n\n    #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n    {\n        app = app.arg(\n            Arg::new(\"OUTBOUND_FWMARK\")\n                .long(\"outbound-fwmark\")\n                .num_args(1)\n                .action(ArgAction::Set)\n                .value_parser(clap::value_parser!(u32))\n                .help(\"Set SO_MARK option for outbound sockets\"),\n        );\n    }\n\n    #[cfg(target_os = \"freebsd\")]\n    {\n        app = app.arg(\n            Arg::new(\"OUTBOUND_USER_COOKIE\")\n                .long(\"outbound-user-cookie\")\n                .num_args(1)\n                .action(ArgAction::Set)\n                .value_parser(clap::value_parser!(u32))\n                .help(\"Set SO_USER_COOKIE option for outbound sockets\"),\n        );\n    }\n\n    #[cfg(feature = \"local-redir\")]\n    {\n        if RedirType::tcp_default() != RedirType::NotSupported {\n            app = app.arg(\n                Arg::new(\"TCP_REDIR\")\n                    .long(\"tcp-redir\")\n                    .num_args(1)\n                    .action(ArgAction::Set)\n                    .requires(\"LOCAL_ADDR\")\n                    .value_parser(PossibleValuesParser::new(RedirType::tcp_available_types()))\n                    .help(\"TCP redir (transparent proxy) type\"),\n            );\n        }\n\n        if RedirType::udp_default() != RedirType::NotSupported {\n            app = app.arg(\n                Arg::new(\"UDP_REDIR\")\n                    .long(\"udp-redir\")\n                    .num_args(1)\n                    .action(ArgAction::Set)\n                    .requires(\"LOCAL_ADDR\")\n                    .value_parser(PossibleValuesParser::new(RedirType::udp_available_types()))\n                    .help(\"UDP redir (transparent proxy) type\"),\n            );\n        }\n    }\n\n    #[cfg(target_os = \"android\")]\n    {\n        app = app.arg(\n            Arg::new(\"VPN_MODE\")\n                .long(\"vpn\")\n                .action(ArgAction::SetTrue)\n                .help(\"Enable VPN mode (only for Android)\"),\n        );\n    }\n\n    #[cfg(feature = \"local-flow-stat\")]\n    {\n        #[cfg(unix)]\n        {\n            app = app.arg(\n                Arg::new(\"STAT_PATH\")\n                    .long(\"stat-path\")\n                    .num_args(1)\n                    .action(ArgAction::Set)\n                    .value_hint(ValueHint::FilePath)\n                    .conflicts_with(\"STAT_ADDR\")\n                    .help(\"Specify socket path (unix domain socket) for sending traffic statistic\"),\n            );\n        }\n\n        app = app.arg(\n            Arg::new(\"STAT_ADDR\")\n                .long(\"stat-addr\")\n                .num_args(1)\n                .action(ArgAction::Set)\n                .value_parser(vparser::parse_socket_addr)\n                .help(\"Specify socket address IP:PORT (TCP) for sending traffic statistic\"),\n        );\n    }\n\n    #[cfg(feature = \"local-dns\")]\n    {\n        app = app\n            .arg(\n                Arg::new(\"LOCAL_DNS_ADDR\")\n                    .long(\"local-dns-addr\")\n                    .num_args(1)\n                    .action(ArgAction::Set)\n                    .required_if_eq(\"PROTOCOL\", \"dns\")\n                    .requires(\"LOCAL_ADDR\")\n                    .value_parser(vparser::parse_name_server_addr)\n                    .help(\"Specify the address of local DNS server, send queries directly\"),\n            )\n            .arg(\n                Arg::new(\"REMOTE_DNS_ADDR\")\n                    .long(\"remote-dns-addr\")\n                    .num_args(1)\n                    .action(ArgAction::Set)\n                    .required_if_eq(\"PROTOCOL\", \"dns\")\n                    .requires(\"LOCAL_ADDR\")\n                    .value_parser(self::local_value_parser::parse_remote_dns_address)\n                    .help(\"Specify the address of remote DNS server, send queries through shadowsocks' tunnel\"),\n            );\n\n        #[cfg(target_os = \"android\")]\n        {\n            app = app.arg(\n                Arg::new(\"DNS_LOCAL_ADDR\")\n                    .long(\"dns-addr\")\n                    .num_args(1)\n                    .action(ArgAction::Set)\n                    .requires_all(&[\"LOCAL_ADDR\", \"REMOTE_DNS_ADDR\"])\n                    .value_parser(vparser::parse_server_addr)\n                    .help(\"DNS address, listen to this address if specified\"),\n            );\n        }\n    }\n\n    #[cfg(feature = \"local-tun\")]\n    {\n        app = app\n            .arg(\n                Arg::new(\"TUN_INTERFACE_NAME\")\n                    .long(\"tun-interface-name\")\n                    .num_args(1)\n                    .action(ArgAction::Set)\n                    .help(\"Tun interface name, allocate one if not specify\"),\n            )\n            .arg(\n                Arg::new(\"TUN_INTERFACE_ADDRESS\")\n                    .long(\"tun-interface-address\")\n                    .num_args(1)\n                    .action(ArgAction::Set)\n                    .value_parser(vparser::parse_ipnet)\n                    .help(\"Tun interface address (network)\"),\n            )\n            .arg(\n                Arg::new(\"TUN_INTERFACE_DESTINATION\")\n                    .long(\"tun-interface-destination\")\n                    .num_args(1)\n                    .action(ArgAction::Set)\n                    .value_parser(vparser::parse_ipnet)\n                    .help(\"Tun interface destination address (network)\"),\n            );\n\n        #[cfg(unix)]\n        {\n            app = app.arg(\n                Arg::new(\"TUN_DEVICE_FD_FROM_PATH\")\n                    .long(\"tun-device-fd-from-path\")\n                    .num_args(1)\n                    .action(ArgAction::Set)\n                    .value_parser(clap::value_parser!(PathBuf))\n                    .value_hint(ValueHint::AnyPath)\n                    .help(\"Tun device file descriptor will be transferred from this unix domain socket path\"),\n            );\n        }\n    }\n\n    #[cfg(feature = \"local-fake-dns\")]\n    {\n        app = app\n            .arg(\n                Arg::new(\"FAKE_DNS_RECORD_EXPIRE_DURATION\")\n                    .long(\"fake-dns-record-expire-duration\")\n                    .num_args(1)\n                    .action(ArgAction::Set)\n                    .value_parser(clap::value_parser!(u64))\n                    .help(\"Fake DNS record expire duration in seconds\"),\n            )\n            .arg(\n                Arg::new(\"FAKE_DNS_IPV4_NETWORK\")\n                    .long(\"fake-dns-ipv4-network\")\n                    .num_args(1)\n                    .action(ArgAction::Set)\n                    .value_parser(vparser::parse_ipnet)\n                    .help(\"Fake DNS IPv4 address network\"),\n            )\n            .arg(\n                Arg::new(\"FAKE_DNS_IPV6_NETWORK\")\n                    .long(\"fake-dns-ipv6-network\")\n                    .num_args(1)\n                    .action(ArgAction::Set)\n                    .value_parser(vparser::parse_ipnet)\n                    .help(\"Fake DNS IPv6 address network\"),\n            )\n            .arg(\n                Arg::new(\"FAKE_DNS_DATABASE_PATH\")\n                    .long(\"fake-dns-database-path\")\n                    .num_args(1)\n                    .action(ArgAction::Set)\n                    .value_hint(ValueHint::AnyPath)\n                    .help(\"Fake DNS database storage path\"),\n            );\n    }\n\n    #[cfg(unix)]\n    {\n        app = app\n            .arg(\n                Arg::new(\"DAEMONIZE\")\n                    .short('d')\n                    .long(\"daemonize\")\n                    .action(ArgAction::SetTrue)\n                    .help(\"Daemonize\"),\n            )\n            .arg(\n                Arg::new(\"DAEMONIZE_PID_PATH\")\n                    .long(\"daemonize-pid\")\n                    .num_args(1)\n                    .action(ArgAction::Set)\n                    .value_parser(clap::value_parser!(PathBuf))\n                    .value_hint(ValueHint::FilePath)\n                    .help(\"File path to store daemonized process's PID\"),\n            );\n    }\n\n    #[cfg(feature = \"multi-threaded\")]\n    {\n        app = app\n            .arg(\n                Arg::new(\"SINGLE_THREADED\")\n                    .long(\"single-threaded\")\n                    .action(ArgAction::SetTrue)\n                    .help(\"Run the program all in one thread\"),\n            )\n            .arg(\n                Arg::new(\"WORKER_THREADS\")\n                    .long(\"worker-threads\")\n                    .num_args(1)\n                    .action(ArgAction::Set)\n                    .value_parser(clap::value_parser!(usize))\n                    .help(\"Sets the number of worker threads the `Runtime` will use\"),\n            );\n    }\n\n    #[cfg(unix)]\n    {\n        app = app.arg(\n            Arg::new(\"USER\")\n                .long(\"user\")\n                .short('a')\n                .num_args(1)\n                .action(ArgAction::Set)\n                .value_hint(ValueHint::Username)\n                .help(\"Run as another user\"),\n        );\n    }\n\n    #[cfg(feature = \"local-online-config\")]\n    {\n        app = app\n            .arg(\n                Arg::new(\"ONLINE_CONFIG_URL\")\n                    .long(\"online-config-url\")\n                    .num_args(1)\n                    .action(ArgAction::Set)\n                    .value_hint(ValueHint::Url)\n                    .help(\"SIP008 Online Configuration Delivery URL (https://shadowsocks.org/doc/sip008.html)\"),\n            )\n            .arg(\n                Arg::new(\"ONLINE_CONFIG_UPDATE_INTERVAL\")\n                    .long(\"online-config-update-interval\")\n                    .num_args(1)\n                    .action(ArgAction::Set)\n                    .value_parser(clap::value_parser!(u64))\n                    .help(\"SIP008 Online Configuration Delivery update interval in seconds, 3600 by default\"),\n            )\n            .arg(\n                Arg::new(\"ONLINE_CONFIG_ALLOWED_PLUGIN\")\n                    .long(\"online-config-allowed-plugin\")\n                    .action(ArgAction::Append)\n                    .help(\"SIP008 Online Configuration Delivery allowed plugin list\"),\n            );\n    }\n\n    app\n}\n\n/// Create `Runtime` and `main` entry\npub fn create(matches: &ArgMatches) -> ShadowsocksResult<(Runtime, impl Future<Output = ShadowsocksResult> + use<>)> {\n    #[cfg_attr(not(feature = \"local-online-config\"), allow(unused_mut))]\n    let (config, _, runtime) = {\n        let config_path_opt = matches.get_one::<PathBuf>(\"CONFIG\").cloned().or_else(|| {\n            if !matches.contains_id(\"SERVER_CONFIG\") {\n                match crate::config::get_default_config_path(\"local.json\") {\n                    None => None,\n                    Some(p) => {\n                        println!(\"loading default config {p:?}\");\n                        Some(p)\n                    }\n                }\n            } else {\n                None\n            }\n        });\n\n        let mut service_config = match config_path_opt {\n            Some(ref config_path) => ServiceConfig::load_from_file(config_path)\n                .map_err(|err| ShadowsocksError::LoadConfigFailure(format!(\"loading config {config_path:?}, {err}\")))?,\n            None => ServiceConfig::default(),\n        };\n        service_config.set_options(matches);\n\n        #[cfg(feature = \"logging\")]\n        match service_config.log.config_path {\n            Some(ref path) => {\n                logging::init_with_file(path);\n            }\n            None => {\n                logging::init_with_config(\"sslocal\", &service_config.log);\n            }\n        }\n\n        trace!(\"{:?}\", service_config);\n\n        let mut config = match config_path_opt {\n            Some(cpath) => Config::load_from_file(&cpath, ConfigType::Local)\n                .map_err(|err| ShadowsocksError::LoadConfigFailure(format!(\"loading config {cpath:?}, {err}\")))?,\n            None => Config::new(ConfigType::Local),\n        };\n\n        if let Some(svr_addr) = matches.get_one::<String>(\"SERVER_ADDR\") {\n            let method = matches\n                .get_one::<String>(\"ENCRYPT_METHOD\")\n                .map(|x| x.parse::<CipherKind>().expect(\"method\"))\n                .expect(\"`method` is required\");\n\n            let password = match matches.get_one::<String>(\"PASSWORD\") {\n                Some(pwd) => read_variable_field_value(pwd).into(),\n                None => {\n                    // NOTE: svr_addr should have been checked by crate::vparser\n                    if method.is_none() {\n                        // If method doesn't need a key (none, plain), then we can leave it empty\n                        String::new()\n                    } else {\n                        match crate::password::read_server_password(svr_addr) {\n                            Ok(pwd) => pwd,\n                            Err(..) => panic!(\"`password` is required for server {svr_addr}\"),\n                        }\n                    }\n                }\n            };\n\n            let svr_addr = svr_addr.parse::<ServerAddr>().expect(\"server-addr\");\n            let timeout = matches.get_one::<u64>(\"TIMEOUT\").map(|x| Duration::from_secs(*x));\n\n            let mut sc = match ServerConfig::new(svr_addr, password, method) {\n                Ok(sc) => sc,\n                Err(err) => {\n                    panic!(\"failed to create ServerConfig, error: {}\", err);\n                }\n            };\n            sc.set_source(ServerSource::CommandLine);\n            if let Some(timeout) = timeout {\n                sc.set_timeout(timeout);\n            }\n\n            if let Some(p) = matches.get_one::<String>(\"PLUGIN\").cloned() {\n                let plugin = PluginConfig {\n                    plugin: p,\n                    plugin_opts: matches.get_one::<String>(\"PLUGIN_OPT\").cloned(),\n                    plugin_args: Vec::new(),\n                    plugin_mode: matches\n                        .get_one::<String>(\"PLUGIN_MODE\")\n                        .map(|x| {\n                            x.parse::<Mode>()\n                                .expect(\"plugin-mode must be one of `tcp_only` (default), `udp_only` and `tcp_and_udp`\")\n                        })\n                        .unwrap_or(Mode::TcpOnly),\n                };\n\n                sc.set_plugin(plugin);\n            }\n\n            config.server.push(ServerInstanceConfig::with_server_config(sc));\n        }\n\n        if let Some(mut svr_addr) = matches.get_one::<ServerConfig>(\"SERVER_URL\").cloned() {\n            svr_addr.set_source(ServerSource::CommandLine);\n            config.server.push(ServerInstanceConfig::with_server_config(svr_addr));\n        }\n\n        #[cfg(feature = \"local-flow-stat\")]\n        {\n            use shadowsocks_service::config::LocalFlowStatAddress;\n            use std::net::SocketAddr;\n\n            #[cfg(unix)]\n            if let Some(stat_path) = matches.get_one::<String>(\"STAT_PATH\") {\n                config.local_stat_addr = Some(LocalFlowStatAddress::UnixStreamPath(From::from(stat_path)));\n            }\n\n            if let Some(stat_addr) = matches.get_one::<SocketAddr>(\"STAT_ADDR\").cloned() {\n                config.local_stat_addr = Some(LocalFlowStatAddress::TcpStreamAddr(stat_addr));\n            }\n        }\n\n        #[cfg(target_os = \"android\")]\n        if matches.get_flag(\"VPN_MODE\") {\n            // A socket `protect_path` in CWD\n            // Same as shadowsocks-libev's android.c\n            config.outbound_vpn_protect_path = Some(From::from(\"protect_path\"));\n        }\n\n        if matches.get_raw(\"LOCAL_ADDR\").is_some() || matches.get_raw(\"PROTOCOL\").is_some() {\n            let protocol = match matches.get_one::<String>(\"PROTOCOL\").map(|s| s.as_str()) {\n                Some(\"socks\") => ProtocolType::Socks,\n                #[cfg(feature = \"local-http\")]\n                Some(\"http\") => ProtocolType::Http,\n                #[cfg(feature = \"local-tunnel\")]\n                Some(\"tunnel\") => ProtocolType::Tunnel,\n                #[cfg(feature = \"local-redir\")]\n                Some(\"redir\") => ProtocolType::Redir,\n                #[cfg(feature = \"local-dns\")]\n                Some(\"dns\") => ProtocolType::Dns,\n                #[cfg(feature = \"local-tun\")]\n                Some(\"tun\") => ProtocolType::Tun,\n                Some(p) => panic!(\"not supported `protocol` \\\"{p}\\\"\"),\n                None => ProtocolType::Socks,\n            };\n\n            let mut local_config = LocalConfig::new(protocol);\n            match matches.get_one::<ServerAddr>(\"LOCAL_ADDR\").cloned() {\n                Some(local_addr) => local_config.addr = Some(local_addr),\n                None => {\n                    #[cfg(feature = \"local-tun\")]\n                    if protocol == ProtocolType::Tun {\n                        // `tun` protocol doesn't need --local-addr\n                    } else {\n                        panic!(\"`local-addr` is required for protocol {}\", protocol.as_str());\n                    }\n                }\n            }\n\n            if let Some(udp_bind_addr) = matches.get_one::<ServerAddr>(\"UDP_BIND_ADDR\").cloned() {\n                local_config.udp_addr = Some(udp_bind_addr);\n            }\n\n            if let Some(udp_associate_addr) = matches.get_one::<ServerAddr>(\"UDP_ASSOCIATE_ADDR\").cloned() {\n                local_config.udp_associate_addr = Some(udp_associate_addr);\n            }\n\n            #[cfg(feature = \"local-tunnel\")]\n            if let Some(addr) = matches.get_one::<Address>(\"FORWARD_ADDR\").cloned() {\n                local_config.forward_addr = Some(addr);\n            }\n\n            #[cfg(feature = \"local-redir\")]\n            {\n                if RedirType::tcp_default() != RedirType::NotSupported\n                    && let Some(tcp_redir) = matches.get_one::<String>(\"TCP_REDIR\")\n                {\n                    local_config.tcp_redir = tcp_redir.parse::<RedirType>().expect(\"tcp-redir\");\n                }\n\n                if RedirType::udp_default() != RedirType::NotSupported\n                    && let Some(udp_redir) = matches.get_one::<String>(\"UDP_REDIR\")\n                {\n                    local_config.udp_redir = udp_redir.parse::<RedirType>().expect(\"udp-redir\");\n                }\n            }\n\n            #[cfg(feature = \"local-dns\")]\n            {\n                use shadowsocks_service::local::dns::NameServerAddr;\n\n                use self::local_value_parser::RemoteDnsAddress;\n\n                if let Some(addr) = matches.get_one::<NameServerAddr>(\"LOCAL_DNS_ADDR\").cloned() {\n                    local_config.local_dns_addr = Some(addr);\n                }\n\n                if let Some(addr) = matches.get_one::<RemoteDnsAddress>(\"REMOTE_DNS_ADDR\").cloned() {\n                    local_config.remote_dns_addr = Some(addr.0);\n                }\n            }\n\n            #[cfg(all(feature = \"local-dns\", target_os = \"android\"))]\n            if protocol != ProtocolType::Dns {\n                // Start a DNS local server binding to DNS_LOCAL_ADDR\n                //\n                // This is a special route only for shadowsocks-android\n                if let Some(addr) = matches.get_one::<ServerAddr>(\"DNS_LOCAL_ADDR\").cloned() {\n                    let mut local_dns_config = LocalConfig::new_with_addr(addr, ProtocolType::Dns);\n\n                    // The `local_dns_addr` and `remote_dns_addr` are for this DNS server (for compatibility)\n                    local_dns_config.local_dns_addr = local_config.local_dns_addr.take();\n                    local_dns_config.remote_dns_addr = local_config.remote_dns_addr.take();\n\n                    config\n                        .local\n                        .push(LocalInstanceConfig::with_local_config(local_dns_config));\n                }\n            }\n\n            #[cfg(feature = \"local-tun\")]\n            {\n                use ipnet::IpNet;\n\n                if let Some(tun_address) = matches.get_one::<IpNet>(\"TUN_INTERFACE_ADDRESS\").cloned() {\n                    local_config.tun_interface_address = Some(tun_address);\n                }\n                if let Some(tun_address) = matches.get_one::<IpNet>(\"TUN_INTERFACE_DESTINATION\").cloned() {\n                    local_config.tun_interface_destination = Some(tun_address);\n                }\n                if let Some(tun_name) = matches.get_one::<String>(\"TUN_INTERFACE_NAME\").cloned() {\n                    local_config.tun_interface_name = Some(tun_name);\n                }\n\n                #[cfg(unix)]\n                if let Some(fd_path) = matches.get_one::<PathBuf>(\"TUN_DEVICE_FD_FROM_PATH\").cloned() {\n                    local_config.tun_device_fd_from_path = Some(fd_path);\n                }\n            }\n\n            #[cfg(feature = \"local-fake-dns\")]\n            {\n                use ipnet::{Ipv4Net, Ipv6Net};\n\n                if let Some(d) = matches.get_one::<u64>(\"FAKE_DNS_RECORD_EXPIRE_DURATION\") {\n                    local_config.fake_dns_record_expire_duration = Some(Duration::from_secs(*d));\n                }\n                if let Some(n) = matches.get_one::<Ipv4Net>(\"FAKE_DNS_IPV4_NETWORK\") {\n                    local_config.fake_dns_ipv4_network = Some(*n);\n                }\n                if let Some(n) = matches.get_one::<Ipv6Net>(\"FAKE_DNS_IPV6_NETWORK\") {\n                    local_config.fake_dns_ipv6_network = Some(*n);\n                }\n                if let Some(p) = matches.get_one::<PathBuf>(\"FAKE_DNS_DATABASE_PATH\").cloned() {\n                    local_config.fake_dns_database_path = Some(p);\n                }\n            }\n\n            if matches.get_flag(\"UDP_ONLY\") {\n                local_config.mode = Mode::UdpOnly;\n            }\n\n            if matches.get_flag(\"TCP_AND_UDP\") {\n                local_config.mode = Mode::TcpAndUdp;\n            }\n\n            config.local.push(LocalInstanceConfig::with_local_config(local_config));\n        }\n\n        if matches.get_flag(\"TCP_NO_DELAY\") {\n            config.no_delay = true;\n        }\n\n        if matches.get_flag(\"TCP_FAST_OPEN\") {\n            config.fast_open = true;\n        }\n\n        if let Some(keep_alive) = matches.get_one::<u64>(\"TCP_KEEP_ALIVE\") {\n            config.keep_alive = Some(Duration::from_secs(*keep_alive));\n        }\n\n        if matches.get_flag(\"TCP_MULTIPATH\") {\n            config.mptcp = true;\n        }\n\n        #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n        if let Some(mark) = matches.get_one::<u32>(\"OUTBOUND_FWMARK\") {\n            config.outbound_fwmark = Some(*mark);\n        }\n\n        #[cfg(target_os = \"freebsd\")]\n        if let Some(user_cookie) = matches.get_one::<u32>(\"OUTBOUND_USER_COOKIE\") {\n            config.outbound_user_cookie = Some(*user_cookie);\n        }\n\n        if let Some(iface) = matches.get_one::<String>(\"OUTBOUND_BIND_INTERFACE\").cloned() {\n            config.outbound_bind_interface = Some(iface);\n        }\n\n        #[cfg(all(unix, not(target_os = \"android\")))]\n        match matches.get_one::<u64>(\"NOFILE\") {\n            Some(nofile) => config.nofile = Some(*nofile),\n            None => {\n                if config.nofile.is_none() {\n                    crate::sys::adjust_nofile();\n                }\n            }\n        }\n\n        if let Some(acl_file) = matches.get_one::<String>(\"ACL\") {\n            let acl = AccessControl::load_from_file(acl_file)\n                .map_err(|err| ShadowsocksError::LoadAclFailure(format!(\"loading ACL \\\"{acl_file}\\\", {err}\")))?;\n            config.acl = Some(acl);\n        }\n\n        if let Some(dns) = matches.get_one::<String>(\"DNS\") {\n            config.set_dns_formatted(dns).expect(\"dns\");\n        }\n\n        if let Some(dns_cache_size) = matches.get_one::<usize>(\"DNS_CACHE_SIZE\") {\n            config.dns_cache_size = Some(*dns_cache_size);\n        }\n\n        if matches.get_flag(\"IPV6_FIRST\") {\n            config.ipv6_first = true;\n        }\n\n        if let Some(udp_timeout) = matches.get_one::<u64>(\"UDP_TIMEOUT\") {\n            config.udp_timeout = Some(Duration::from_secs(*udp_timeout));\n        }\n\n        if let Some(udp_max_assoc) = matches.get_one::<usize>(\"UDP_MAX_ASSOCIATIONS\") {\n            config.udp_max_associations = Some(*udp_max_assoc);\n        }\n\n        if let Some(bs) = matches.get_one::<u32>(\"INBOUND_SEND_BUFFER_SIZE\") {\n            config.inbound_send_buffer_size = Some(*bs);\n        }\n        if let Some(bs) = matches.get_one::<u32>(\"INBOUND_RECV_BUFFER_SIZE\") {\n            config.inbound_recv_buffer_size = Some(*bs);\n        }\n        if let Some(bs) = matches.get_one::<u32>(\"OUTBOUND_SEND_BUFFER_SIZE\") {\n            config.outbound_send_buffer_size = Some(*bs);\n        }\n        if let Some(bs) = matches.get_one::<u32>(\"OUTBOUND_RECV_BUFFER_SIZE\") {\n            config.outbound_recv_buffer_size = Some(*bs);\n        }\n\n        if let Some(bind_addr) = matches.get_one::<IpAddr>(\"OUTBOUND_BIND_ADDR\") {\n            config.outbound_bind_addr = Some(*bind_addr);\n        }\n\n        #[cfg(feature = \"local-online-config\")]\n        if let Some(online_config_url) = matches.get_one::<String>(\"ONLINE_CONFIG_URL\") {\n            use shadowsocks_service::config::OnlineConfig;\n\n            let online_config_update_interval = matches.get_one::<u64>(\"ONLINE_CONFIG_UPDATE_INTERVAL\").cloned();\n\n            let mut allowed_plugins = None;\n            if let Some(plugins) = matches.get_many::<String>(\"ONLINE_CONFIG_ALLOWED_PLUGIN\") {\n                allowed_plugins = Some(plugins.cloned().collect());\n            }\n\n            config.online_config = Some(OnlineConfig {\n                config_url: online_config_url.clone(),\n                update_interval: online_config_update_interval.map(Duration::from_secs),\n                allowed_plugins,\n            });\n        }\n\n        // DONE READING options\n\n        if config.local.is_empty() {\n            return Err(ShadowsocksError::InsufficientParams(\n                \"missing `local_address`, consider specifying it by --local-addr command line option, \\\n                    or \\\"local_address\\\" and \\\"local_port\\\" in configuration file\"\n                    .to_string(),\n            ));\n        }\n\n        config\n            .check_integrity()\n            .map_err(|err| ShadowsocksError::LoadConfigFailure(format!(\"config integrity check failed, {err}\")))?;\n\n        #[cfg(unix)]\n        if matches.get_flag(\"DAEMONIZE\") || matches.get_raw(\"DAEMONIZE_PID_PATH\").is_some() {\n            use crate::daemonize;\n            daemonize::daemonize(matches.get_one::<PathBuf>(\"DAEMONIZE_PID_PATH\"));\n        }\n\n        #[cfg(unix)]\n        if let Some(uname) = matches.get_one::<String>(\"USER\") {\n            crate::sys::run_as_user(uname).map_err(|err| {\n                ShadowsocksError::InsufficientParams(format!(\"failed to change as user, error: {err}\"))\n            })?;\n        }\n\n        info!(\"shadowsocks local {} build {}\", crate::VERSION, crate::BUILD_TIME);\n\n        let mut builder = match service_config.runtime.mode {\n            RuntimeMode::SingleThread => Builder::new_current_thread(),\n            #[cfg(feature = \"multi-threaded\")]\n            RuntimeMode::MultiThread => {\n                let mut builder = Builder::new_multi_thread();\n                if let Some(worker_threads) = service_config.runtime.worker_count {\n                    builder.worker_threads(worker_threads);\n                }\n\n                builder\n            }\n        };\n\n        let runtime = builder.enable_all().build().expect(\"create tokio Runtime\");\n\n        (config, service_config, runtime)\n    };\n\n    let main_fut = async move {\n        let config_path = config.config_path.clone();\n\n        let instance = Server::new(config).await.expect(\"create local\");\n\n        let reload_task = match config_path {\n            Some(config_path) => ServerReloader {\n                config_path: config_path.clone(),\n                balancer: instance.server_balancer().clone(),\n            }\n            .launch_reload_server_task()\n            .boxed(),\n            None => future::pending().boxed(),\n        };\n\n        let abort_signal = monitor::create_signal_monitor();\n        let server = instance.run();\n\n        let reload_task = reload_task.fuse();\n        let abort_signal = abort_signal.fuse();\n        let server = server.fuse();\n\n        tokio::pin!(reload_task);\n        tokio::pin!(abort_signal);\n        tokio::pin!(server);\n\n        loop {\n            futures::select! {\n                server_res = server => {\n                    match server_res {\n                        // Server future resolved without an error. This should never happen.\n                        Ok(..) => {\n                            return Err(ShadowsocksError::ServerExitUnexpectedly(\"server exited unexpectedly\".to_owned()));\n                        }\n                        // Server future resolved with error, which are listener errors in most cases\n                        Err(err) => {\n                            return Err(ShadowsocksError::ServerAborted(format!(\"server aborted with {err}\")));\n                        }\n                    }\n                }\n                // The abort signal future resolved. Means we should just exit.\n                _ = abort_signal => {\n                    return Ok(());\n                }\n                _ = reload_task => {\n                    // continue.\n                    trace!(\"server-loader task task exited\");\n                }\n            }\n        }\n    };\n\n    Ok((runtime, main_fut))\n}\n\n/// Program entrance `main`\n#[inline]\npub fn main(matches: &ArgMatches) -> ExitCode {\n    match create(matches).and_then(|(runtime, main_fut)| runtime.block_on(main_fut)) {\n        Ok(()) => ExitCode::SUCCESS,\n        Err(err) => {\n            eprintln!(\"{err}\");\n            err.exit_code().into()\n        }\n    }\n}\n\nstruct ServerReloader {\n    config_path: PathBuf,\n    balancer: PingBalancer,\n}\n\nimpl ServerReloader {\n    #[cfg_attr(not(unix), allow(dead_code))]\n    async fn run_once(&self) -> Result<(), Box<dyn std::error::Error>> {\n        let start_time = Instant::now();\n\n        // Load servers from source\n        let source_config = match Config::load_from_file(&self.config_path, ConfigType::Local) {\n            Ok(c) => c,\n            Err(err) => {\n                error!(\n                    \"server-loader task failed to load from file: {}, error: {}\",\n                    self.config_path.display(),\n                    err\n                );\n                return Err(Box::new(err));\n            }\n        };\n\n        let server_len = source_config.server.len();\n\n        let fetch_end_time = Instant::now();\n\n        if let Err(err) = self\n            .balancer\n            .reset_servers(source_config.server, &[ServerSource::Configuration])\n            .await\n        {\n            error!(\"server-loader task {} servers but found error: {}\", server_len, err);\n            return Err(Box::new(err));\n        }\n\n        let total_end_time = Instant::now();\n\n        info!(\n            \"server-loader task load from {} with {} servers, fetch costs: {:?}, total costs: {:?}\",\n            self.config_path.display(),\n            server_len,\n            fetch_end_time - start_time,\n            total_end_time - start_time,\n        );\n\n        Ok(())\n    }\n\n    #[cfg(unix)]\n    async fn launch_signal_reload_server_task(self: Arc<Self>) {\n        use log::debug;\n        use tokio::signal::unix::{SignalKind, signal};\n\n        let mut sigusr1 = signal(SignalKind::user_defined1()).expect(\"signal\");\n\n        debug!(\"server-loader task is now listening USR1\");\n\n        while sigusr1.recv().await.is_some() {\n            let _ = self.run_once().await;\n        }\n    }\n\n    #[cfg(unix)]\n    async fn launch_reload_server_task(self) {\n        let arc_self = Arc::new(self);\n        arc_self.launch_signal_reload_server_task().await\n    }\n\n    #[cfg(windows)]\n    async fn launch_reload_server_task(self) {\n        let _ = self.config_path;\n        let _ = self.balancer;\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use clap::Command;\n\n    #[test]\n    fn verify_local_command() {\n        let mut app = Command::new(\"shadowsocks\")\n            .version(crate::VERSION)\n            .about(\"A fast tunnel proxy that helps you bypass firewalls. (https://shadowsocks.org)\");\n        app = super::define_command_line_options(app);\n        app.debug_assert();\n    }\n}\n"
  },
  {
    "path": "src/service/manager.rs",
    "content": "//! Server Manager launchers\n\nuse std::{future::Future, net::IpAddr, path::PathBuf, process::ExitCode, time::Duration};\n\nuse clap::{Arg, ArgAction, ArgGroup, ArgMatches, Command, ValueHint, builder::PossibleValuesParser};\nuse futures::future::{self, Either};\nuse log::{info, trace};\nuse tokio::{\n    self,\n    runtime::{Builder, Runtime},\n};\n\n#[cfg(unix)]\nuse shadowsocks_service::config::ManagerServerMode;\nuse shadowsocks_service::{\n    acl::AccessControl,\n    config::{Config, ConfigType, ManagerConfig, ManagerServerHost},\n    run_manager,\n    shadowsocks::{\n        config::{ManagerAddr, Mode},\n        crypto::{CipherKind, available_ciphers},\n        plugin::PluginConfig,\n    },\n};\n\n#[cfg(feature = \"logging\")]\nuse crate::logging;\nuse crate::{\n    config::{Config as ServiceConfig, RuntimeMode},\n    error::{ShadowsocksError, ShadowsocksResult},\n    monitor, vparser,\n};\n\n/// Defines command line options\npub fn define_command_line_options(mut app: Command) -> Command {\n    app = app\n        .arg(\n            Arg::new(\"CONFIG\")\n                .short('c')\n                .long(\"config\")\n                .num_args(1)\n                .action(ArgAction::Set)\n                .value_parser(clap::value_parser!(PathBuf))\n                .value_hint(ValueHint::FilePath)\n                .help(\"Shadowsocks configuration file (https://shadowsocks.org/doc/configs.html), the only required fields are \\\"manager_address\\\" and \\\"manager_port\\\". Servers defined will be created when process is started.\"),\n        )\n        .arg(\n            Arg::new(\"UDP_ONLY\")\n                .short('u')\n                .action(ArgAction::SetTrue)\n                .conflicts_with(\"TCP_AND_UDP\")\n                .help(\"Server mode UDP_ONLY\"),\n        )\n        .arg(\n            Arg::new(\"TCP_AND_UDP\")\n                .short('U')\n                .action(ArgAction::SetTrue)\n                .help(\"Server mode TCP_AND_UDP\"),\n        )\n        .arg(\n            Arg::new(\"OUTBOUND_BIND_ADDR\")\n                .short('b')\n                .long(\"outbound-bind-addr\")\n                .num_args(1)\n                .action(ArgAction::Set)\n                .alias(\"bind-addr\")\n                .value_parser(vparser::parse_ip_addr)\n                .help(\"Bind address, outbound socket will bind this address\"),\n        )\n        .arg(\n            Arg::new(\"OUTBOUND_BIND_INTERFACE\")\n                .long(\"outbound-bind-interface\")\n                .num_args(1)\n                .action(ArgAction::Set)\n                .help(\"Set SO_BINDTODEVICE / IP_BOUND_IF / IP_UNICAST_IF option for outbound socket\"),\n        )\n        .arg(Arg::new(\"SERVER_HOST\").short('s').long(\"server-host\").num_args(1).action(ArgAction::Set).value_parser(vparser::parse_manager_server_host).help(\"Host name or IP address of your remote server\"))\n        .arg(\n            Arg::new(\"MANAGER_ADDR\")\n                .long(\"manager-addr\")\n                .num_args(1)\n                .action(ArgAction::Set)\n                .alias(\"manager-address\")\n                .value_parser(vparser::parse_manager_addr)\n                .help(\"ShadowSocks Manager (ssmgr) address, could be ip:port, domain:port or /path/to/unix.sock\"),\n        )\n        .group(ArgGroup::new(\"SERVER_CONFIG\").arg(\"MANAGER_ADDR\"))\n        .arg(Arg::new(\"ENCRYPT_METHOD\").short('m').long(\"encrypt-method\").num_args(1).action(ArgAction::Set).value_parser(PossibleValuesParser::new(available_ciphers())).help(\"Default encryption method\"))\n        .arg(Arg::new(\"TIMEOUT\").long(\"timeout\").num_args(1).action(ArgAction::Set).value_parser(clap::value_parser!(u64)).help(\"Default timeout seconds for TCP relay\"))\n        .arg(\n            Arg::new(\"PLUGIN\")\n                .long(\"plugin\")\n                .num_args(1)\n                .action(ArgAction::Set)\n                .value_hint(ValueHint::CommandName)\n                .help(\"Default SIP003 (https://shadowsocks.org/doc/sip003.html) plugin\"),\n        )\n        .arg(\n            Arg::new(\"PLUGIN_MODE\")\n                .long(\"plugin-mode\")\n                .num_args(1)\n                .action(ArgAction::Set)\n                .requires(\"PLUGIN\")\n                .help(\"SIP003/SIP003u plugin mode, must be one of `tcp_only` (default), `udp_only` and `tcp_and_udp`\"),\n        )\n        .arg(\n            Arg::new(\"PLUGIN_OPT\")\n                .long(\"plugin-opts\")\n                .num_args(1)\n                .action(ArgAction::Set)\n                .requires(\"PLUGIN\")\n                .help(\"Default SIP003 plugin options\"),\n        ).arg(Arg::new(\"ACL\").long(\"acl\").num_args(1).action(ArgAction::Set).value_hint(ValueHint::FilePath).help(\"Path to ACL (Access Control List)\"))\n        .arg(Arg::new(\"DNS\").long(\"dns\").num_args(1).action(ArgAction::Set).help(\"DNS nameservers, formatted like [(tcp|udp)://]host[:port][,host[:port]]..., or unix:///path/to/dns, or predefined keys like \\\"google\\\", \\\"cloudflare\\\"\"))\n        .arg(Arg::new(\"DNS_CACHE_SIZE\").long(\"dns-cache-size\").num_args(1).action(ArgAction::Set).value_parser(clap::value_parser!(usize)).help(\"DNS cache size in number of records. Works when trust-dns DNS backend is used.\"))\n        .arg(Arg::new(\"TCP_NO_DELAY\").long(\"tcp-no-delay\").alias(\"no-delay\").action(ArgAction::SetTrue).help(\"Set TCP_NODELAY option for sockets\"))\n        .arg(Arg::new(\"TCP_FAST_OPEN\").long(\"tcp-fast-open\").alias(\"fast-open\").action(ArgAction::SetTrue).help(\"Enable TCP Fast Open (TFO)\"))\n        .arg(Arg::new(\"TCP_KEEP_ALIVE\").long(\"tcp-keep-alive\").num_args(1).action(ArgAction::Set).value_parser(clap::value_parser!(u64)).help(\"Set TCP keep alive timeout seconds\"))\n        .arg(Arg::new(\"TCP_MULTIPATH\").long(\"tcp-multipath\").alias(\"mptcp\").action(ArgAction::SetTrue).help(\"Enable Multipath-TCP (MPTCP)\"))\n        .arg(Arg::new(\"UDP_TIMEOUT\").long(\"udp-timeout\").num_args(1).action(ArgAction::Set).value_parser(clap::value_parser!(u64)).help(\"Timeout seconds for UDP relay\"))\n        .arg(Arg::new(\"UDP_MAX_ASSOCIATIONS\").long(\"udp-max-associations\").num_args(1).action(ArgAction::Set).value_parser(clap::value_parser!(usize)).help(\"Maximum associations to be kept simultaneously for UDP relay\"))\n        .arg(Arg::new(\"INBOUND_SEND_BUFFER_SIZE\").long(\"inbound-send-buffer-size\").num_args(1).action(ArgAction::Set).value_parser(clap::value_parser!(u32)).help(\"Set inbound sockets' SO_SNDBUF option\"))\n        .arg(Arg::new(\"INBOUND_RECV_BUFFER_SIZE\").long(\"inbound-recv-buffer-size\").num_args(1).action(ArgAction::Set).value_parser(clap::value_parser!(u32)).help(\"Set inbound sockets' SO_RCVBUF option\"))\n        .arg(Arg::new(\"OUTBOUND_SEND_BUFFER_SIZE\").long(\"outbound-send-buffer-size\").num_args(1).action(ArgAction::Set).value_parser(clap::value_parser!(u32)).help(\"Set outbound sockets' SO_SNDBUF option\"))\n        .arg(Arg::new(\"OUTBOUND_RECV_BUFFER_SIZE\").long(\"outbound-recv-buffer-size\").num_args(1).action(ArgAction::Set).value_parser(clap::value_parser!(u32)).help(\"Set outbound sockets' SO_RCVBUF option\"))\n        .arg(\n            Arg::new(\"IPV6_FIRST\")\n                .short('6')\n                .action(ArgAction::SetTrue)\n                .help(\"Resolve hostname to IPv6 address first\"),\n        );\n\n    #[cfg(feature = \"logging\")]\n    {\n        app = app\n            .arg(\n                Arg::new(\"VERBOSE\")\n                    .short('v')\n                    .action(ArgAction::Count)\n                    .help(\"Set log level\"),\n            )\n            .arg(\n                Arg::new(\"LOG_WITHOUT_TIME\")\n                    .long(\"log-without-time\")\n                    .action(ArgAction::SetTrue)\n                    .help(\"Log without datetime prefix\"),\n            )\n            .arg(\n                Arg::new(\"LOG_CONFIG\")\n                    .long(\"log-config\")\n                    // deprecated for removal\n                    .hide(true)\n                    .num_args(1)\n                    .action(ArgAction::Set)\n                    .value_parser(clap::value_parser!(PathBuf))\n                    .value_hint(ValueHint::FilePath)\n                    .help(\"log4rs configuration file\"),\n            );\n    }\n\n    #[cfg(unix)]\n    {\n        app = app\n            .arg(\n                Arg::new(\"DAEMONIZE\")\n                    .short('d')\n                    .long(\"daemonize\")\n                    .action(ArgAction::SetTrue)\n                    .help(\"Daemonize\"),\n            )\n            .arg(\n                Arg::new(\"DAEMONIZE_PID_PATH\")\n                    .long(\"daemonize-pid\")\n                    .num_args(1)\n                    .action(ArgAction::Set)\n                    .value_parser(clap::value_parser!(PathBuf))\n                    .value_hint(ValueHint::FilePath)\n                    .help(\"File path to store daemonized process's PID\"),\n            )\n            .arg(\n                Arg::new(\"MANAGER_SERVER_MODE\")\n                    .long(\"manager-server-mode\")\n                    .num_args(1)\n                    .action(ArgAction::Set)\n                    .value_parser(vparser::parse_manager_server_mode)\n                    // .possible_values([\"builtin\", \"standalone\"])\n                    .help(\"Servers mode: builtin (default) or standalone\"),\n            )\n            .arg(\n                Arg::new(\"MANAGER_SERVER_WORKING_DIRECTORY\")\n                    .long(\"manager-server-working-directory\")\n                    .num_args(1)\n                    .action(ArgAction::Set)\n                    .value_parser(clap::value_parser!(PathBuf))\n                    .value_hint(ValueHint::DirPath)\n                    .help(\"Folder for putting servers' configuration and pid files, default is current directory\"),\n            );\n    }\n\n    #[cfg(all(unix, not(target_os = \"android\")))]\n    {\n        app = app.arg(\n            Arg::new(\"NOFILE\")\n                .short('n')\n                .long(\"nofile\")\n                .num_args(1)\n                .action(ArgAction::Set)\n                .value_parser(clap::value_parser!(u64))\n                .help(\"Set RLIMIT_NOFILE with both soft and hard limit\"),\n        );\n    }\n\n    #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n    {\n        app = app.arg(\n            Arg::new(\"OUTBOUND_FWMARK\")\n                .long(\"outbound-fwmark\")\n                .num_args(1)\n                .action(ArgAction::Set)\n                .value_parser(clap::value_parser!(u32))\n                .help(\"Set SO_MARK option for outbound sockets\"),\n        );\n    }\n\n    #[cfg(target_os = \"freebsd\")]\n    {\n        app = app.arg(\n            Arg::new(\"OUTBOUND_USER_COOKIE\")\n                .long(\"outbound-user-cookie\")\n                .num_args(1)\n                .action(ArgAction::Set)\n                .value_parser(clap::value_parser!(u32))\n                .help(\"Set SO_USER_COOKIE option for outbound sockets\"),\n        );\n    }\n\n    #[cfg(feature = \"multi-threaded\")]\n    {\n        app = app\n            .arg(\n                Arg::new(\"SINGLE_THREADED\")\n                    .long(\"single-threaded\")\n                    .action(ArgAction::SetTrue)\n                    .help(\"Run the program all in one thread\"),\n            )\n            .arg(\n                Arg::new(\"WORKER_THREADS\")\n                    .long(\"worker-threads\")\n                    .num_args(1)\n                    .action(ArgAction::Set)\n                    .value_parser(clap::value_parser!(usize))\n                    .help(\"Sets the number of worker threads the `Runtime` will use\"),\n            );\n    }\n\n    #[cfg(unix)]\n    {\n        app = app.arg(\n            Arg::new(\"USER\")\n                .long(\"user\")\n                .short('a')\n                .num_args(1)\n                .action(ArgAction::Set)\n                .value_hint(ValueHint::Username)\n                .help(\"Run as another user\"),\n        );\n    }\n\n    app\n}\n\n/// Create `Runtime` and `main` entry\npub fn create(matches: &ArgMatches) -> ShadowsocksResult<(Runtime, impl Future<Output = ShadowsocksResult> + use<>)> {\n    let (config, runtime) = {\n        let config_path_opt = matches.get_one::<PathBuf>(\"CONFIG\").cloned().or_else(|| {\n            if !matches.contains_id(\"SERVER_CONFIG\") {\n                match crate::config::get_default_config_path(\"manager.json\") {\n                    None => None,\n                    Some(p) => {\n                        println!(\"loading default config {p:?}\");\n                        Some(p)\n                    }\n                }\n            } else {\n                None\n            }\n        });\n\n        let mut service_config = match config_path_opt {\n            Some(ref config_path) => ServiceConfig::load_from_file(config_path)\n                .map_err(|err| ShadowsocksError::LoadConfigFailure(format!(\"loading config {config_path:?}, {err}\")))?,\n            None => ServiceConfig::default(),\n        };\n        service_config.set_options(matches);\n\n        #[cfg(feature = \"logging\")]\n        match service_config.log.config_path {\n            Some(ref path) => {\n                logging::init_with_file(path);\n            }\n            None => {\n                logging::init_with_config(\"ssmanager\", &service_config.log);\n            }\n        }\n\n        trace!(\"{:?}\", service_config);\n\n        let mut config = match config_path_opt {\n            Some(cpath) => Config::load_from_file(&cpath, ConfigType::Manager)\n                .map_err(|err| ShadowsocksError::LoadConfigFailure(format!(\"loading config {cpath:?}, {err}\")))?,\n            None => Config::new(ConfigType::Manager),\n        };\n\n        if matches.get_flag(\"TCP_NO_DELAY\") {\n            config.no_delay = true;\n        }\n\n        if matches.get_flag(\"TCP_FAST_OPEN\") {\n            config.fast_open = true;\n        }\n\n        if let Some(keep_alive) = matches.get_one::<u64>(\"TCP_KEEP_ALIVE\") {\n            config.keep_alive = Some(Duration::from_secs(*keep_alive));\n        }\n\n        if matches.get_flag(\"TCP_MULTIPATH\") {\n            config.mptcp = true;\n        }\n\n        #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n        if let Some(mark) = matches.get_one::<u32>(\"OUTBOUND_FWMARK\") {\n            config.outbound_fwmark = Some(*mark);\n        }\n\n        #[cfg(target_os = \"freebsd\")]\n        if let Some(user_cookie) = matches.get_one::<u32>(\"OUTBOUND_USER_COOKIE\") {\n            config.outbound_user_cookie = Some(*user_cookie);\n        }\n\n        if let Some(iface) = matches.get_one::<String>(\"OUTBOUND_BIND_INTERFACE\").cloned() {\n            config.outbound_bind_interface = Some(iface);\n        }\n\n        if let Some(addr) = matches.get_one::<ManagerAddr>(\"MANAGER_ADDR\").cloned() {\n            match config.manager {\n                Some(ref mut manager_config) => {\n                    manager_config.addr = addr;\n                }\n                _ => {\n                    config.manager = Some(ManagerConfig::new(addr));\n                }\n            }\n        }\n\n        #[cfg(all(unix, not(target_os = \"android\")))]\n        match matches.get_one::<u64>(\"NOFILE\") {\n            Some(nofile) => config.nofile = Some(*nofile),\n            None => {\n                if config.nofile.is_none() {\n                    crate::sys::adjust_nofile();\n                }\n            }\n        }\n\n        if let Some(ref mut manager_config) = config.manager {\n            if let Some(m) = matches.get_one::<String>(\"ENCRYPT_METHOD\").cloned() {\n                manager_config.method = Some(m.parse::<CipherKind>().expect(\"method\"));\n            }\n\n            if let Some(t) = matches.get_one::<u64>(\"TIMEOUT\") {\n                manager_config.timeout = Some(Duration::from_secs(*t));\n            }\n\n            if let Some(sh) = matches.get_one::<ManagerServerHost>(\"SERVER_HOST\").cloned() {\n                manager_config.server_host = sh;\n            }\n\n            if let Some(p) = matches.get_one::<String>(\"PLUGIN\").cloned() {\n                manager_config.plugin = Some(PluginConfig {\n                    plugin: p,\n                    plugin_opts: matches.get_one::<String>(\"PLUGIN_OPT\").cloned(),\n                    plugin_args: Vec::new(),\n                    plugin_mode: matches\n                        .get_one::<String>(\"PLUGIN_MODE\")\n                        .map(|x| {\n                            x.parse::<Mode>()\n                                .expect(\"plugin-mode must be one of `tcp_only` (default), `udp_only` and `tcp_and_udp`\")\n                        })\n                        .unwrap_or(Mode::TcpOnly),\n                });\n            }\n\n            #[cfg(unix)]\n            if let Some(server_mode) = matches.get_one::<ManagerServerMode>(\"MANAGER_SERVER_MODE\").cloned() {\n                manager_config.server_mode = server_mode;\n            }\n\n            #[cfg(unix)]\n            if let Some(server_working_directory) =\n                matches.get_one::<PathBuf>(\"MANAGER_SERVER_WORKING_DIRECTORY\").cloned()\n            {\n                manager_config.server_working_directory = server_working_directory;\n            }\n        }\n\n        // Overrides\n        if matches.get_flag(\"UDP_ONLY\")\n            && let Some(ref mut m) = config.manager\n        {\n            m.mode = Mode::UdpOnly;\n        }\n\n        if matches.get_flag(\"TCP_AND_UDP\")\n            && let Some(ref mut m) = config.manager\n        {\n            m.mode = Mode::TcpAndUdp;\n        }\n\n        if let Some(acl_file) = matches.get_one::<String>(\"ACL\") {\n            let acl = AccessControl::load_from_file(acl_file)\n                .map_err(|err| ShadowsocksError::LoadAclFailure(format!(\"loading ACL \\\"{acl_file}\\\", {err}\")))?;\n            config.acl = Some(acl);\n        }\n\n        if let Some(dns) = matches.get_one::<String>(\"DNS\") {\n            config.set_dns_formatted(dns).expect(\"dns\");\n        }\n\n        if let Some(dns_cache_size) = matches.get_one::<usize>(\"DNS_CACHE_SIZE\") {\n            config.dns_cache_size = Some(*dns_cache_size);\n        }\n\n        if matches.get_flag(\"IPV6_FIRST\") {\n            config.ipv6_first = true;\n        }\n\n        if let Some(udp_timeout) = matches.get_one::<u64>(\"UDP_TIMEOUT\") {\n            config.udp_timeout = Some(Duration::from_secs(*udp_timeout));\n        }\n\n        if let Some(udp_max_assoc) = matches.get_one::<usize>(\"UDP_MAX_ASSOCIATIONS\") {\n            config.udp_max_associations = Some(*udp_max_assoc);\n        }\n\n        if let Some(bs) = matches.get_one::<u32>(\"INBOUND_SEND_BUFFER_SIZE\") {\n            config.inbound_send_buffer_size = Some(*bs);\n        }\n        if let Some(bs) = matches.get_one::<u32>(\"INBOUND_RECV_BUFFER_SIZE\") {\n            config.inbound_recv_buffer_size = Some(*bs);\n        }\n        if let Some(bs) = matches.get_one::<u32>(\"OUTBOUND_SEND_BUFFER_SIZE\") {\n            config.outbound_send_buffer_size = Some(*bs);\n        }\n        if let Some(bs) = matches.get_one::<u32>(\"OUTBOUND_RECV_BUFFER_SIZE\") {\n            config.outbound_recv_buffer_size = Some(*bs);\n        }\n\n        if let Some(bind_addr) = matches.get_one::<IpAddr>(\"OUTBOUND_BIND_ADDR\") {\n            config.outbound_bind_addr = Some(*bind_addr);\n        }\n\n        // DONE reading options\n\n        config.manager.as_ref().ok_or_else(|| {\n            ShadowsocksError::InsufficientParams(\n                \"missing `manager_address`, consider specifying it by --manager-address command line option, \\\n                    or \\\"manager_address\\\" and \\\"manager_port\\\" keys in configuration file\"\n                    .to_string(),\n            )\n        })?;\n\n        config\n            .check_integrity()\n            .map_err(|err| ShadowsocksError::LoadConfigFailure(format!(\"config integrity check failed, {err}\")))?;\n\n        #[cfg(unix)]\n        if matches.get_flag(\"DAEMONIZE\") || matches.get_raw(\"DAEMONIZE_PID_PATH\").is_some() {\n            use crate::daemonize;\n            daemonize::daemonize(matches.get_one::<PathBuf>(\"DAEMONIZE_PID_PATH\"));\n        }\n\n        #[cfg(unix)]\n        if let Some(uname) = matches.get_one::<String>(\"USER\") {\n            crate::sys::run_as_user(uname).map_err(|err| {\n                ShadowsocksError::InsufficientParams(format!(\"failed to change as user, error: {err}\"))\n            })?;\n        }\n\n        info!(\"shadowsocks manager {} build {}\", crate::VERSION, crate::BUILD_TIME);\n\n        let mut builder = match service_config.runtime.mode {\n            RuntimeMode::SingleThread => Builder::new_current_thread(),\n            #[cfg(feature = \"multi-threaded\")]\n            RuntimeMode::MultiThread => {\n                let mut builder = Builder::new_multi_thread();\n                if let Some(worker_threads) = service_config.runtime.worker_count {\n                    builder.worker_threads(worker_threads);\n                }\n\n                builder\n            }\n        };\n\n        let runtime = builder.enable_all().build().expect(\"create tokio Runtime\");\n\n        (config, runtime)\n    };\n\n    let main_fut = async move {\n        let abort_signal = monitor::create_signal_monitor();\n        let server = run_manager(config);\n\n        tokio::pin!(abort_signal);\n        tokio::pin!(server);\n\n        match future::select(server, abort_signal).await {\n            // Server future resolved without an error. This should never happen.\n            Either::Left((Ok(..), ..)) => Err(ShadowsocksError::ServerExitUnexpectedly(\n                \"server exited unexpectedly\".to_owned(),\n            )),\n            // Server future resolved with error, which are listener errors in most cases\n            Either::Left((Err(err), ..)) => Err(ShadowsocksError::ServerAborted(format!(\"server aborted with {err}\"))),\n            // The abort signal future resolved. Means we should just exit.\n            Either::Right(_) => Ok(()),\n        }\n    };\n\n    Ok((runtime, main_fut))\n}\n\n/// Program entrance `main`\n#[inline]\npub fn main(matches: &ArgMatches) -> ExitCode {\n    match create(matches).and_then(|(runtime, main_fut)| runtime.block_on(main_fut)) {\n        Ok(()) => ExitCode::SUCCESS,\n        Err(err) => {\n            eprintln!(\"{err}\");\n            err.exit_code().into()\n        }\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use clap::Command;\n\n    #[test]\n    fn verify_manager_command() {\n        let mut app = Command::new(\"shadowsocks\")\n            .version(crate::VERSION)\n            .about(\"A fast tunnel proxy that helps you bypass firewalls. (https://shadowsocks.org)\");\n        app = super::define_command_line_options(app);\n        app.debug_assert();\n    }\n}\n"
  },
  {
    "path": "src/service/mod.rs",
    "content": "//! Service launchers\n\npub mod genkey;\n#[cfg(feature = \"local\")]\npub mod local;\n#[cfg(feature = \"manager\")]\npub mod manager;\n#[cfg(feature = \"server\")]\npub mod server;\n"
  },
  {
    "path": "src/service/server.rs",
    "content": "//! Server launchers\n\nuse std::{future::Future, net::IpAddr, path::PathBuf, process::ExitCode, time::Duration};\n\nuse clap::{Arg, ArgAction, ArgGroup, ArgMatches, Command, ValueHint, builder::PossibleValuesParser};\nuse futures::future::{self, Either};\nuse log::{info, trace};\nuse tokio::{\n    self,\n    runtime::{Builder, Runtime},\n};\n\nuse shadowsocks_service::{\n    acl::AccessControl,\n    config::{Config, ConfigType, ManagerConfig, ServerInstanceConfig, read_variable_field_value},\n    run_server,\n    shadowsocks::{\n        config::{ManagerAddr, Mode, ServerAddr, ServerConfig},\n        crypto::{CipherKind, available_ciphers},\n        plugin::PluginConfig,\n    },\n};\n\n#[cfg(feature = \"logging\")]\nuse crate::logging;\nuse crate::{\n    config::{Config as ServiceConfig, RuntimeMode},\n    error::{ShadowsocksError, ShadowsocksResult},\n    monitor, vparser,\n};\n\n/// Defines command line options\npub fn define_command_line_options(mut app: Command) -> Command {\n    app = app\n        .arg(\n            Arg::new(\"CONFIG\")\n                .short('c')\n                .long(\"config\")\n                .num_args(1)\n                .action(ArgAction::Set)\n                .value_parser(clap::value_parser!(PathBuf))\n                .value_hint(ValueHint::FilePath)\n                .help(\"Shadowsocks configuration file (https://shadowsocks.org/doc/configs.html)\"),\n        )\n        .arg(\n            Arg::new(\"OUTBOUND_BIND_ADDR\")\n                .short('b')\n                .long(\"outbound-bind-addr\")\n                .num_args(1)\n                .action(ArgAction::Set)\n                .alias(\"bind-addr\")\n                .value_parser(vparser::parse_ip_addr)\n                .help(\"Bind address, outbound socket will bind this address\"),\n        )\n        .arg(\n            Arg::new(\"OUTBOUND_BIND_INTERFACE\")\n                .long(\"outbound-bind-interface\")\n                .num_args(1)\n                .action(ArgAction::Set)\n                .help(\"Set SO_BINDTODEVICE / IP_BOUND_IF / IP_UNICAST_IF option for outbound socket\"),\n        )\n        .arg(\n            Arg::new(\"SERVER_ADDR\")\n                .short('s')\n                .long(\"server-addr\")\n                .num_args(1)\n                .action(ArgAction::Set)\n                .requires(\"ENCRYPT_METHOD\")\n                .help(\"Server address\"),\n        )\n        .arg(\n            Arg::new(\"PASSWORD\")\n                .short('k')\n                .long(\"password\")\n                .num_args(1)\n                .action(ArgAction::Set)\n                .requires(\"SERVER_ADDR\")\n                .help(\"Server's password\"),\n        )\n        .arg(\n            Arg::new(\"ENCRYPT_METHOD\")\n                .short('m')\n                .long(\"encrypt-method\")\n                .num_args(1)\n                .action(ArgAction::Set)\n                .value_parser(PossibleValuesParser::new(available_ciphers()))\n                .requires(\"SERVER_ADDR\")\n                .help(\"Server's encryption method\"),\n        )\n        .arg(\n            Arg::new(\"TIMEOUT\")\n                .long(\"timeout\")\n                .num_args(1)\n                .action(ArgAction::Set)\n                .value_parser(clap::value_parser!(u64))\n                .requires(\"SERVER_ADDR\")\n                .help(\"Server's timeout seconds for TCP relay\"),\n        )\n        .group(\n            ArgGroup::new(\"SERVER_CONFIG\").arg(\"SERVER_ADDR\")\n        )\n        .arg(\n            Arg::new(\"UDP_ONLY\")\n                .short('u')\n                .action(ArgAction::SetTrue)\n                .conflicts_with(\"TCP_AND_UDP\")\n                .requires(\"SERVER_ADDR\")\n                .help(\"Server mode UDP_ONLY\"),\n        )\n        .arg(\n            Arg::new(\"TCP_AND_UDP\")\n                .short('U')\n                .action(ArgAction::SetTrue)\n                .requires(\"SERVER_ADDR\")\n                .help(\"Server mode TCP_AND_UDP\"),\n        )\n        .arg(\n            Arg::new(\"PLUGIN\")\n                .long(\"plugin\")\n                .num_args(1)\n                .action(ArgAction::Set)\n                .value_hint(ValueHint::CommandName)\n                .requires(\"SERVER_ADDR\")\n                .help(\"SIP003 (https://shadowsocks.org/doc/sip003.html) plugin\"),\n        )\n        .arg(\n            Arg::new(\"PLUGIN_MODE\")\n                .long(\"plugin-mode\")\n                .num_args(1)\n                .action(ArgAction::Set)\n                .requires(\"PLUGIN\")\n                .help(\"SIP003/SIP003u plugin mode, must be one of `tcp_only` (default), `udp_only` and `tcp_and_udp`\"),\n        )\n        .arg(\n            Arg::new(\"PLUGIN_OPT\")\n                .long(\"plugin-opts\")\n                .num_args(1)\n                .action(ArgAction::Set)\n                .requires(\"PLUGIN\")\n                .help(\"Set SIP003 plugin options\"),\n        )\n        .arg(Arg::new(\"MANAGER_ADDR\").long(\"manager-addr\").num_args(1).action(ArgAction::Set).value_parser(vparser::parse_manager_addr).alias(\"manager-address\").help(\"ShadowSocks Manager (ssmgr) address, could be \\\"IP:Port\\\", \\\"Domain:Port\\\" or \\\"/path/to/unix.sock\\\"\"))\n        .arg(Arg::new(\"ACL\").long(\"acl\").num_args(1).action(ArgAction::Set).value_hint(ValueHint::FilePath).help(\"Path to ACL (Access Control List)\"))\n        .arg(Arg::new(\"DNS\").long(\"dns\").num_args(1).action(ArgAction::Set).help(\"DNS nameservers, formatted like [(tcp|udp)://]host[:port][,host[:port]]..., or unix:///path/to/dns, or predefined keys like \\\"google\\\", \\\"cloudflare\\\"\"))\n        .arg(Arg::new(\"DNS_CACHE_SIZE\").long(\"dns-cache-size\").num_args(1).action(ArgAction::Set).value_parser(clap::value_parser!(usize)).help(\"DNS cache size in number of records. Works when trust-dns DNS backend is enabled.\"))\n        .arg(Arg::new(\"TCP_NO_DELAY\").long(\"tcp-no-delay\").alias(\"no-delay\").action(ArgAction::SetTrue).help(\"Set TCP_NODELAY option for sockets\"))\n        .arg(Arg::new(\"TCP_FAST_OPEN\").long(\"tcp-fast-open\").alias(\"fast-open\").action(ArgAction::SetTrue).help(\"Enable TCP Fast Open (TFO)\"))\n        .arg(Arg::new(\"TCP_KEEP_ALIVE\").long(\"tcp-keep-alive\").num_args(1).action(ArgAction::Set).value_parser(clap::value_parser!(u64)).help(\"Set TCP keep alive timeout seconds\"))\n        .arg(Arg::new(\"TCP_MULTIPATH\").long(\"tcp-multipath\").alias(\"mptcp\").action(ArgAction::SetTrue).help(\"Enable Multipath-TCP (MPTCP)\"))\n        .arg(Arg::new(\"UDP_TIMEOUT\").long(\"udp-timeout\").num_args(1).action(ArgAction::Set).value_parser(clap::value_parser!(u64)).help(\"Timeout seconds for UDP relay\"))\n        .arg(Arg::new(\"UDP_MAX_ASSOCIATIONS\").long(\"udp-max-associations\").num_args(1).action(ArgAction::Set).value_parser(clap::value_parser!(usize)).help(\"Maximum associations to be kept simultaneously for UDP relay\"))\n        .arg(Arg::new(\"INBOUND_SEND_BUFFER_SIZE\").long(\"inbound-send-buffer-size\").num_args(1).action(ArgAction::Set).value_parser(clap::value_parser!(u32)).help(\"Set inbound sockets' SO_SNDBUF option\"))\n        .arg(Arg::new(\"INBOUND_RECV_BUFFER_SIZE\").long(\"inbound-recv-buffer-size\").num_args(1).action(ArgAction::Set).value_parser(clap::value_parser!(u32)).help(\"Set inbound sockets' SO_RCVBUF option\"))\n        .arg(Arg::new(\"OUTBOUND_SEND_BUFFER_SIZE\").long(\"outbound-send-buffer-size\").num_args(1).action(ArgAction::Set).value_parser(clap::value_parser!(u32)).help(\"Set outbound sockets' SO_SNDBUF option\"))\n        .arg(Arg::new(\"OUTBOUND_RECV_BUFFER_SIZE\").long(\"outbound-recv-buffer-size\").num_args(1).action(ArgAction::Set).value_parser(clap::value_parser!(u32)).help(\"Set outbound sockets' SO_RCVBUF option\"))\n        .arg(\n            Arg::new(\"IPV6_FIRST\")\n                .short('6')\n                .action(ArgAction::SetTrue)\n                .help(\"Resolve hostname to IPv6 address first\"),\n        );\n\n    #[cfg(feature = \"logging\")]\n    {\n        app = app\n            .arg(\n                Arg::new(\"VERBOSE\")\n                    .short('v')\n                    .action(ArgAction::Count)\n                    .help(\"Set log level\"),\n            )\n            .arg(\n                Arg::new(\"LOG_WITHOUT_TIME\")\n                    .long(\"log-without-time\")\n                    .action(ArgAction::SetTrue)\n                    .help(\"Log without datetime prefix\"),\n            )\n            .arg(\n                Arg::new(\"LOG_CONFIG\")\n                    .long(\"log-config\")\n                    // deprecated for removal\n                    .hide(true)\n                    .num_args(1)\n                    .action(ArgAction::Set)\n                    .value_parser(clap::value_parser!(PathBuf))\n                    .value_hint(ValueHint::FilePath)\n                    .help(\"log4rs configuration file\"),\n            );\n    }\n\n    #[cfg(unix)]\n    {\n        app = app\n            .arg(\n                Arg::new(\"DAEMONIZE\")\n                    .short('d')\n                    .long(\"daemonize\")\n                    .action(ArgAction::SetTrue)\n                    .help(\"Daemonize\"),\n            )\n            .arg(\n                Arg::new(\"DAEMONIZE_PID_PATH\")\n                    .long(\"daemonize-pid\")\n                    .num_args(1)\n                    .action(ArgAction::Set)\n                    .value_parser(clap::value_parser!(PathBuf))\n                    .value_hint(ValueHint::FilePath)\n                    .help(\"File path to store daemonized process's PID\"),\n            );\n    }\n\n    #[cfg(all(unix, not(target_os = \"android\")))]\n    {\n        app = app.arg(\n            Arg::new(\"NOFILE\")\n                .short('n')\n                .long(\"nofile\")\n                .num_args(1)\n                .action(ArgAction::Set)\n                .value_parser(clap::value_parser!(u64))\n                .help(\"Set RLIMIT_NOFILE with both soft and hard limit\"),\n        );\n    }\n\n    #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n    {\n        app = app.arg(\n            Arg::new(\"OUTBOUND_FWMARK\")\n                .long(\"outbound-fwmark\")\n                .num_args(1)\n                .action(ArgAction::Set)\n                .value_parser(clap::value_parser!(u32))\n                .help(\"Set SO_MARK option for outbound sockets\"),\n        );\n    }\n\n    #[cfg(target_os = \"freebsd\")]\n    {\n        app = app.arg(\n            Arg::new(\"OUTBOUND_USER_COOKIE\")\n                .long(\"outbound-user-cookie\")\n                .num_args(1)\n                .action(ArgAction::Set)\n                .value_parser(clap::value_parser!(u32))\n                .help(\"Set SO_USER_COOKIE option for outbound sockets\"),\n        );\n    }\n\n    #[cfg(feature = \"multi-threaded\")]\n    {\n        app = app\n            .arg(\n                Arg::new(\"SINGLE_THREADED\")\n                    .long(\"single-threaded\")\n                    .action(ArgAction::SetTrue)\n                    .help(\"Run the program all in one thread\"),\n            )\n            .arg(\n                Arg::new(\"WORKER_THREADS\")\n                    .long(\"worker-threads\")\n                    .num_args(1)\n                    .action(ArgAction::Set)\n                    .value_parser(clap::value_parser!(usize))\n                    .help(\"Sets the number of worker threads the `Runtime` will use\"),\n            );\n    }\n\n    #[cfg(unix)]\n    {\n        app = app.arg(\n            Arg::new(\"USER\")\n                .long(\"user\")\n                .short('a')\n                .num_args(1)\n                .action(ArgAction::Set)\n                .value_hint(ValueHint::Username)\n                .help(\"Run as another user\"),\n        );\n    }\n\n    app\n}\n\n/// Create `Runtime` and `main` entry\npub fn create(matches: &ArgMatches) -> ShadowsocksResult<(Runtime, impl Future<Output = ShadowsocksResult> + use<>)> {\n    let (config, runtime) = {\n        let config_path_opt = matches.get_one::<PathBuf>(\"CONFIG\").cloned().or_else(|| {\n            if !matches.contains_id(\"SERVER_CONFIG\") {\n                match crate::config::get_default_config_path(\"server.json\") {\n                    None => None,\n                    Some(p) => {\n                        println!(\"loading default config {p:?}\");\n                        Some(p)\n                    }\n                }\n            } else {\n                None\n            }\n        });\n\n        let mut service_config = match config_path_opt {\n            Some(ref config_path) => ServiceConfig::load_from_file(config_path)\n                .map_err(|err| ShadowsocksError::LoadConfigFailure(format!(\"loading config {config_path:?}, {err}\")))?,\n            None => ServiceConfig::default(),\n        };\n        service_config.set_options(matches);\n\n        #[cfg(feature = \"logging\")]\n        match service_config.log.config_path {\n            Some(ref path) => {\n                logging::init_with_file(path);\n            }\n            None => {\n                logging::init_with_config(\"ssserver\", &service_config.log);\n            }\n        }\n\n        trace!(\"{:?}\", service_config);\n\n        let mut config = match config_path_opt {\n            Some(cpath) => Config::load_from_file(&cpath, ConfigType::Server)\n                .map_err(|err| ShadowsocksError::LoadConfigFailure(format!(\"loading config {cpath:?}, {err}\")))?,\n            None => Config::new(ConfigType::Server),\n        };\n\n        if let Some(svr_addr) = matches.get_one::<String>(\"SERVER_ADDR\") {\n            let method = matches\n                .get_one::<String>(\"ENCRYPT_METHOD\")\n                .map(|x| x.parse::<CipherKind>().expect(\"method\"))\n                .expect(\"`method` is required\");\n\n            let password = match matches.get_one::<String>(\"PASSWORD\") {\n                Some(pwd) => read_variable_field_value(pwd).into(),\n                None => {\n                    // NOTE: svr_addr should have been checked by crate::vparser\n                    if method.is_none() {\n                        // If method doesn't need a key (none, plain), then we can leave it empty\n                        String::new()\n                    } else {\n                        match crate::password::read_server_password(svr_addr) {\n                            Ok(pwd) => pwd,\n                            Err(..) => panic!(\"`password` is required for server {svr_addr}\"),\n                        }\n                    }\n                }\n            };\n\n            let svr_addr = svr_addr.parse::<ServerAddr>().expect(\"server-addr\");\n            let timeout = matches.get_one::<u64>(\"TIMEOUT\").map(|x| Duration::from_secs(*x));\n\n            let mut sc = match ServerConfig::new(svr_addr, password, method) {\n                Ok(sc) => sc,\n                Err(err) => {\n                    panic!(\"failed to create ServerConfig, error: {}\", err);\n                }\n            };\n            if let Some(timeout) = timeout {\n                sc.set_timeout(timeout);\n            }\n\n            if let Some(p) = matches.get_one::<String>(\"PLUGIN\").cloned() {\n                let plugin = PluginConfig {\n                    plugin: p,\n                    plugin_opts: matches.get_one::<String>(\"PLUGIN_OPT\").cloned(),\n                    plugin_args: Vec::new(),\n                    plugin_mode: matches\n                        .get_one::<String>(\"PLUGIN_MODE\")\n                        .map(|x| {\n                            x.parse::<Mode>()\n                                .expect(\"plugin-mode must be one of `tcp_only` (default), `udp_only` and `tcp_and_udp`\")\n                        })\n                        .unwrap_or(Mode::TcpOnly),\n                };\n\n                sc.set_plugin(plugin);\n            }\n\n            // For historical reason, servers that are created from command-line have to be tcp_only.\n            sc.set_mode(Mode::TcpOnly);\n\n            if matches.get_flag(\"UDP_ONLY\") {\n                sc.set_mode(Mode::UdpOnly);\n            }\n\n            if matches.get_flag(\"TCP_AND_UDP\") {\n                sc.set_mode(Mode::TcpAndUdp);\n            }\n\n            config.server.push(ServerInstanceConfig::with_server_config(sc));\n        }\n\n        if matches.get_flag(\"TCP_NO_DELAY\") {\n            config.no_delay = true;\n        }\n\n        if matches.get_flag(\"TCP_FAST_OPEN\") {\n            config.fast_open = true;\n        }\n\n        if let Some(keep_alive) = matches.get_one::<u64>(\"TCP_KEEP_ALIVE\") {\n            config.keep_alive = Some(Duration::from_secs(*keep_alive));\n        }\n\n        if matches.get_flag(\"TCP_MULTIPATH\") {\n            config.mptcp = true;\n        }\n\n        #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n        if let Some(mark) = matches.get_one::<u32>(\"OUTBOUND_FWMARK\") {\n            config.outbound_fwmark = Some(*mark);\n        }\n\n        #[cfg(target_os = \"freebsd\")]\n        if let Some(user_cookie) = matches.get_one::<u32>(\"OUTBOUND_USER_COOKIE\") {\n            config.outbound_user_cookie = Some(*user_cookie);\n        }\n\n        if let Some(iface) = matches.get_one::<String>(\"OUTBOUND_BIND_INTERFACE\").cloned() {\n            config.outbound_bind_interface = Some(iface);\n        }\n\n        if let Some(addr) = matches.get_one::<ManagerAddr>(\"MANAGER_ADDR\").cloned() {\n            match config.manager {\n                Some(ref mut manager_config) => {\n                    manager_config.addr = addr;\n                }\n                _ => {\n                    config.manager = Some(ManagerConfig::new(addr));\n                }\n            }\n        }\n\n        #[cfg(all(unix, not(target_os = \"android\")))]\n        match matches.get_one::<u64>(\"NOFILE\") {\n            Some(nofile) => config.nofile = Some(*nofile),\n            None => {\n                if config.nofile.is_none() {\n                    crate::sys::adjust_nofile();\n                }\n            }\n        }\n\n        if let Some(acl_file) = matches.get_one::<String>(\"ACL\") {\n            let acl = AccessControl::load_from_file(acl_file)\n                .map_err(|err| ShadowsocksError::LoadAclFailure(format!(\"loading ACL \\\"{acl_file}\\\", {err}\")))?;\n            config.acl = Some(acl);\n        }\n\n        if let Some(dns) = matches.get_one::<String>(\"DNS\") {\n            config.set_dns_formatted(dns).expect(\"dns\");\n        }\n\n        if let Some(dns_cache_size) = matches.get_one::<usize>(\"DNS_CACHE_SIZE\") {\n            config.dns_cache_size = Some(*dns_cache_size);\n        }\n\n        if matches.get_flag(\"IPV6_FIRST\") {\n            config.ipv6_first = true;\n        }\n\n        if let Some(udp_timeout) = matches.get_one::<u64>(\"UDP_TIMEOUT\") {\n            config.udp_timeout = Some(Duration::from_secs(*udp_timeout));\n        }\n\n        if let Some(udp_max_assoc) = matches.get_one::<usize>(\"UDP_MAX_ASSOCIATIONS\") {\n            config.udp_max_associations = Some(*udp_max_assoc);\n        }\n\n        if let Some(bs) = matches.get_one::<u32>(\"INBOUND_SEND_BUFFER_SIZE\") {\n            config.inbound_send_buffer_size = Some(*bs);\n        }\n        if let Some(bs) = matches.get_one::<u32>(\"INBOUND_RECV_BUFFER_SIZE\") {\n            config.inbound_recv_buffer_size = Some(*bs);\n        }\n        if let Some(bs) = matches.get_one::<u32>(\"OUTBOUND_SEND_BUFFER_SIZE\") {\n            config.outbound_send_buffer_size = Some(*bs);\n        }\n        if let Some(bs) = matches.get_one::<u32>(\"OUTBOUND_RECV_BUFFER_SIZE\") {\n            config.outbound_recv_buffer_size = Some(*bs);\n        }\n\n        if let Some(bind_addr) = matches.get_one::<IpAddr>(\"OUTBOUND_BIND_ADDR\") {\n            config.outbound_bind_addr = Some(*bind_addr);\n        }\n\n        // DONE READING options\n\n        if config.server.is_empty() {\n            return Err(ShadowsocksError::InsufficientParams(\n                \"missing proxy servers, consider specifying it by \\\n                    --server-addr, --encrypt-method, --password command line option, \\\n                        or configuration file, check more details in https://shadowsocks.org/doc/configs.html\"\n                    .to_string(),\n            ));\n        }\n\n        config\n            .check_integrity()\n            .map_err(|err| ShadowsocksError::LoadConfigFailure(format!(\"config integrity check failed, {err}\")))?;\n\n        #[cfg(unix)]\n        if matches.get_flag(\"DAEMONIZE\") || matches.get_raw(\"DAEMONIZE_PID_PATH\").is_some() {\n            use crate::daemonize;\n            daemonize::daemonize(matches.get_one::<PathBuf>(\"DAEMONIZE_PID_PATH\"));\n        }\n\n        #[cfg(unix)]\n        if let Some(uname) = matches.get_one::<String>(\"USER\") {\n            crate::sys::run_as_user(uname).map_err(|err| {\n                ShadowsocksError::InsufficientParams(format!(\"failed to change as user, error: {err}\"))\n            })?;\n        }\n\n        info!(\"shadowsocks server {} build {}\", crate::VERSION, crate::BUILD_TIME);\n\n        let mut builder = match service_config.runtime.mode {\n            RuntimeMode::SingleThread => Builder::new_current_thread(),\n            #[cfg(feature = \"multi-threaded\")]\n            RuntimeMode::MultiThread => {\n                let mut builder = Builder::new_multi_thread();\n                if let Some(worker_threads) = service_config.runtime.worker_count {\n                    builder.worker_threads(worker_threads);\n                }\n\n                builder\n            }\n        };\n\n        let runtime = builder.enable_all().build().expect(\"create tokio Runtime\");\n\n        (config, runtime)\n    };\n\n    let main_fut = async move {\n        let abort_signal = monitor::create_signal_monitor();\n        let server = run_server(config);\n\n        tokio::pin!(abort_signal);\n        tokio::pin!(server);\n\n        match future::select(server, abort_signal).await {\n            // Server future resolved without an error. This should never happen.\n            Either::Left((Ok(..), ..)) => Err(ShadowsocksError::ServerExitUnexpectedly(\n                \"server exited unexpectedly\".to_owned(),\n            )),\n            // Server future resolved with error, which are listener errors in most cases\n            Either::Left((Err(err), ..)) => Err(ShadowsocksError::ServerAborted(format!(\"server aborted with {err}\"))),\n            // The abort signal future resolved. Means we should just exit.\n            Either::Right(_) => Ok(()),\n        }\n    };\n\n    Ok((runtime, main_fut))\n}\n\n/// Program entrance `main`\n#[inline]\npub fn main(matches: &ArgMatches) -> ExitCode {\n    match create(matches).and_then(|(runtime, main_fut)| runtime.block_on(main_fut)) {\n        Ok(()) => ExitCode::SUCCESS,\n        Err(err) => {\n            eprintln!(\"{err}\");\n            err.exit_code().into()\n        }\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use clap::Command;\n\n    #[test]\n    fn verify_server_command() {\n        let mut app = Command::new(\"shadowsocks\")\n            .version(crate::VERSION)\n            .about(\"A fast tunnel proxy that helps you bypass firewalls. (https://shadowsocks.org)\");\n        app = super::define_command_line_options(app);\n        app.debug_assert();\n    }\n}\n"
  },
  {
    "path": "src/sys.rs",
    "content": "//! System related APIs\n\n/// Some systems set an artificially low soft limit on open file count, for compatibility\n/// with code that uses select and its hard-coded maximum file descriptor\n/// (limited by the size of fd_set).\n///\n/// Tokio (Mio) doesn't use select.\n///\n/// http://0pointer.net/blog/file-descriptor-limits.html\n/// https://github.com/golang/go/issues/46279\n#[cfg(all(unix, not(target_os = \"android\")))]\npub fn adjust_nofile() {\n    use log::{debug, trace};\n    use std::{io::Error, mem};\n\n    unsafe {\n        let mut lim: libc::rlimit = mem::zeroed();\n        let ret = libc::getrlimit(libc::RLIMIT_NOFILE, &mut lim);\n        if ret < 0 {\n            debug!(\"getrlimit NOFILE failed, {}\", Error::last_os_error());\n            return;\n        }\n\n        if lim.rlim_cur != lim.rlim_max {\n            trace!(\"rlimit NOFILE {:?} require adjustion\", lim);\n            lim.rlim_cur = lim.rlim_max;\n\n            // On older macOS, setrlimit with rlim_cur = infinity will fail.\n            #[cfg(any(target_os = \"macos\", target_os = \"ios\", target_os = \"watchos\", target_os = \"tvos\"))]\n            {\n                use std::ptr;\n\n                unsafe extern \"C\" {\n                    fn sysctlbyname(\n                        name: *const libc::c_char,\n                        oldp: *mut libc::c_void,\n                        oldlenp: *mut libc::size_t,\n                        newp: *mut libc::c_void,\n                        newlen: libc::size_t,\n                    ) -> libc::c_int;\n                }\n\n                // CTL_KERN\n                //\n                // Name                         Type                    Changeable\n                // kern.maxfiles                int32_t                 yes\n                // kern.maxfilesperproc         int32_t                 yes\n\n                let name = b\"kern.maxfilesperproc\\0\";\n                let mut nfile: i32 = 0;\n                let mut nfile_len: libc::size_t = mem::size_of_val(&nfile);\n\n                let ret = sysctlbyname(\n                    name.as_ptr() as *const _,\n                    &mut nfile as *mut _ as *mut _,\n                    &mut nfile_len,\n                    ptr::null_mut(),\n                    0,\n                );\n\n                if ret < 0 {\n                    debug!(\"sysctlbyname kern.maxfilesperproc failed, {}\", Error::last_os_error());\n                } else {\n                    lim.rlim_cur = nfile as libc::rlim_t;\n                }\n            }\n\n            let ret = libc::setrlimit(libc::RLIMIT_NOFILE, &lim);\n            if ret < 0 {\n                debug!(\"setrlimit NOFILE {:?} failed, {}\", lim, Error::last_os_error());\n            } else {\n                debug!(\"rlimit NOFILE adjusted {:?}\", lim);\n            }\n        }\n    }\n}\n\n/// setuid(), setgid() for a specific user or uid\n#[cfg(unix)]\npub fn run_as_user(uname: &str) -> std::io::Result<()> {\n    use log::error;\n    use std::{\n        ffi::{CStr, CString},\n        io::{Error, ErrorKind},\n    };\n\n    unsafe {\n        let pwd = match uname.parse::<libc::uid_t>() {\n            Ok(uid) => {\n                let mut pwd = libc::getpwuid(uid);\n                if pwd.is_null() {\n                    let uname = CString::new(uname).expect(\"username\");\n                    pwd = libc::getpwnam(uname.as_ptr())\n                }\n                pwd\n            }\n            Err(..) => {\n                let uname = CString::new(uname).expect(\"username\");\n                libc::getpwnam(uname.as_ptr())\n            }\n        };\n\n        if pwd.is_null() {\n            return Err(Error::new(ErrorKind::InvalidInput, format!(\"user {} not found\", uname)));\n        }\n\n        let pwd = &*pwd;\n\n        // setgid first, because we may not allowed to do it anymore after setuid\n        if libc::setgid(pwd.pw_gid as libc::gid_t) != 0 {\n            let err = Error::last_os_error();\n\n            error!(\n                \"could not change group id to user {:?}'s gid: {}, uid: {}, error: {}\",\n                CStr::from_ptr(pwd.pw_name),\n                pwd.pw_gid,\n                pwd.pw_uid,\n                err\n            );\n            return Err(err);\n        }\n\n        if libc::initgroups(pwd.pw_name, pwd.pw_gid as _) != 0 {\n            let err = Error::last_os_error();\n            error!(\n                \"could not change supplementary groups to user {:?}'s gid: {}, uid: {}, error: {}\",\n                CStr::from_ptr(pwd.pw_name),\n                pwd.pw_gid,\n                pwd.pw_uid,\n                err\n            );\n            return Err(err);\n        }\n\n        if libc::setuid(pwd.pw_uid) != 0 {\n            let err = Error::last_os_error();\n            error!(\n                \"could not change user id to user {:?}'s gid: {}, uid: {}, error: {}\",\n                CStr::from_ptr(pwd.pw_name),\n                pwd.pw_gid,\n                pwd.pw_uid,\n                err\n            );\n            return Err(err);\n        }\n    }\n\n    Ok(())\n}\n"
  },
  {
    "path": "src/vparser/mod.rs",
    "content": "//! Command line argument validator\n\n#![allow(dead_code)]\n\nuse std::net::{IpAddr, SocketAddr};\n\n#[cfg(any(feature = \"local-tun\", feature = \"local-fake-dns\"))]\nuse ipnet::IpNet;\n#[cfg(feature = \"local-redir\")]\nuse shadowsocks_service::config::RedirType;\n#[cfg(feature = \"local-dns\")]\nuse shadowsocks_service::local::dns::NameServerAddr;\nuse shadowsocks_service::{\n    config::{ManagerServerHost, ManagerServerMode},\n    shadowsocks::{ManagerAddr, ServerAddr, ServerConfig, crypto::CipherKind, relay::socks5::Address},\n};\n\nmacro_rules! value_parser_type {\n    ($name:ident, $ty:ty, $help:expr) => {\n        pub fn $name(v: &str) -> Result<$ty, String> {\n            match v.parse::<$ty>() {\n                Ok(t) => Ok(t),\n                Err(..) => Err($help.to_owned()),\n            }\n        }\n    };\n}\n\nvalue_parser_type!(parse_server_addr, ServerAddr, \"should be either ip:port or domain:port\");\nvalue_parser_type!(parse_ip_addr, IpAddr, \"should be a valid IPv4 or IPv6 address\");\nvalue_parser_type!(parse_socket_addr, SocketAddr, \"should be ip:port\");\nvalue_parser_type!(parse_address, Address, \"should be either ip:port or domain:port\");\nvalue_parser_type!(\n    parse_manager_addr,\n    ManagerAddr,\n    \"should be either ip:port, domain:port or /path/to/unix.sock\"\n);\nvalue_parser_type!(parse_manager_server_host, ManagerServerHost, \"invalid server-host\");\nvalue_parser_type!(\n    parse_manager_server_mode,\n    ManagerServerMode,\n    \"should be \\\"builtin\\\" or \\\"standalone\\\"\"\n);\n#[cfg(feature = \"local-dns\")]\nvalue_parser_type!(\n    parse_name_server_addr,\n    NameServerAddr,\n    \"should be either ip:port or a path to unix domain socket\"\n);\nvalue_parser_type!(parse_cipher_kind, CipherKind, \"invalid cipher\");\n\npub fn parse_server_url(v: &str) -> Result<ServerConfig, String> {\n    match ServerConfig::from_url(v) {\n        Ok(t) => Ok(t),\n        Err(..) => Err(\"should be SIP002 (https://shadowsocks.org/doc/sip002.html) format\".to_owned()),\n    }\n}\n\n#[cfg(any(feature = \"local-tun\", feature = \"local-fake-dns\"))]\npub fn parse_ipnet(v: &str) -> Result<IpNet, String> {\n    match v.parse::<IpNet>() {\n        Err(..) => Err(\"should be a CIDR address like 10.1.2.3/24\".to_owned()),\n        Ok(n) => Ok(n),\n    }\n}\n\n#[cfg(feature = \"local-redir\")]\nvalue_parser_type!(parse_redir_type, RedirType, \"invalid redir-type\");\n"
  },
  {
    "path": "tests/dns.rs",
    "content": "#![cfg(all(feature = \"local-dns\", feature = \"server\"))]\n\nuse std::time::Duration;\n\nuse byteorder::{BigEndian, ByteOrder};\nuse tokio::{\n    io::{AsyncReadExt, AsyncWriteExt},\n    net::{TcpStream, UdpSocket},\n    time,\n};\n\nuse shadowsocks_service::{\n    config::{Config, ConfigType},\n    run_local, run_server,\n};\n\n#[tokio::test]\nasync fn dns_relay() {\n    let _ = env_logger::try_init();\n\n    let local_config = Config::load_from_str(\n        r#\"{\n            \"locals\": [\n                {\n                    \"local_address\": \"127.0.0.1\",\n                    \"local_port\": 6110,\n                    \"protocol\": \"dns\",\n                    \"local_dns_address\": \"114.114.114.114\",\n                    \"remote_dns_address\": \"8.8.8.8\"\n                }\n            ],\n            \"server\": \"127.0.0.1\",\n            \"server_port\": 6120,\n            \"password\": \"password\",\n            \"method\": \"aes-256-gcm\"\n        }\"#,\n        ConfigType::Local,\n    )\n    .unwrap();\n\n    let server_config = Config::load_from_str(\n        r#\"{\n            \"server\": \"127.0.0.1\",\n            \"server_port\": 6120,\n            \"password\": \"password\",\n            \"method\": \"aes-256-gcm\",\n            \"mode\": \"tcp_and_udp\"\n        }\"#,\n        ConfigType::Server,\n    )\n    .unwrap();\n\n    tokio::spawn(run_local(local_config));\n    tokio::spawn(run_server(server_config));\n\n    time::sleep(Duration::from_secs(1)).await;\n\n    // Query firefox.com, TransactionID: 0x1234\n    const DNS_QUERY: &[u8] = b\"\\x12\\x34\\x01\\x00\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x07firefox\\x03com\\x00\\x00\\x01\\x00\\x01\";\n\n    // 1. DoT\n    {\n        let mut c = TcpStream::connect(\"127.0.0.1:6110\").await.unwrap();\n\n        let mut len_buf = [0u8; 2];\n        BigEndian::write_u16(&mut len_buf, DNS_QUERY.len() as u16);\n        c.write_all(&len_buf).await.unwrap();\n\n        c.write_all(DNS_QUERY).await.unwrap();\n        c.flush().await.unwrap();\n\n        c.read_exact(&mut len_buf).await.unwrap();\n        let resp_len = BigEndian::read_u16(&len_buf);\n\n        let mut buf = vec![0u8; resp_len as usize];\n        c.read_exact(&mut buf).await.unwrap();\n\n        assert!(buf.starts_with(b\"\\x12\\x34\"));\n    }\n\n    // 2. DoU\n    {\n        let c = UdpSocket::bind(\"0.0.0.0:0\").await.unwrap();\n        c.send_to(DNS_QUERY, \"127.0.0.1:6110\").await.unwrap();\n\n        let mut buf = [0u8; 65536];\n        let n = c.recv(&mut buf).await.unwrap();\n        assert!(n >= 12);\n\n        let pkt = &buf[..n];\n        assert_eq!(&pkt[..2], b\"\\x12\\x34\");\n    }\n}\n"
  },
  {
    "path": "tests/http.rs",
    "content": "#![cfg(all(feature = \"local-http\", feature = \"server\"))]\n\nuse std::time::Duration;\n\nuse tokio::{\n    io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader},\n    net::TcpStream,\n    time,\n};\n\nuse shadowsocks_service::{\n    config::{Config, ConfigType},\n    run_local, run_server,\n};\n\n#[tokio::test]\nasync fn http_proxy() {\n    let _ = env_logger::try_init();\n\n    let local_config = Config::load_from_str(\n        r#\"{\n            \"locals\": [\n                {\n                    \"local_port\": 5110,\n                    \"local_address\": \"127.0.0.1\",\n                    \"protocol\": \"http\"\n                }\n            ],\n            \"server\": \"127.0.0.1\",\n            \"server_port\": 5120,\n            \"password\": \"password\",\n            \"method\": \"aes-256-gcm\"\n        }\"#,\n        ConfigType::Local,\n    )\n    .unwrap();\n\n    let server_config = Config::load_from_str(\n        r#\"{\n            \"server\": \"127.0.0.1\",\n            \"server_port\": 5120,\n            \"password\": \"password\",\n            \"method\": \"aes-256-gcm\"\n        }\"#,\n        ConfigType::Server,\n    )\n    .unwrap();\n\n    tokio::spawn(run_local(local_config));\n    tokio::spawn(run_server(server_config));\n\n    time::sleep(Duration::from_secs(1)).await;\n\n    {\n        let mut c = TcpStream::connect(\"127.0.0.1:5110\").await.unwrap();\n        c.write_all(b\"GET http://www.example.com/ HTTP/1.0\\r\\nHost: www.example.com\\r\\nAccept: */*\\r\\n\\r\\n\")\n            .await\n            .unwrap();\n        c.flush().await.unwrap();\n\n        // Proxy should close connection actively because HTTP/1.0 use short connection by default\n        let mut buf = Vec::new();\n        c.read_to_end(&mut buf).await.unwrap();\n\n        assert!(buf.starts_with(b\"HTTP/1.0 200 OK\\r\\n\"));\n    }\n\n    {\n        let mut c = TcpStream::connect(\"127.0.0.1:5110\").await.unwrap();\n        c.write_all(b\"CONNECT http://www.example.com/ HTTP/1.0\\r\\n\\r\\n\")\n            .await\n            .unwrap();\n        c.flush().await.unwrap();\n\n        c.write_all(b\"GET / HTTP/1.0\\r\\nHost: www.example.com\\r\\nAccept: */*\\r\\n\\r\\n\")\n            .await\n            .unwrap();\n        c.flush().await.unwrap();\n\n        let mut r = BufReader::new(c);\n\n        let mut buf = Vec::new();\n        r.read_until(b'\\n', &mut buf).await.unwrap();\n\n        assert!(buf.starts_with(b\"HTTP/1.0 200 OK\\r\\n\"));\n    }\n}\n"
  },
  {
    "path": "tests/socks4.rs",
    "content": "#![cfg(all(feature = \"local-socks4\", feature = \"server\"))]\n\nuse std::{\n    net::{SocketAddr, ToSocketAddrs},\n    str,\n};\n\nuse tokio::{\n    io::{AsyncBufReadExt, AsyncWriteExt, BufReader},\n    time::{self, Duration},\n};\n\nuse shadowsocks_service::{\n    config::{Config, ConfigType, LocalConfig, LocalInstanceConfig, ProtocolType, ServerInstanceConfig},\n    local::socks::client::Socks4TcpClient,\n    run_local, run_server,\n    shadowsocks::{\n        config::{ServerAddr, ServerConfig},\n        crypto::CipherKind,\n    },\n};\n\npub struct Socks4TestServer {\n    local_addr: SocketAddr,\n    svr_config: Config,\n    cli_config: Config,\n}\n\nimpl Socks4TestServer {\n    pub fn new<S, L>(svr_addr: S, local_addr: L, pwd: &str, method: CipherKind) -> Self\n    where\n        S: ToSocketAddrs,\n        L: ToSocketAddrs,\n    {\n        let svr_addr = svr_addr.to_socket_addrs().unwrap().next().unwrap();\n        let local_addr = local_addr.to_socket_addrs().unwrap().next().unwrap();\n\n        Self {\n            local_addr,\n            svr_config: {\n                let mut cfg = Config::new(ConfigType::Server);\n                cfg.server = vec![ServerInstanceConfig::with_server_config(\n                    ServerConfig::new(svr_addr, pwd.to_owned(), method).unwrap(),\n                )];\n                cfg\n            },\n            cli_config: {\n                let mut cfg = Config::new(ConfigType::Local);\n                cfg.local = vec![LocalInstanceConfig::with_local_config(LocalConfig::new_with_addr(\n                    ServerAddr::from(local_addr),\n                    ProtocolType::Socks,\n                ))];\n                cfg.server = vec![ServerInstanceConfig::with_server_config(\n                    ServerConfig::new(svr_addr, pwd.to_owned(), method).unwrap(),\n                )];\n                cfg\n            },\n        }\n    }\n\n    pub fn client_addr(&self) -> &SocketAddr {\n        &self.local_addr\n    }\n\n    pub async fn run(&self) {\n        let svr_cfg = self.svr_config.clone();\n        tokio::spawn(run_server(svr_cfg));\n\n        let client_cfg = self.cli_config.clone();\n        tokio::spawn(run_local(client_cfg));\n\n        time::sleep(Duration::from_secs(1)).await;\n    }\n}\n\n#[tokio::test]\nasync fn socks4_relay_connect() {\n    let _ = env_logger::try_init();\n\n    const SERVER_ADDR: &str = \"127.0.0.1:7100\";\n    const LOCAL_ADDR: &str = \"127.0.0.1:7200\";\n\n    const PASSWORD: &str = \"test-password\";\n    const METHOD: CipherKind = CipherKind::AES_128_GCM;\n\n    let svr = Socks4TestServer::new(SERVER_ADDR, LOCAL_ADDR, PASSWORD, METHOD);\n    svr.run().await;\n\n    const HTTP_REQUEST: &[u8] = b\"GET /success.txt HTTP/1.0\\r\\nHost: detectportal.firefox.com\\r\\nAccept: */*\\r\\n\\r\\n\";\n\n    let mut c = Socks4TcpClient::connect((\"detectportal.firefox.com\", 80), LOCAL_ADDR, Vec::new())\n        .await\n        .unwrap();\n\n    c.write_all(HTTP_REQUEST).await.unwrap();\n    c.flush().await.unwrap();\n\n    let mut r = BufReader::new(c);\n\n    let mut buf = Vec::new();\n    r.read_until(b'\\n', &mut buf).await.unwrap();\n\n    let http_status = b\"HTTP/1.0 200 OK\\r\\n\";\n    assert!(buf.starts_with(http_status));\n}\n"
  },
  {
    "path": "tests/socks5.rs",
    "content": "#![cfg(all(feature = \"local\", feature = \"server\"))]\n\nuse std::{\n    net::{SocketAddr, ToSocketAddrs},\n    str,\n};\n\nuse tokio::{\n    io::{AsyncBufReadExt, AsyncWriteExt, BufReader},\n    time::{self, Duration},\n};\n\nuse shadowsocks_service::{\n    config::{Config, ConfigType, LocalConfig, LocalInstanceConfig, ProtocolType, ServerInstanceConfig},\n    local::socks::client::socks5::Socks5TcpClient,\n    run_local, run_server,\n    shadowsocks::{\n        config::{Mode, ServerAddr, ServerConfig},\n        crypto::CipherKind,\n        relay::socks5::Address,\n    },\n};\n\npub struct Socks5TestServer {\n    local_addr: SocketAddr,\n    svr_config: Config,\n    cli_config: Config,\n}\n\nimpl Socks5TestServer {\n    pub fn new<S, L>(svr_addr: S, local_addr: L, pwd: &str, method: CipherKind, enable_udp: bool) -> Self\n    where\n        S: ToSocketAddrs,\n        L: ToSocketAddrs,\n    {\n        let svr_addr = svr_addr.to_socket_addrs().unwrap().next().unwrap();\n        let local_addr = local_addr.to_socket_addrs().unwrap().next().unwrap();\n\n        Self {\n            local_addr,\n            svr_config: {\n                let mut cfg = Config::new(ConfigType::Server);\n                cfg.server = vec![ServerInstanceConfig::with_server_config(\n                    ServerConfig::new(svr_addr, pwd.to_owned(), method).unwrap(),\n                )];\n                cfg.server[0]\n                    .config\n                    .set_mode(if enable_udp { Mode::TcpAndUdp } else { Mode::TcpOnly });\n                cfg\n            },\n            cli_config: {\n                let mut cfg = Config::new(ConfigType::Local);\n                cfg.local = vec![LocalInstanceConfig::with_local_config(LocalConfig::new_with_addr(\n                    ServerAddr::from(local_addr),\n                    ProtocolType::Socks,\n                ))];\n                cfg.local[0].config.mode = if enable_udp { Mode::TcpAndUdp } else { Mode::TcpOnly };\n                cfg.server = vec![ServerInstanceConfig::with_server_config(\n                    ServerConfig::new(svr_addr, pwd.to_owned(), method).unwrap(),\n                )];\n                cfg\n            },\n        }\n    }\n\n    pub fn client_addr(&self) -> &SocketAddr {\n        &self.local_addr\n    }\n\n    pub async fn run(&self) {\n        let svr_cfg = self.svr_config.clone();\n        tokio::spawn(run_server(svr_cfg));\n\n        let client_cfg = self.cli_config.clone();\n        tokio::spawn(run_local(client_cfg));\n\n        time::sleep(Duration::from_secs(1)).await;\n    }\n}\n\n#[cfg(feature = \"stream-cipher\")]\n#[tokio::test]\nasync fn socks5_relay_stream() {\n    let _ = env_logger::try_init();\n\n    const SERVER_ADDR: &str = \"127.0.0.1:8100\";\n    const LOCAL_ADDR: &str = \"127.0.0.1:8200\";\n\n    const PASSWORD: &str = \"test-password\";\n    const METHOD: CipherKind = CipherKind::AES_128_CFB128;\n\n    let svr = Socks5TestServer::new(SERVER_ADDR, LOCAL_ADDR, PASSWORD, METHOD, false);\n    svr.run().await;\n\n    let mut c = Socks5TcpClient::connect(\n        Address::DomainNameAddress(\"www.example.com\".to_owned(), 80),\n        svr.client_addr(),\n    )\n    .await\n    .unwrap();\n\n    let req = b\"GET / HTTP/1.1\\r\\nHost: www.example.com\\r\\nAccept: */*\\r\\nConnection: close\\r\\n\\r\\n\";\n    c.write_all(req).await.unwrap();\n    c.flush().await.unwrap();\n\n    let mut r = BufReader::new(c);\n\n    let mut buf = Vec::new();\n    r.read_until(b'\\n', &mut buf).await.unwrap();\n\n    let http_status = b\"HTTP/1.1 200 OK\\r\\n\";\n    assert!(buf.starts_with(http_status), \"buf: {:?}\", str::from_utf8(&buf));\n}\n\n#[tokio::test]\nasync fn socks5_relay_aead() {\n    let _ = env_logger::try_init();\n\n    const SERVER_ADDR: &str = \"127.0.0.1:8110\";\n    const LOCAL_ADDR: &str = \"127.0.0.1:8210\";\n\n    const PASSWORD: &str = \"test-password\";\n    const METHOD: CipherKind = CipherKind::AES_256_GCM;\n\n    let svr = Socks5TestServer::new(SERVER_ADDR, LOCAL_ADDR, PASSWORD, METHOD, false);\n    svr.run().await;\n\n    let mut c = Socks5TcpClient::connect(\n        Address::DomainNameAddress(\"detectportal.firefox.com\".to_owned(), 80),\n        svr.client_addr(),\n    )\n    .await\n    .unwrap();\n\n    let req = b\"GET /success.txt HTTP/1.0\\r\\nHost: detectportal.firefox.com\\r\\nAccept: */*\\r\\n\\r\\n\";\n    c.write_all(req).await.unwrap();\n    c.flush().await.unwrap();\n\n    let mut r = BufReader::new(c);\n\n    let mut buf = Vec::new();\n    r.read_until(b'\\n', &mut buf).await.unwrap();\n\n    let http_status = b\"HTTP/1.0 200 OK\\r\\n\";\n    assert!(buf.starts_with(http_status));\n}\n"
  },
  {
    "path": "tests/tunnel.rs",
    "content": "#![cfg(all(feature = \"local-tunnel\", feature = \"server\"))]\n\nuse byte_string::ByteStr;\nuse log::debug;\nuse tokio::{\n    self,\n    io::{AsyncBufReadExt, AsyncWriteExt, BufReader},\n    net::{TcpStream, UdpSocket},\n    time::{self, Duration},\n};\n\nuse shadowsocks_service::{\n    config::{Config, ConfigType},\n    run_local, run_server,\n};\n\nfn random_local_tcp_port_pair() -> (u16, u16) {\n    let listener1 = std::net::TcpListener::bind(\"127.0.0.1:0\").unwrap();\n    let port1 = listener1.local_addr().unwrap().port();\n\n    let listener2 = std::net::TcpListener::bind(\"127.0.0.1:0\").unwrap();\n    let port2 = listener2.local_addr().unwrap().port();\n\n    (port1, port2)\n}\n\n#[tokio::test]\nasync fn tcp_tunnel() {\n    let _ = env_logger::try_init();\n\n    let (local_port, server_port) = random_local_tcp_port_pair();\n    let local_config = Config::load_from_str(\n        &format!(\n            r#\"{{\n            \"locals\": [\n                {{\n                    \"local_port\": {local_port},\n                    \"local_address\": \"127.0.0.1\",\n                    \"protocol\": \"tunnel\",\n                    \"forward_address\": \"detectportal.firefox.com\",\n                    \"forward_port\": 80\n                }}\n            ],\n            \"server\": \"127.0.0.1\",\n            \"server_port\": {server_port},\n            \"password\": \"password\",\n            \"method\": \"aes-256-gcm\"\n        }}\"#\n        ),\n        ConfigType::Local,\n    )\n    .unwrap();\n\n    let server_config = Config::load_from_str(\n        &format!(\n            r#\"{{\n            \"server\": \"127.0.0.1\",\n            \"server_port\": {server_port},\n            \"password\": \"password\",\n            \"method\": \"aes-256-gcm\"\n        }}\"#\n        ),\n        ConfigType::Server,\n    )\n    .unwrap();\n\n    tokio::spawn(run_local(local_config));\n    tokio::spawn(run_server(server_config));\n\n    time::sleep(Duration::from_secs(5)).await;\n\n    // Connect it directly, because it is now established a TCP tunnel with detectportal.firefox.com\n    let mut stream = TcpStream::connect((\"127.0.0.1\", local_port)).await.unwrap();\n\n    let req = b\"GET /success.txt HTTP/1.0\\r\\nHost: detectportal.firefox.com\\r\\nAccept: */*\\r\\n\\r\\n\";\n    stream.write_all(req).await.unwrap();\n    stream.flush().await.unwrap();\n\n    let mut r = BufReader::new(stream);\n\n    let mut buf = Vec::new();\n    r.read_until(b'\\n', &mut buf).await.unwrap();\n\n    let http_status = b\"HTTP/1.0 200 OK\\r\\n\";\n    assert!(buf.starts_with(http_status));\n}\n\n#[tokio::test]\nasync fn udp_tunnel() {\n    let _ = env_logger::try_init();\n\n    let socket = UdpSocket::bind(\"127.0.0.1:0\").await.unwrap();\n    let socket_local_addr = socket.local_addr().unwrap();\n    let echo_server_port = socket_local_addr.port();\n\n    // A UDP echo server\n    tokio::spawn(async move {\n        debug!(\"UDP echo server listening on {socket_local_addr}\");\n\n        let mut buffer = [0u8; 65536];\n        loop {\n            let (n, peer_addr) = socket.recv_from(&mut buffer).await.unwrap();\n            debug!(\"UDP echo server received {} bytes from {}, echoing\", n, peer_addr);\n            socket.send_to(&buffer[..n], peer_addr).await.unwrap();\n        }\n    });\n\n    time::sleep(Duration::from_secs(1)).await;\n\n    let (local_port, server_port) = random_local_tcp_port_pair();\n    let local_config = Config::load_from_str(\n        &format!(\n            r#\"{{\n            \"locals\": [\n                {{\n                    \"local_port\": {local_port},\n                    \"local_address\": \"127.0.0.1\",\n                    \"protocol\": \"tunnel\",\n                    \"forward_address\": \"127.0.0.1\",\n                    \"forward_port\": {echo_server_port}\n                }}\n            ],\n            \"server\": \"127.0.0.1\",\n            \"server_port\": {server_port},\n            \"password\": \"password\",\n            \"method\": \"aes-256-gcm\",\n            \"mode\": \"tcp_and_udp\"\n        }}\"#\n        ),\n        ConfigType::Local,\n    )\n    .unwrap();\n\n    let server_config = Config::load_from_str(\n        &format!(\n            r#\"{{\n            \"server\": \"127.0.0.1\",\n            \"server_port\": {server_port},\n            \"password\": \"password\",\n            \"method\": \"aes-256-gcm\",\n            \"mode\": \"udp_only\"\n        }}\"#\n        ),\n        ConfigType::Server,\n    )\n    .unwrap();\n\n    tokio::spawn(run_local(local_config));\n    tokio::spawn(run_server(server_config));\n\n    time::sleep(Duration::from_secs(5)).await;\n\n    const MESSAGE: &[u8] = b\"hello shadowsocks\";\n\n    let socket = UdpSocket::bind(\"0.0.0.0:0\").await.unwrap();\n    socket.send_to(MESSAGE, (\"127.0.0.1\", local_port)).await.unwrap();\n\n    let mut buf = vec![0u8; 65536];\n    let n = socket.recv(&mut buf).await.unwrap();\n\n    let recv_payload = &buf[..n];\n    println!(\"Got reply from server: {:?}\", ByteStr::new(recv_payload));\n\n    assert_eq!(MESSAGE, recv_payload);\n}\n"
  },
  {
    "path": "tests/udp.rs",
    "content": "#![cfg(all(feature = \"local\", feature = \"server\"))]\n\nuse std::net::SocketAddr;\n\nuse log::debug;\nuse tokio::time::{self, Duration};\n\nuse shadowsocks_service::{\n    config::{Config, ConfigType, LocalConfig, LocalInstanceConfig, ProtocolType, ServerInstanceConfig},\n    local::socks::client::socks5::Socks5UdpClient,\n    run_local, run_server,\n    shadowsocks::{ServerConfig, config::Mode, crypto::CipherKind, relay::socks5::Address},\n};\n\nconst SERVER_ADDR: &str = \"127.0.0.1:8093\";\nconst LOCAL_ADDR: &str = \"127.0.0.1:8291\";\n\nconst UDP_ECHO_SERVER_ADDR: &str = \"127.0.0.1:50403\";\n\nconst PASSWORD: &str = \"test-password\";\nconst METHOD: CipherKind = CipherKind::AES_128_GCM;\n\nfn get_svr_config() -> Config {\n    let mut cfg = Config::new(ConfigType::Server);\n    cfg.server = vec![ServerInstanceConfig::with_server_config(\n        ServerConfig::new(SERVER_ADDR.parse::<SocketAddr>().unwrap(), PASSWORD.to_owned(), METHOD).unwrap(),\n    )];\n    cfg.server[0].config.set_mode(Mode::TcpAndUdp);\n    cfg\n}\n\nfn get_cli_config() -> Config {\n    let mut cfg = Config::new(ConfigType::Local);\n    cfg.local = vec![LocalInstanceConfig::with_local_config(LocalConfig::new_with_addr(\n        LOCAL_ADDR.parse().unwrap(),\n        ProtocolType::Socks,\n    ))];\n    cfg.local[0].config.mode = Mode::TcpAndUdp;\n    cfg.server = vec![ServerInstanceConfig::with_server_config(\n        ServerConfig::new(SERVER_ADDR.parse::<SocketAddr>().unwrap(), PASSWORD.to_owned(), METHOD).unwrap(),\n    )];\n    cfg\n}\n\nfn get_client_addr() -> SocketAddr {\n    LOCAL_ADDR.parse().unwrap()\n}\n\nfn start_server() {\n    tokio::spawn(run_server(get_svr_config()));\n}\n\nfn start_local() {\n    tokio::spawn(run_local(get_cli_config()));\n}\n\nfn start_udp_echo_server() {\n    use tokio::net::UdpSocket;\n\n    tokio::spawn(async {\n        let l = UdpSocket::bind(UDP_ECHO_SERVER_ADDR).await.unwrap();\n\n        debug!(\"UDP echo server started {}\", UDP_ECHO_SERVER_ADDR);\n\n        let mut buf = vec![0u8; 65536];\n        let (amt, src) = l.recv_from(&mut buf).await.unwrap();\n\n        debug!(\"UDP echo received {} bytes from {}\", amt, src);\n\n        l.send_to(&buf[..amt], &src).await.unwrap();\n\n        debug!(\"UDP echo sent {} bytes to {}\", amt, src);\n    });\n}\n\n#[tokio::test]\nasync fn udp_relay() {\n    let _ = env_logger::try_init();\n\n    let remote_addr = Address::SocketAddress(UDP_ECHO_SERVER_ADDR.parse().unwrap());\n\n    start_server();\n    start_local();\n\n    start_udp_echo_server();\n\n    // Wait until all server starts\n    time::sleep(Duration::from_secs(1)).await;\n\n    let mut l = Socks5UdpClient::bind(\"127.0.0.1:0\".parse::<SocketAddr>().unwrap())\n        .await\n        .unwrap();\n    l.associate(&get_client_addr()).await.unwrap();\n\n    let payload = b\"HEllo WORld\";\n    l.send_to(0, payload, &remote_addr).await.unwrap();\n\n    let mut buf = vec![0u8; 65536];\n    let (amt, _, recv_addr) = time::timeout(Duration::from_secs(5), l.recv_from(&mut buf))\n        .await\n        .unwrap()\n        .unwrap();\n    println!(\"Received {} buf size={} {:?}\", recv_addr, amt, &buf[..amt]);\n\n    assert_eq!(recv_addr, remote_addr);\n    assert_eq!(&buf[..amt], payload);\n}\n"
  }
]