Full Code of genmeta/gm-quic for AI

main 5e8392136608 cached
300 files
2.0 MB
548.7k tokens
4373 symbols
1 requests
Download .txt
Showing preview only (2,212K chars total). Download the full file or copy to clipboard to get everything.
Repository: genmeta/gm-quic
Branch: main
Commit: 5e8392136608
Files: 300
Total size: 2.0 MB

Directory structure:
gitextract_c16ycxax/

├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── feature_request.md
│   │   └── r2cn.md
│   ├── dependabot.yml
│   └── workflows/
│       ├── benchmark.yml
│       ├── codecov.yml
│       ├── commitlint.yml
│       ├── feishu-bot.yml
│       ├── rust.yml
│       └── traversal.yml
├── .gitignore
├── .pre-commit-config.yaml
├── .rustfmt.toml
├── .rusty-hook.toml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Cargo.toml
├── LICENSE
├── README.md
├── README_CN.md
├── SECURITY.md
├── benchmark/
│   └── launch.py
├── codecov.yml
├── commitlint.config.js
├── dquic/
│   ├── Cargo.toml
│   ├── examples/
│   │   ├── echo-client.rs
│   │   ├── echo-server.rs
│   │   ├── http-client.rs
│   │   ├── http-server.rs
│   │   ├── traversal-client.rs
│   │   └── traversal-server.rs
│   ├── src/
│   │   ├── cert.rs
│   │   ├── client.rs
│   │   ├── common.rs
│   │   ├── lib.rs
│   │   └── server.rs
│   └── tests/
│       ├── auth.rs
│       ├── common/
│       │   └── mod.rs
│       ├── echo.rs
│       ├── echo_common/
│       │   └── mod.rs
│       └── traversal.rs
├── h3-shim/
│   ├── Cargo.toml
│   ├── examples/
│   │   ├── README.md
│   │   ├── h3-client.rs
│   │   └── h3-server.rs
│   └── src/
│       ├── conn.rs
│       ├── error.rs
│       ├── ext.rs
│       ├── lib.rs
│       ├── pool.rs
│       └── streams.rs
├── interop/
│   ├── Dockerfile
│   └── run_endpoint.sh
├── qbase/
│   ├── Cargo.toml
│   └── src/
│       ├── cid/
│       │   ├── connection_id.rs
│       │   ├── local_cid.rs
│       │   └── remote_cid.rs
│       ├── cid.rs
│       ├── error.rs
│       ├── flow.rs
│       ├── frame/
│       │   ├── ack.rs
│       │   ├── add_address.rs
│       │   ├── connection_close.rs
│       │   ├── crypto.rs
│       │   ├── data_blocked.rs
│       │   ├── datagram.rs
│       │   ├── error.rs
│       │   ├── handshake_done.rs
│       │   ├── io.rs
│       │   ├── max_data.rs
│       │   ├── max_stream_data.rs
│       │   ├── max_streams.rs
│       │   ├── new_connection_id.rs
│       │   ├── new_token.rs
│       │   ├── padding.rs
│       │   ├── path_challenge.rs
│       │   ├── path_response.rs
│       │   ├── ping.rs
│       │   ├── punch_done.rs
│       │   ├── punch_hello.rs
│       │   ├── punch_me_now.rs
│       │   ├── remove_address.rs
│       │   ├── reset_stream.rs
│       │   ├── retire_connection_id.rs
│       │   ├── stop_sending.rs
│       │   ├── stream.rs
│       │   ├── stream_data_blocked.rs
│       │   └── streams_blocked.rs
│       ├── frame.rs
│       ├── handshake.rs
│       ├── lib.rs
│       ├── metric.rs
│       ├── net/
│       │   ├── addr.rs
│       │   ├── nat.rs
│       │   ├── route.rs
│       │   └── tx.rs
│       ├── net.rs
│       ├── packet/
│       │   ├── decrypt.rs
│       │   ├── encrypt.rs
│       │   ├── error.rs
│       │   ├── header/
│       │   │   ├── long.rs
│       │   │   └── short.rs
│       │   ├── header.rs
│       │   ├── io.rs
│       │   ├── keys.rs
│       │   ├── number.rs
│       │   ├── signal.rs
│       │   ├── type/
│       │   │   ├── long/
│       │   │   │   └── v1.rs
│       │   │   ├── long.rs
│       │   │   └── short.rs
│       │   └── type.rs
│       ├── packet.rs
│       ├── param/
│       │   ├── core.rs
│       │   ├── error.rs
│       │   ├── handy.rs
│       │   ├── io.rs
│       │   └── preferred_address.rs
│       ├── param.rs
│       ├── role.rs
│       ├── sid/
│       │   ├── handy.rs
│       │   ├── local_sid.rs
│       │   └── remote_sid.rs
│       ├── sid.rs
│       ├── time.rs
│       ├── token.rs
│       ├── util/
│       │   ├── async_deque.rs
│       │   ├── bound_queue.rs
│       │   ├── data.rs
│       │   ├── index_deque.rs
│       │   ├── unique_id.rs
│       │   └── wakers.rs
│       ├── util.rs
│       └── varint.rs
├── qcongestion/
│   ├── Cargo.toml
│   └── src/
│       ├── algorithm/
│       │   ├── bbr/
│       │   │   ├── delivery_rate.rs
│       │   │   ├── min_max.rs
│       │   │   ├── model.rs
│       │   │   ├── parameters.rs
│       │   │   └── state.rs
│       │   ├── bbr.rs
│       │   └── new_reno.rs
│       ├── algorithm.rs
│       ├── congestion.rs
│       ├── lib.rs
│       ├── pacing.rs
│       ├── packets.rs
│       ├── rtt.rs
│       └── status.rs
├── qconnection/
│   ├── Cargo.toml
│   └── src/
│       ├── builder.rs
│       ├── events.rs
│       ├── handshake.rs
│       ├── lib.rs
│       ├── path/
│       │   ├── aa.rs
│       │   ├── burst.rs
│       │   ├── drive.rs
│       │   ├── error.rs
│       │   ├── paths.rs
│       │   ├── util.rs
│       │   └── validate.rs
│       ├── path.rs
│       ├── space/
│       │   ├── data.rs
│       │   ├── handshake.rs
│       │   └── initial.rs
│       ├── space.rs
│       ├── state.rs
│       ├── termination.rs
│       ├── tls/
│       │   ├── agent.rs
│       │   └── client_auth.rs
│       ├── tls.rs
│       ├── traversal.rs
│       └── tx.rs
├── qdatagram/
│   ├── Cargo.toml
│   └── src/
│       ├── lib.rs
│       ├── reader.rs
│       └── writer.rs
├── qevent/
│   ├── Cargo.toml
│   └── src/
│       ├── legacy/
│       │   ├── exporter.rs
│       │   └── quic.rs
│       ├── legacy.rs
│       ├── lib.rs
│       ├── loglevel.rs
│       ├── macro_support.rs
│       ├── macros.rs
│       ├── packet.rs
│       ├── quic/
│       │   ├── connectivity.rs
│       │   ├── recovery.rs
│       │   ├── security.rs
│       │   └── transport.rs
│       ├── quic.rs
│       ├── telemetry/
│       │   ├── filter.rs
│       │   ├── handy.rs
│       │   ├── macro_support.rs
│       │   └── macros.rs
│       └── telemetry.rs
├── qinterface/
│   ├── Cargo.toml
│   ├── examples/
│   │   └── interface-monitor.rs
│   ├── src/
│   │   ├── bind_uri.rs
│   │   ├── component/
│   │   │   ├── alive.rs
│   │   │   ├── location.rs
│   │   │   ├── route/
│   │   │   │   ├── handler.rs
│   │   │   │   ├── packet.rs
│   │   │   │   └── queue.rs
│   │   │   └── route.rs
│   │   ├── component.rs
│   │   ├── device.rs
│   │   ├── iface.rs
│   │   ├── io/
│   │   │   ├── factory.rs
│   │   │   └── handy.rs
│   │   ├── io.rs
│   │   ├── lib.rs
│   │   └── manager.rs
│   └── tests/
│       ├── auto_rebind.rs
│       ├── common/
│       │   └── mod.rs
│       ├── components.rs
│       ├── lifecycle.rs
│       ├── locations.rs
│       └── rebind.rs
├── qmacro/
│   ├── Cargo.toml
│   └── src/
│       ├── derive.rs
│       └── lib.rs
├── qprotocol/
│   ├── Cargo.toml
│   └── src/
│       ├── dns.rs
│       ├── forward.rs
│       ├── io.rs
│       ├── lib.rs
│       ├── quic.rs
│       ├── stun/
│       │   └── msg.rs
│       └── stun.rs
├── qrecovery/
│   ├── Cargo.toml
│   └── src/
│       ├── crypto.rs
│       ├── journal/
│       │   ├── rcvd.rs
│       │   └── sent.rs
│       ├── journal.rs
│       ├── lib.rs
│       ├── recv/
│       │   ├── incoming.rs
│       │   ├── rcvbuf.rs
│       │   ├── reader.rs
│       │   └── recver.rs
│       ├── recv.rs
│       ├── reliable.rs
│       ├── send/
│       │   ├── outgoing.rs
│       │   ├── sender.rs
│       │   ├── sndbuf.rs
│       │   └── writer.rs
│       ├── send.rs
│       ├── streams/
│       │   ├── error.rs
│       │   ├── io.rs
│       │   ├── listener.rs
│       │   └── raw.rs
│       └── streams.rs
├── qresolve/
│   ├── Cargo.toml
│   └── src/
│       └── lib.rs
├── qtraversal/
│   ├── Cargo.toml
│   ├── README.md
│   ├── examples/
│   │   ├── stun_client.rs
│   │   └── stun_server.rs
│   ├── src/
│   │   ├── addr.rs
│   │   ├── future.rs
│   │   ├── lib.rs
│   │   ├── nat/
│   │   │   ├── client.rs
│   │   │   ├── iface.rs
│   │   │   ├── msg.rs
│   │   │   ├── router.rs
│   │   │   ├── server.rs
│   │   │   └── tx.rs
│   │   ├── nat.rs
│   │   ├── packet.rs
│   │   ├── punch/
│   │   │   ├── predictor.rs
│   │   │   ├── puncher.rs
│   │   │   ├── scheduler.rs
│   │   │   └── tx.rs
│   │   ├── punch.rs
│   │   └── route.rs
│   ├── tests/
│   │   └── detect.rs
│   └── tools/
│       ├── build_nat.sh
│       ├── clear_nat.sh
│       ├── dockerfile
│       └── run_stun.sh
├── qudp/
│   ├── Cargo.toml
│   ├── examples/
│   │   ├── receive.rs
│   │   └── send.rs
│   └── src/
│       ├── lib.rs
│       ├── unix.rs
│       └── windows.rs
└── tests/
    └── keychain/
        ├── gen_key.sh
        ├── localhost/
        │   ├── ca.cert
        │   ├── ca.key
        │   ├── ca.srl
        │   ├── client.cert
        │   ├── client.key
        │   ├── server.cert
        │   └── server.key
        ├── quic.test.net/
        │   ├── quic-test-net-ECC.crt
        │   ├── quic-test-net-ECC.key
        │   └── quic-test-net.csr
        ├── root/
        │   ├── rootCA-ECC.crt
        │   ├── rootCA-ECC.key
        │   └── rootCA-ECC.srl
        └── start-quic-server.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Desktop (please complete the following information):**
 - OS: [e.g. iOS]
 - Browser [e.g. chrome, safari]
 - Version [e.g. 22]

**Smartphone (please complete the following information):**
 - Device: [e.g. iPhone6]
 - OS: [e.g. iOS8.1]
 - Browser [e.g. stock browser, safari]
 - Version [e.g. 22]

**Additional context**
Add any other context about the problem here.


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.


================================================
FILE: .github/ISSUE_TEMPLATE/r2cn.md
================================================
---
name: r2cn
about: r2cn 任务模板
title: "[r2cn] "
labels: r2cn
assignees: ""
---

[__任务__]

[__任务分值__] 4 分

[__背景描述__]

[__需求描述__]

[__代码标准__]

1. 所有 **PR** 提交必须签署 `Signed-off-by` 和 使用 `GPG` 签名,即提交代码时(使用 `git commit` 命令时)至少使用 `-s -S` 两个参数,参考 [Contributing Guide](https://github.com/genmeta/dquic/blob/main/docs/contributing.md);
2. 所有 **PR** 提交必须通过 `GitHub Actions` 自动化测试,提交 **PR** 后请关注 `GitHub Actions` 结果;
3. 代码注释均需要使用英文;

[__PR 提交地址__] 提交到 [dquic](https://github.com/genmeta/dquic) 仓库的 `main` 分支 `` 目录;

[__开发指导__]

1. 认领任务参考 [r2cn 开源实习计划 - 任务认领与确认](https://r2cn.dev/docs/student/assign);

[__导师及邮箱__] 请申请此题目的同学使用邮件联系导师,或加入到 [R2CN Discord](https://discord.gg/WRp4TKv6rh) 后在 `#p-meta` 频道和导师交流。

1. Peng Zhang <zhangpeng@genmeta.net>

[__备注__]

1. **认领实习任务的同学,必须完成测试任务和注册流程,请参考:** [r2cn 开源实习计划 - 测试任务](https://r2cn.dev/docs/student/pre-task) 和 [r2cn 开源实习计划 - 学生注册与审核](https://r2cn.dev/docs/student/signup)


================================================
FILE: .github/dependabot.yml
================================================
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates

version: 2
updates:
  - package-ecosystem: "cargo" # See documentation for possible values
    directory: "/" # Location of package manifests
    schedule:
      interval: "weekly"



================================================
FILE: .github/workflows/benchmark.yml
================================================
name: Benchmarks

on:
  workflow_dispatch:  # Allows manual triggering
  schedule:
    - cron: '0 2 * * *'  # UTC 2:00 AM = Beijing 10:00 AM

jobs:

  prepare-matrix:
    runs-on: ubuntu-latest
    outputs: 
      runners: ${{ steps.prepare-runners.outputs.runners }}
    steps:
      - uses: actions/checkout@v4
      - id: prepare-runners
        run: |
          runners="$(python3 benchmark/launch.py runners -q)"
          echo "runners=$runners" >> $GITHUB_OUTPUT

  run-benchmarks:
    strategy:
      fail-fast: false
      matrix:
        runner: ${{ fromJson(needs.prepare-matrix.outputs.runners) }}
        target: [ubuntu,macos,]
    runs-on: ${{ matrix.target }}-latest
    needs: prepare-matrix
    steps:
      - uses: actions/checkout@v4
      - name: Install latest rust stable toolchain
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          rustflags: "" # tquic use deprecated function, and this action set rustflags to "-D warnings" by default
      - name: Install go for macos runner
        if: matrix.target=='macos' && matrix.runner=='quic-go'
        run: brew install go
      - name: Run benchmarks
        run: |
          which openssl
          python3 benchmark/launch.py run ${{ matrix.runner }} --no-plot
      - name: Rename benchmark results dir
        run: mv benchmark/output benchmark-output-${{ matrix.target }}-${{ matrix.runner }}
      - name: Upload benchmark results
        uses: actions/upload-artifact@v4
        with:
          path: benchmark-output-${{ matrix.target }}-${{ matrix.runner }}
          name: benchmark-output-${{ matrix.target }}-${{ matrix.runner }}
  
  summary-results:
    runs-on: ubuntu-latest
    needs: [run-benchmarks]
    strategy:
      fail-fast: false
      matrix:
        target: [ubuntu, macos]
    steps:
      - uses: actions/checkout@v4
      - name: Install matplotlib
        run: |
          sudo apt update
          sudo apt install -y python3-matplotlib
      - name: Download outputs
        uses: actions/download-artifact@v4
        with:
          pattern: benchmark-output-${{ matrix.target }}-*
      - name: Summary ${{ matrix.target }}
        run: |
          # Collect all results.json paths and create a space-separated list
          results_files=$(find . -name "results.json" | tr '\n' ' ')
          echo "Results files: $results_files"

          # Pass all results files to the plot command
          python3 benchmark/launch.py plot $results_files

          # Collect logs
          cp -r */logs benchmark/output/
          mv benchmark/output/ benchmark-output-${{ matrix.target }}

      - name: Upload benchmark results
        uses: actions/upload-artifact@v4
        with:
          path: benchmark-output-${{ matrix.target }}
          name: benchmark-output-${{ matrix.target }}



================================================
FILE: .github/workflows/codecov.yml
================================================
name: Coverage

on:
  push:
    branches: ["main"]
  pull_request:
    branches: ['main']

jobs:
  coverage:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - uses: taiki-e/install-action@cargo-llvm-cov
      # Limit test parallelism to 1 thread to avoid resource contention
      - run: cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info -- --test-threads=1
          
      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@v4
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          files: lcov.info
          fail_ci_if_error: true


================================================
FILE: .github/workflows/commitlint.yml
================================================
name: Commitlint

on:
  push:
    branches: ["main"]
  pull_request:
    branches: ["main"]

jobs:
  commitlint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: wagoid/commitlint-github-action@v5


================================================
FILE: .github/workflows/feishu-bot.yml
================================================
name: feishu bot

on:
  branch_protection_rule:
    types: [created, deleted]
  check_run:
    types: [rerequested, completed]
  check_suite:
    types: [completed]
  create:
  delete:
  deployment_status:
  discussion:
    types: [created, edited, answered]
  discussion_comment:
    types: [created, deleted]
  fork:
  gollum:
  issues:
    types: [opened, edited, milestoned, pinned, reopened]
  issue_comment:
    types: [created, deleted]
  label:
    types: [created, deleted]
  merge_group:
    types: [checks_requested]
  milestone:
    types: [opened, deleted]
  page_build:
  project:
    types: [created, deleted, reopened]
  project_card:
    types: [created, deleted]
  project_column:
    types: [created, deleted]
  public:
  pull_request:
    branches: ["main"]
    types: [opened, reopened]
  pull_request_review:
    types: [edited, dismissed, submitted]
  pull_request_review_comment:
    types: [created, edited, deleted]
  pull_request_target:
    types: [assigned, opened, synchronize, reopened]
  push:
    branches: ["main"]
  registry_package:
    types: [published]
  release:
    types: [published]
  status:
  watch:
    types: [started]
  # schedule:
  #   - cron: "30 2 * * *"

jobs:
  send-event:
    name: Webhook
    runs-on: ubuntu-latest
    steps:
      - uses: KaminariOS/feishu-bot-webhook-action@main
        with:
          webhook: ${{ secrets.FEISHU_BOT_WEBHOOK }}
          signkey: ${{ secrets.FEISHU_BOT_SIGNKEY }}


================================================
FILE: .github/workflows/rust.yml
================================================
name: Rust

on:
  push:
    branches: ["main"]
  pull_request:
    branches: ["main"]

env:
  CARGO_TERM_COLOR: always

jobs:
  build:
    strategy:
      matrix:
        target: [ubuntu, macos, windows]
      fail-fast: false
    runs-on: ${{ matrix.target }}-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install latest rust stable toolchain
        uses: actions-rust-lang/setup-rust-toolchain@v1
      - name: Build
        run: cargo build --verbose
      - name: Run tests
        # Limit test parallelism to 1 thread to avoid resource contention
        # GitHub runners have limited cores (ubuntu/windows=2, macos=3)
        run: cargo test --workspace --verbose -- --test-threads=1

  format:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install latest rust nightly toolchain and rustfmt
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          toolchain: nightly
          components: rustfmt
      - name: Run rustfmt
        run: cargo +nightly fmt --all -- --check
  clippy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install latest rust nightly toolchain with clippy
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          toolchain: nightly
          components: clippy
      - name: Run clippy
        run: cargo +nightly clippy --all-targets --all-features -- -Dwarnings
  doc:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install latest rust nightly toolchain
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          toolchain: nightly
      - name: Run doc
        run: RUSTDOCFLAGS="-D warnings" cargo +nightly doc --no-deps

  msrv:
    strategy:
      matrix:
        target: [ubuntu, macos, windows]
      fail-fast: false
    runs-on: ${{ matrix.target }}-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install msrv toolchain
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          toolchain: 1.88.0
      - name: Build with msrv
        run: cargo build --workspace --release


================================================
FILE: .github/workflows/traversal.yml
================================================
name: Traversal

on:
  push:
    branches: ["main", "build/*"]
  pull_request:
    branches: ["main"]
  workflow_dispatch:

env:
  CARGO_TERM_COLOR: always
  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true

jobs:
  nat-detection:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Build Docker image with cache
        uses: docker/build-push-action@v6
        with:
          context: .
          file: qtraversal/tools/dockerfile
          tags: dquic-traversal-test:latest
          load: true
          cache-from: type=gha
          cache-to: type=gha,mode=max

      - name: Create cargo cache volume
        run: docker volume create cargo-cache

      - name: Compile tests and get NAT detection test list
        run: |
          docker run --rm --privileged \
            -v ${{ github.workspace }}:/dquic \
            -v cargo-cache:/usr/local/cargo/registry \
            dquic-traversal-test:latest \
            /bin/bash -c "
              set -e
              cd /dquic
              cargo build --example stun_server --release
              cargo test --package qtraversal test_detect --no-run
              cargo test --package qtraversal test_detect -- --list
            " | grep ": test$" | awk '{print $1}' | sed 's/:$//' > /tmp/nat_tests.txt
          cat /tmp/nat_tests.txt

      - name: Run NAT detection tests serially
        run: |
          mapfile -t NAT_TESTS < /tmp/nat_tests.txt

          for test in "${NAT_TESTS[@]}"; do
            if [ -z "$test" ]; then
              continue
            fi
            echo "========================================"
            echo "Running NAT detection: $test"
            echo "========================================"

            docker run --rm --privileged \
              -v ${{ github.workspace }}:/dquic \
              -v cargo-cache:/usr/local/cargo/registry \
              dquic-traversal-test:latest \
              /bin/bash -c "
                set -e
                cd /dquic
                bash qtraversal/tools/run_stun.sh
                echo 'DEBUG: Running test [$test]'
                ip netns exec nsa cargo test --package qtraversal '$test' -- --nocapture --include-ignored
              "

            echo "Completed: $test"
            echo ""
          done

  punch:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Build Docker image with cache
        uses: docker/build-push-action@v6
        with:
          context: .
          file: qtraversal/tools/dockerfile
          tags: dquic-traversal-test:latest
          load: true
          cache-from: type=gha
          cache-to: type=gha,mode=max

      - name: Create cargo cache volume
        run: docker volume create cargo-cache

      - name: Compile tests and get hole punching test list
        run: |
          docker run --rm --privileged \
            -v ${{ github.workspace }}:/dquic \
            -v cargo-cache:/usr/local/cargo/registry \
            dquic-traversal-test:latest \
            /bin/bash -c "
              set -e
              cd /dquic
              cargo build --example stun_server --release
              cargo test --test traversal --no-run
              cargo test --test traversal -- --list
            " | grep ": test$" | awk '{print $1}' | sed 's/:$//' > /tmp/hp_tests.txt
          cat /tmp/hp_tests.txt

      - name: Run hole punching tests serially
        run: |
          mapfile -t HP_TESTS < /tmp/hp_tests.txt

          for test in "${HP_TESTS[@]}"; do
            if [ -z "$test" ]; then
              continue
            fi
            echo "========================================"
            echo "Running hole punching: $test"
            echo "========================================"

            docker run --rm --privileged \
              -v ${{ github.workspace }}:/dquic \
              -v cargo-cache:/usr/local/cargo/registry \
              dquic-traversal-test:latest \
              /bin/bash -c "
                set -e
                cd /dquic
                bash qtraversal/tools/run_stun.sh
                echo 'DEBUG: Running test [$test]'
                ip netns exec nsa cargo test --test traversal '$test' -- --include-ignored --nocapture
              "

            echo "Completed: $test"
            echo ""
          done


================================================
FILE: .gitignore
================================================
# Generated by Cargo
# will have compiled files and executables
debug/
target/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk

# Exclude benchmark temp files
/benchmark/*
!/benchmark/launch.py

# cago-tarpaulin (coverage tool) generates this
tarpaulin-report.html

# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb
.vscode/*
.idea/
*.log
log
.DS_Store
*.sqlog
.cargo/config.toml

# Local agent instructions
AGENTS.md


================================================
FILE: .pre-commit-config.yaml
================================================
repos:
  - hooks:
      - id: commitizen
        stages:
          - commit-msg
    repo: https://github.com/commitizen-tools/commitizen
    rev: v2.24.0
  - hooks:
      - id: fmt
      #- id: cargo-check
      #- id: clippy
    repo: https://github.com/doublify/pre-commit-rust
    rev: v1.0
  - repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook
    rev: v9.5.0
    hooks:
      - id: commitlint
        stages: [commit-msg]
        additional_dependencies: ["@commitlint/config-conventional"]


================================================
FILE: .rustfmt.toml
================================================
imports_granularity = "Crate"
group_imports = "StdExternalCrate"
style_edition = "2024"


================================================
FILE: .rusty-hook.toml
================================================
[hooks]
#pre-commit = "cargo check && cargo clippy --all-targets --all -- -D warnings"
#pre-push = "cargo check && cargo clippy --all-targets --all -- -D warnings && cargo test -- --test-threads=1"
pre-push = "cargo build"
#post-commit = "echo yay"

[logging]
verbose = true


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.

We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.

## Our Standards

Examples of behavior that contributes to a positive environment for our
community include:

* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
  and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
  overall community

Examples of unacceptable behavior include:

* The use of sexualized language or imagery, and sexual attention or
  advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
  address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Enforcement Responsibilities

Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.

Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.

## Scope

This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
[quic_team@genmeta.net].
All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the
reporter of any incident.

## Enforcement Guidelines

Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:

### 1. Correction

**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.

**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.

### 2. Warning

**Community Impact**: A violation through a single incident or series
of actions.

**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.

### 3. Temporary Ban

**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.

**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.

### 4. Permanent Ban

**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior,  harassment of an
individual, or aggression toward or disparagement of classes of individuals.

**Consequence**: A permanent ban from any sort of public interaction within
the community.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.

Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to dquic

Welcome all feedback and PRs, including bug reports, feature requests, documentation improvements, and code refactoring. However, please note that dquic has extremely strict quality requirements for code and documentation. The quality of code and documentation will undergo rigorous review before being merged. Contributors must understand and patiently address all feedback before merging.

If you are unsure about the reasonableness of a feature or its implementation, please first create an issue in the [issue list](https://github.com/genmeta/dquic/issues) for discussion to ensure that the feature is reasonable and has a good implementation plan.


================================================
FILE: Cargo.toml
================================================
[workspace]
resolver = "2"
members = [
    "qmacro",
    "qbase",
    "qevent",
    "qrecovery",
    "qcongestion",
    "qudp",
    "qinterface",
    "qprotocol",
    "qdatagram",
    "qconnection",
    "dquic",
    "h3-shim",
    "qtraversal",
    "qresolve",
]
default-members = [
    "qmacro",
    "qbase",
    "qevent",
    "qrecovery",
    "qcongestion",
    "qinterface",
    "qprotocol",
    "qconnection",
    "dquic",
    "h3-shim",
    "qtraversal",
]

[workspace.package]
version = "0.5.0"
edition = "2024"
readme = "README.md"
repository = "https://github.com/genmeta/dquic"
license = "Apache-2.0"
keywords = ["async", "quic", "http3"]
categories = ["network-programming", "asynchronous"]
rust-version = "1.88.0"

[workspace.dependencies]
arc-swap = "1"
async-trait = "0.1.88"
bitflags = "2"
bon = "3"
bytes = "1"
cfg-if = "1"
dashmap = "6"
derive_builder = "0.20"
derive_more = "2"
enum_dispatch = "0.3"
futures = "0.3"
getset = "0.1"
netdev = "0.42"
nom = "8"
netwatcher = "0.4"
pin-project-lite = "0.2"
rand = "0.10"
ring = "0.17"
rustls = { version = "0.23", default-features = false, features = ["std"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
serde_with = "3"
smallvec = { version = "1", features = [
    "union",
    "const_generics",
    "const_new",
] }
socket2 = { version = "0.6", features = ["all"] }
snafu = "0.8"
thiserror = "2"
tokio = { version = "1" }
tokio-util = { version = "0.7" }
tracing = "0.1"
x509-parser = "0.18"
url = "2.5.7"

# h3 for h3-shim only , windows-sys, nix and libc for qudp only
# they are not the default members of the workspace
# windows-sys = "?"
# libc = "0.2"
# nix = "?"

# dev-dependencies, for examples
clap = { version = "4", features = ["derive"] }
h3 = "0.0.8"
h3-datagram = "0.0.2"
http = "1"
indicatif = { version = "0.18", features = ["tokio"] }
parking_lot = "0.12"
postcard = { version = "1", features = ["use-std"] }
rustls-native-certs = "0.8"
tracing-subscriber = "0.3"
tracing-appender = "0.2"

# members
qmacro = { path = "./qmacro", version = "0.5.0" }
qbase = { path = "./qbase", version = "0.5.0" }
qevent = { path = "./qevent", version = "0.5.0" }
qudp = { path = "./qudp", version = "0.5.0" }
qinterface = { path = "./qinterface", version = "0.5.0" }
qdatagram = { path = "./qdatagram", version = "0.5.0" }
qresolve = { path = "./qresolve", version = "0.5.0" }
qrecovery = { path = "./qrecovery", version = "0.5.0" }
qtraversal = { path = "./qtraversal", version = "0.5.0" }
qcongestion = { path = "./qcongestion", version = "0.5.0" }
qconnection = { path = "./qconnection", version = "0.5.0" }
dquic = { path = "./dquic", version = "0.5.0" }
h3-shim = { path = "./h3-shim", version = "0.5.0" }


[profile.bench]
debug = true

[profile.release]
debug = true


================================================
FILE: LICENSE
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

================================================
FILE: README.md
================================================
# dquic

[![License: Apache-2.0](https://img.shields.io/github/license/genmeta/dquic)](https://www.apache.org/licenses/LICENSE-2.0)
[![Build Status](https://img.shields.io/github/actions/workflow/status/genmeta/dquic/rust.yml)](https://github.com/genmeta/dquic/actions/workflows/rust.yml)
[![codecov](https://codecov.io/gh/genmeta/dquic/graph/badge.svg)](https://codecov.io/gh/genmeta/dquic)
[![crates.io](https://img.shields.io/crates/v/dquic.svg)](https://crates.io/crates/dquic)
[![Documentation](https://docs.rs/dquic/badge.svg)](https://docs.rs/dquic/)
[![Dependencies](https://img.shields.io/deps-rs/repo/github/genmeta/dquic)](https://github.com/genmeta/dquic/network/dependencies)
![MSRV](https://img.shields.io/crates/msrv/dquic)

English | [中文](README_CN.md)

The QUIC protocol is an important infrastructure for the next generation Internet, and `dquic` is a native asynchronous Rust implementation of the QUIC protocol, an efficient and scalable [RFC 9000][1] implementation with excellent engineering quality.
`dquic` not only implements the standard QUIC protocol but also includes additional extensions such as [RFC 9221 (Unreliable Datagram Extension)][3] and [qlog (QUIC event logging)][2].

As widely recognized, QUIC possesses numerous advanced features and unparalleled security, making it highly suitable for applications in:

**High-performance data transmission:**

- Achieves 0-RTT connection establishment to minimize latency.
- Utilizes multiplexed streams to eliminate head-of-line blocking and improve throughput.
- Multi-path transmission to improve transmission capacity.
- Efficient transmission control algorithms such as BBR ensure low latency and high bandwidth utilization.

**Data privacy and security:**

- Integrates TLS 1.3 encryption by default for end-to-end security.
- Implements forward-secure keys and authenticated packet headers to resist tampering.

**IoT and edge computing:**

- Supports connection migration to maintain sessions across network changes (e.g., Wi-Fi to cellular).
- Enables lightweight communication with unreliable datagrams (RFC 9221) for real-time IoT scenarios.

These characteristics position QUIC as a transformative protocol for modern networks, combining performance optimizations with robust cryptographic guarantees.

## Design

The QUIC protocol is a rather complex, IO-intensive protocol, making it extremely fit for asynchronous programming.
The basic events in asynchronous IO are read, write, and timers. However, throughout the implementation of the QUIC protocol, the internal events are intricate and dazzling.
If you look at the protocol carefully, you will found that certain structures become evident, revealing that the core of the QUIC protocol is driven by layers of underlying IO events progressively influencing the application layer behavior.
For example, when the receiving data of a stream is contiguous, it constitutes an event that awakens the corresponding application layer to read;
similarly, when the Initial data exchange completes and the Handshake keys are obtained, this is another event that awakens the task processing the Handshake data packet.
These events illustrate the classic Reactor pattern.
`dquic` refines and encapsulates these various internal Reactors of QUIC, making each module more independent, clarifying the cooperation between the system's modules, and thereby making the overall design more user-friendly.

It is noticeable that the QUIC protocol has multiple layers. In the transport layer, there are many functions such as opening new connections, receiving, sending, reading, writing, and accepting new connections, most of which are asynchronous.
Here, we call these functions as various functors with each layer having its own functor.
With these layers in place, it becomes clear that the `Accept Functor` and the `Read Functor`, or the `Write Functor`, do not belong to the same layer, which is quite interesting.

![image](https://github.com/genmeta/dquic/blob/main/images/arch.png?raw=true)

## Overview

- **qbase**: Core structure of the QUIC protocol, including variable integer encoding (VarInt), connection ID management, stream ID, various frame and packet type definitions, and asynchronous keys.
- **qrecovery**: The reliable transport part of QUIC, encompassing the state machine evolution of the sender/receiver, and the internal logic interaction between the application layer and the transport layer.
- **qcongestion**: Congestion control in QUIC, which abstracts a unified congestion control interface and implements BBRv1. In the future, it will also implement more transport control algorithms such as Cubic and others.
- **qinterface**: QUIC's packet routing and definition of the underlying I/O interface (`QuicIO`) enable dquic to run in various environments. Contains an optional qudp-based `QuicIO` implementation
- **qdatagram**: The extension for unreliable datagram transmission based on QUIC offers transmission control mechanisms and enhanced security compared to directly sending unreliable datagrams over UDP. See [RFC 9221][3].
- **qconnection**: Encapsulation of QUIC connections, linking the necessary components and tasks within a QUIC connection to ensure smooth operation.
- **dquic**: The top-level encapsulation of the QUIC protocol, including interfaces for both the QUIC client and server.
- **qudp**: High-performance UDP encapsulation for QUIC. Ordinary UDP incurs a system call for each packet sent or received, resulting in poor performance.
- **qevent**: The implementation of [qlog][2] supports logging internal activities of individual QUIC connections in JSON format, maintains compatibility with qlog 3, and enables visualization analysis through [qvis][4]. However, it is important to note that enabling qlog can significantly impact performance despite its utility in troubleshooting.

![image](https://github.com/genmeta/dquic/blob/main/images/qvis.png?raw=true)

## Usage

#### Demos

Run h3 server:

```shell
cargo run --example h3-server --package h3-shim -- --dir ./h3-shim
```

Send a h3 request:

```shell
cargo run --example h3-client --package h3-shim -- https://localhost:4433/examples/h3-server.rs
```

For more complete examples, please refer to the `examples` folders under the `h3-shim` and `dquic` folders.

#### API

`dquic` provides user-friendly interfaces for creating client and server connections, while also supporting additional features that meet modern network requirements.

In addition to bind an IP address + port, `dquic` can also bind a network interface, dynamically adapting to actual address changes, which provides good mobility for dquic.

The QUIC client not only provides configuration options specified by the QUIC protocol's Parameters and optional 0-RTT functionality, but also includes some additional advanced options. For example, the QUIC client can set its own certificate for server verification, and can also set its own Token manager to manage Tokens issued by various servers for future connections with these servers.

The QUIC client supports multipath handshaking, it can simultaneously connect to server's IPv4 and IPv6 addresses. Even if some paths are unreachable, as long as one path is reachable, the connection can be established.

The following is a simple example, please refer to the documentation for more details.

```rust
use std::path::PathBuf;
use std::sync::Arc;
use dquic::prelude::{handy::ToCertificate, *};

async fn client() -> Result<(), Box<dyn std::error::Error>> {
    // Set up root certificate store
    let mut roots = rustls::RootCertStore::empty();

    // Load system certificates
    roots.add_parsable_certificates(rustls_native_certs::load_native_certs().certs);
    // Load custom certificates (can be used independently of system certificates)
    roots.add_parsable_certificates(PathBuf::from("/path/to/ca.cert").to_certificate());  // Load at runtime
    // roots.add_parsable_certificates(include_bytes!("/path/to/ca.cert").to_certificate()); // Embed at compile time

    // Build the QUIC client
    let quic_client = Arc::new(QuicClient::builder()
        .with_root_certificates(roots)
        .without_cert()                                      // Client certificate verification is typically not required
        // .with_parameters(your_parameters)                 // Custom transport parameters
        // .bind(["iface://v4.eth0:0", "iface://v6.eth0:0"]) // Bind to specific network interfaces
        // .enable_0rtt()                                    // Enable 0-RTT
        // .enable_sslkeylog()                               // Enable SSL key logging
        // .with_qlog(Arc::new(handy::LegacySeqLogger::new(
        //     PathBuf::from("/path/to/qlog_dir"),
        // )))                                               // Enable qlog for visualization with qvis tool
        .build());

    // Connect to the server
    let connection = quic_client.connect("localhost").await?;

    // Start using the QUIC connection!
    // For more usage examples, see dquic/examples and h3-shim/examples

    Ok(())
}
```

The QUIC server is represented as `QuicListeners`, supporting SNI (Server Name Indication), allowing multiple Servers to be started in one process, each with their own certificates and keys. Each server can also bind to multiple addresses, and multiple Servers can bind to the same address. Clients must correctly connect to the corresponding interface of the corresponding Server, otherwise the connection will be rejected.

QuicListeners supports verifying client identity through various methods, including through `client_name` transport parameters, verifying client certificate content, etc. QuicListeners also supports anti-port scanning functionality, only responding after preliminary verification of client identity.

```rust
use std::path::PathBuf;
use dquic::prelude::*;

async fn server() -> Result<(), Box<dyn std::error::Error>> {
    let quic_listeners = QuicListeners::builder()
        .without_client_cert_verifier()         // Client certificate verification is typically not required
        // .with_parameters(your_parameters)    // Custom transport parameters
        // .enable_0rtt()                       // Enable 0-RTT for servers
        // .enable_anti_port_scan()             // Anti-port scanning protection
        .listen(8192)?;                         // Start listening with backlog (similar to Unix listen)

    // Add a server that can be connected
    quic_listeners.add_server(
        "localhost",
        // Certificate and key files as byte arrays or paths
        PathBuf::from("/path/to/server.cert").as_path(),
        PathBuf::from("/path/to/server.key").as_path(),
        [
            "192.168.1.108:4433",   // Bind to the IPv4 address
            "iface://v6.eth0:4433", // Bind to the eth0's IPv6 address
        ],
        None, // ocsp
    ).await?;

    // Continue calling `quic_listeners.add_server()` to add more servers
    // Call `quic_listeners.remove_server()` to remove a server

    // Accept trusted new connections
    while let Ok((connection, server_name, pathway, link)) = quic_listeners.accept().await {
        // Handle the incoming QUIC connection!
        // You can refer to examples in dquic/examples and h3-shim/examples
    }

    Ok(())
}
```

There is an asynchronous interface for creating unidirectional or bidirectional QUIC streams from a QUIC Connection, or for listening to incoming streams from the other side of a QUIC Connection. This interface is almost identical to the one in [`hyperium/h3`](https://github.com/hyperium/h3/blob/master/docs/PROPOSAL.md#5-quic-transport).

For reading and writing data from QUIC streams, the standard **`AsyncRead`** and **`AsyncWrite`** interfaces are implemented for QUIC streams, making them very convenient to use.

## Performance

GitHub Actions periodically runs [benchmark tests][5]. The results show that dquic, quiche, tquic and quinn all deliver excellent performance, with each excelling in different benchmark testing scenarios. It should be noted that transmission performance is also greatly related to congestion control algorithms. dquic's performance will continue to be optimized in the coming period. If you want higher performance, dquic provides abstract interfaces that can use DPDK or XDP to replace UdpSocket!

<img src="https://github.com/genmeta/dquic/blob/main/images/benchmark_15KB.png?raw=true" width=33% height=33%><img src="https://github.com/genmeta/dquic/blob/main/images/benchmark_30KB.png?raw=true" width=33% height=33%><img src="https://github.com/genmeta/dquic/blob/main/images/benchmark_2048KB.png?raw=true" width=33% height=33%>

## Contribution

All feedback and PRs are welcome, including bug reports, feature requests, documentation improvements, code refactoring, and more.

If you are unsure whether a feature or its implementation is reasonable, please first create an issue in the [issue list](https://github.com/genmeta/dquic/issues) for discussion.
This ensures the feature is reasonable and has a solid implementation plan.

## Community

- [Official Community](https://github.com/genmeta/dquic/discussions)
- chat group:[send email](mailto:quic_team@genmeta.net) to introduce your contribution, and we will reply to your email with an invitation link and QR code to join the group.

[1]: https://www.rfc-editor.org/rfc/rfc9000.html
[2]: https://datatracker.ietf.org/doc/draft-ietf-quic-qlog-quic-events/
[3]: https://datatracker.ietf.org/doc/html/rfc9221
[4]: https://qvis.quictools.info/#/files
[5]: https://github.com/genmeta/dquic/actions


================================================
FILE: README_CN.md
================================================
# dquic

[![License: Apache-2.0](https://img.shields.io/github/license/genmeta/dquic)](https://www.apache.org/licenses/LICENSE-2.0)
[![Build Status](https://img.shields.io/github/actions/workflow/status/genmeta/dquic/rust.yml)](https://github.com/genmeta/dquic/actions/workflows/rust.yml)
[![codecov](https://codecov.io/gh/genmeta/dquic/graph/badge.svg)](https://codecov.io/gh/genmeta/dquic)
[![crates.io](https://img.shields.io/crates/v/dquic.svg)](https://crates.io/crates/dquic)
[![Documentation](https://docs.rs/dquic/badge.svg)](https://docs.rs/dquic/)
[![Dependencies](https://img.shields.io/deps-rs/repo/github/genmeta/dquic)](https://github.com/genmeta/dquic/network/dependencies)
![MSRV](https://img.shields.io/crates/msrv/dquic)

[English](README.md) | 中文

QUIC协议是下一代互联网重要的基础设施,而`dquic`则是一个原生异步Rust的QUIC协议实现,一个高效的、可扩展的[RFC 9000][1]实现,同时工程质量优良。
`dquic`不仅实现了标准QUIC协议,还额外实现了[RFC 9221 (Unreliable Datagram Extension)][3]、[qlog (QUIC event logging)][2]等扩展。

众所周知,QUIC拥有许多优良特性,以及极致的安全性,十分适合在高性能传输、数据隐私安全、物联网领域推广使用:

**高性能数据传输:**

- 0-RTT握手,最小化建连时延
- 流的多路复用,消除了头端阻塞,提升吞吐率
- 多路径传输,提升传输能力
- BBR等高效的传输控制算法,保证低时延、高带宽利用率

**数据隐私安全:**

- 默认集成TLS 1.3端到端加密
- 实现前向安全密钥和经过身份验证的数据包头,以抵御篡改。

**IoT和边缘计算:**

- 支持连接迁移,以便在网络变化(例如从Wi-Fi切换到蜂窝网络)时保持会话。
- 实现轻量级通信,支持不可靠数据报(RFC 9221),适用于实时物联网场景。

## 设计原则

QUIC协议可谓一个相当复杂的、IO密集型的协议,因此正是适合异步大显身手的地方。异步IO中最基本的事件有数据可读、可写,以及定时器,但纵观整个QUIC协议实现,内部的事件错综复杂、令人眼花缭乱。然而,仔细探查之下还是能发现一些结构,会发现QUIC协议核心是由一层层底层IO事件逐步向上驱动应用层行为的。比如当一个流接收数据至连续,这也是一个事件,将唤醒对应的应用层来读;再比如,当Initial数据交互完毕获得Handshake密钥之后,这也是一个事件,将唤醒Handshake数据包任务的处理。以上这些事件就是经典的Reactor模式,`dquic`正是对这些QUIC内部形形色色的Reactor的拆分细化和封装,让各个模块更加独立,让整个系统各模块配合的更加清晰,进而整体设计也更加人性化。

注意到QUIC协议内部,还能分出很多层。在传输层,有很多功能比如打开新连接、接收、发送、读取、写入、Accept新连接,它们大都是异步的,在这里称之为各种“算子”,且每层都有自己的算子,有了这些分层之后,就会发现,其实Accept算子和Read算子、Write算子根本不在同一层,很有意思。

![image](https://github.com/genmeta/dquic/blob/main/images/arch.png)

## 概览

- **qbase**: QUIC协议的基础结构,包括可变整型编码VarInt、连接ID管理、流ID、各种帧以及包类型定义、异步密钥等
- **qrecovery**: QUIC的可靠传输部分,包括发送端/接收端的状态机演变、应用层与传输层的内部逻辑交互等
- **qcongestion**: QUIC的拥塞控制,抽象了统一的拥塞控制接口,并实现了BBRv1,未来还会实现Cubic、ETC等更多的传输控制算法
- **qinterface**: QUIC的数据包路由和对底层I/O接口(`QuicIO`)的定义,令dquic可以运行在各种环境。内含一个可选的基于qudp的`QuicIO`实现
- **qconnection**: QUIC连接封装,将QUIC连接内部所需的各组件、任务串联起来,最终能够完美运行
- **dquic**: QUIC协议的顶层封装,包括QUIC客户端和服务端2部分的接口
- **qudp**: QUIC的高性能UDP封装,使用GSO、GRO等手段极致优化UDP的性能
- **qdatagram**: 基于QUIC的不可靠数据报传输的扩展,相比于直接用UDP发送不可靠数据报,该扩展拥有QUIC的传输控制和极致安全性。详情参考[RFC 9221][3]
- **qevent**: [qlog][2]的实现,支持以json形式记录单个quic连接内部活动,兼容qlog 3,支持[qvis][4]可视化分析。请注意,开启qlog虽有助于分析问题,但相当影响性能

![image](https://github.com/genmeta/dquic/blob/main/images/qvis.png?raw=true)

## 使用方式

#### 样例演示

本仓库提供了三组样例:

- `echo-client`和`echo-server`: 位于`dquic/examples/`文件夹下,展示了dquic的基本使用方法。
- `http-client`和`http-server`: 位于`dquic/examples/`文件夹下,展示了在dquic上运行HTTP/0.9协议。
- `h3-client`和`h3-server`: 位于`h3-shim/examples/`文件夹下,展示了在dquic上运行HTTP/3协议。

以H3为例,运行一个H3服务器:

```shell
cargo run --example h3-server --package h3-shim -- --dir ./h3-shim
```

发起一个H3请求:

```shell
cargo run --example h3-client --package h3-shim -- https://localhost:4433/examples/h3-server.rs
```

#### API简介

`dquic`提供了人性化的接口创建客户端和服务端的连接,同时还支持一些符合现代网络需求的附加功能设置。

除了可以绑定到ip地址+端口,`dquic`还支持绑定到网络接口上,以动态地适应实际地址变化,这使得`dquic`拥有了良好的移动性。

QUIC客户端不仅提供了QUIC协议所规定的Parameters选项配置,可选的0RTT功能,还有一些额外的高级选项,比如QUIC客户端可设置自己的证书以供服务端验证,也可设置自己的Token管理器,管理着各服务器颁发的Token,以便未来和这些服务器再次连接时用的上。

QUIC客户端支持多路径握手,即同时尝试连接到服务器的IPv4和IPv6地址,即使某些路径不可达,但只要有一条路径能够联通,连接就可以建立。如果对端的实现同样是dquic,则还支持多路径传输。

以下为简单示例,更多细节请参阅文档。

```rust
use std::path::PathBuf;
use std::sync::Arc;
use dquic::prelude::{handy::ToCertificate, *};

async fn client() -> Result<(), Box<dyn std::error::Error>> {
    // 设置根证书存储
    let mut roots = rustls::RootCertStore::empty();

    // 加载系统证书
    roots.add_parsable_certificates(rustls_native_certs::load_native_certs().certs);

    // 加载自定义证书(可与系统证书独立使用)
    roots.add_parsable_certificates(PathBuf::from("path/to/your/cert.pem").to_certificate()); // 运行时加载
    // roots.add_parsable_certificates(include_bytes!("path/to/your/cert.pem").to_certificate()); // 编译时嵌入

    // 构建QUIC客户端
    let quic_client = Arc::new(QuicClient::builder()
        .with_root_certificates(roots)
        .without_cert()                                      // 通常不需要客户端证书验证
        // .with_parameters(your_parameters)                 // 自定义传输参数
        // .bind(["iface://v4.eth0:0", "iface://v6.eth0:0"]) // 绑定到指定网络接口eth0的IPv4和IPv6地址
        // .enable_0rtt()                                    // 启用0-RTT
        // .enable_sslkeylog()                               // 启用SSL密钥日志
        // .with_qlog(Arc::new(handy::LegacySeqLogger::new(
        //     PathBuf::from("/path/to/qlog_dir"),
        // )))                                               // 启用qlog,可用qvis工具可视化
        .build());

    // 连接到服务器
    let connection = quic_client.connect("localhost").await?;

    // 开始使用QUIC连接!
    // 更多使用示例请参考 dquic/examples 和 h3-shim/examples

    Ok(())
}
```

QUIC服务端表现为`QuicListeners`,支持SNI(Server Name Indication),在一个进程启动多个Server,分别有自己的证书和密钥,每个服务端又可以绑定到多个地址上,支持多个Server绑定同一个地址。Client必须正确连接到对应的Server的对应接口上,否则连接会被自动拒绝。

QuicListeners支持通过多种方法验证客客户端的身份,包括通过`client_name`传输参数,验证客户端证书的内容等。QuicListeners还支持抗端口扫描功能,只有在初步验证客户端的身份后才会做出响应。

```rust
// 创建QUIC监听器(每个程序只能有一个实例)
use std::path::PathBuf;
use dquic::prelude::*;

async fn server() -> Result<(), Box<dyn std::error::Error>> {
    let quic_listeners = QuicListeners::builder()
        .without_client_cert_verifier()         // 通常不需要客户端证书验证
        // .with_parameters(your_parameters)    // 自定义传输参数
        // .enable_0rtt()                       // 为服务器启用0-RTT
        // .enable_anti_port_scan()             // 抗端口扫描保护
        .listen(8192)?;                         // 开始监听,设置积压队列(类似Unix listen)

    // 添加可连接的服务器
    quic_listeners.add_server(
        "localhost",
        // 证书和密钥文件的字节数组或路径
        PathBuf::from("/path/to/server.crt").as_path(),
        PathBuf::from("/path/to/server.key").as_path(),
        [
            "192.168.1.106:4433",   // 绑定到此IPv4地址
            "iface://v6.eth0:4433", // 绑定到eth0的IPv6地址
        ],
        None, // ocsp
    ).await?;

    // 继续调用 `quic_listeners.add_server()` 来添加更Server
    // 调用 `quic_listeners.remove_server()` 来移除一个Serer

    // 接受可信的新连接
    while let Ok((connection, server_name, pathway, link)) = quic_listeners.accept().await {
        // 处理传入的QUIC连接!
        // 可以参考 dquic/examples 和 h3-shim/examples 中的示例
    }

    Ok(())
}
```

关于如何从QUIC Connection中创建单向QUIC流,或者双向QUIC流,抑或是从QUIC Connection监听来自对方的流,都有一套异步的接口,这套接口几乎与[`hyperium/h3`](https://github.com/hyperium/h3/blob/master/docs/PROPOSAL.md#5-quic-transport)的接口相同。

至于如何从QUIC流中读写数据,则为QUIC流实现了标准的 **`AsyncRead`** 、 **`AsyncWrite`** 接口,可以很方便地使用。

## 性能

github action会定期运行[基准测试][5],效果如下。go-quic和quiche、tquic、quinn都具备优良性能,在三种基准测试场景下互有千秋。须知传输性能跟传输控制算法也有很大关系,dquic的性能在未来一段时间还会持续优化,如果想获得更高性能,dquic提供了抽象接口,可使用DPDK或者XDP代替UdpSocket!

<img src="https://github.com/genmeta/dquic/blob/main/images/benchmark_15KB.png?raw=true" width=33% height=33%><img src="https://github.com/genmeta/dquic/blob/main/images/benchmark_30KB.png?raw=true" width=33% height=33%><img src="https://github.com/genmeta/dquic/blob/main/images/benchmark_2048KB.png?raw=true" width=33% height=33%>

## 贡献

欢迎所有反馈和PR,包括bug反馈、功能请求、文档修缮、代码重构等。

如果不确定一个功能或者其实现是否合理,请首先在[issue列表](https://github.com/genmeta/dquic/issues)中创建一个issue,大家一起讨论,以确保功能是合理的,并有一个良好的实现方案。

## 社区交流

- [用户论坛](https://github.com/genmeta/dquic/discussions)
- 聊天群:[发送邮件](mailto:quic_team@genmeta.net)介绍一下您的贡献,我们将邮件回复您加群链接及群二维码。

[1]: https://www.rfc-editor.org/rfc/rfc9000.html
[2]: https://datatracker.ietf.org/doc/draft-ietf-quic-qlog-quic-events/
[3]: https://datatracker.ietf.org/doc/html/rfc9221
[4]: https://qvis.quictools.info/#/files
[5]: https://github.com/genmeta/dquic/actions


================================================
FILE: SECURITY.md
================================================
# Security Policy

## Supported Versions

Use this section to tell people about which versions of your project are
currently being supported with security updates.

| Version | Supported          |
| ------- | ------------------ |
| 0.5.x   | :white_check_mark: |

## Reporting a Vulnerability

Use this section to tell people how to report a vulnerability.

Tell them where to go, how often they can expect to get an update on a
reported vulnerability, what to expect if the vulnerability is accepted or
declined, etc.


================================================
FILE: benchmark/launch.py
================================================
#!/usr/bin/env python3


import os
import subprocess
import re
import json
import logging
import shutil
import argparse


class ServerRunner:
    name: str
    launch_server: list[str]
    listen_port: int

    def __init__(self, impl_name: str, launch_server: list[str], listen_port: int):
        self.name = impl_name
        self.listen_port = listen_port
        self.launch_server = launch_server

    def run(self, log) -> subprocess.Popen:
        # 在后台运行server
        return subprocess.Popen(
            self.launch_server,
            cwd=rand_files.path,
            stdout=log,
            stderr=log,
            env={**os.environ, "RUST_LOG": "off"}
        )


class Result:
    success: int
    duration: float
    qps: float

    def __init__(self, success: int, duration: float):
        self.success, self.duration = success, duration
        self.qps = success / duration if duration > 0 else 0

    def __str__(self):
        return f"success={self.success}, duration={self.duration}, qps={self.qps}"

    def __repr__(self):
        return self.__str__()

    @staticmethod
    def average(results: list['Result']) -> 'Result':
        total_success, total_duration = 0, 0
        total_success = sum(result.success for result in results)
        total_duration = sum(result.duration for result in results)
        return Result(total_success, total_duration)


root = os.path.join(os.path.dirname(__file__))


class RandomFiles:
    path = os.path.join(root, "rand_files")

    def __init__(self):
        if not os.path.exists(self.path):
            os.makedirs(self.path)

    def gen(self, file_size: int) -> str:
        file_name = f"rand_file_{file_size}.bin"
        logging.info(f"Generating {file_name}...")
        file_path = os.path.join(self.path, file_name)
        if not os.path.exists(file_path):
            with open(file_path, "wb") as f:
                f.write(os.urandom(int(file_size) * 1024))
        return file_name


class Certs:
    path = os.path.join(root, "certs")

    root_cert = os.path.join(path, "root_cert.pem")
    root_key = os.path.join(path, "root_key.pem")
    server_cert = os.path.join(path, "server_cert.pem")
    server_key = os.path.join(path, "server_key.pem")
    server_csr = os.path.join(path, "server_csr.pem")
    server_ext = os.path.join(path, "server.ext")
    server_cert_der = os.path.join(path, "server_cert.der")
    server_key_der = os.path.join(path, "server_key.der")

    def __init__(self):
        pass

    def gen(self):
        if not os.path.exists(self.path):
            logging.info("Generating certs...")
            os.makedirs(self.path)

            # CA
            subprocess.run(
                ["openssl", "ecparam", "-name", "prime256v1",
                    "-genkey", "-out", self.root_key], check=True)
            subprocess.run(
                ["openssl", "req", "-new", "-x509", "-key", self.root_key, "-out", self.root_cert,
                 "-days", "3650", "-subj", "/CN=localhost", "-addext", "subjectAltName=DNS:localhost"], check=True)
            # Server

            subprocess.run(
                ["openssl", "ecparam", "-name", "prime256v1", "-genkey", "-out", self.server_key], check=True)
            subprocess.run(
                ["openssl", "req", "-new", "-key", self.server_key, "-out",
                 self.server_csr,  "-subj", "/CN=localhost", "-addext", "subjectAltName=DNS:localhost"], check=True)
            # use server ext to add subjectAltName, openssl binary on macos CI doesnot support `-copy-extensions copy` parameter
            with open(self.server_ext, "w") as f:
                f.write("subjectAltName=DNS:localhost\n")
                f.flush()
            subprocess.run(
                ["openssl", "x509", "-req", "-in", self.server_csr, "-CA", self.root_cert,
                 "-CAkey", self.root_key, "-CAcreateserial", "-out", self.server_cert,
                 "-days", "365", "-extfile", self.server_ext], check=True)
            # Convert pem to der
            subprocess.run(
                ["openssl", "x509", "-in", self.server_cert, "-outform", "der",
                 "-out", self.server_cert_der], check=True)
            subprocess.run(
                ["openssl", "ec", "-in", self.server_key, "-outform", "der",
                 "-out", self.server_key_der], check=True)


rand_files = RandomFiles()
ecc_certs = Certs()

quic_go_dir = os.path.join(root, "go-quic-demo")
dquic_dir = os.path.join(root, "..")
tquic_dir = os.path.join(root, "tquic")
quinn_dir = os.path.join(root, "h3")
quiche_dir = os.path.join(root, "quiche")


def git_clone(owner: str, repo: str, branch: str) -> None:
    if not os.path.exists(os.path.join(root, repo)):
        logging.info(f"Cloning {owner}/{repo}...")
        subprocess.run(
            ["git", "clone", "--recursive", "--branch", branch,
             f"https://github.com/{owner}/{repo}"],
            cwd=root,
        )


def go_quic_runner() -> ServerRunner:
    logging.info("Building quic-go server...")

    git_clone("eareimu", "go-quic-demo", "main")

    # 编译
    subprocess.run(
        ["go", "get", "example/quic-server",],
        cwd=quic_go_dir,
        check=True
    )
    subprocess.run(
        ["go", "build", "-ldflags=-s -w", "-trimpath", "-o", "quic_server"],
        cwd=quic_go_dir,
        check=True
    )

    binary = os.path.join(quic_go_dir, "quic_server")
    launch = [
        binary,
        "-c", ecc_certs.server_cert,
        "-k", ecc_certs.server_key,
        "-a", "[::1]:4430",
    ]

    return ServerRunner('quic-go', launch, 4430)


def dquic_runner() -> ServerRunner:
    logging.info("Building dquic server...")

    # git_clone("genmeta", "dquic", "main")

    # 编译
    subprocess.run(
        ["cargo", "build", "--release", "--package",
            "h3-shim", "--example", "h3-server"],
        cwd=dquic_dir,
        check=True
    )

    launch = [
        os.path.join(dquic_dir,
                     "target", "release", "examples", "h3-server"),
        "-c", ecc_certs.server_cert,
        "-k", ecc_certs.server_key,
        "-b", "4096",  # 设置backlog
        "-l", "[::1]:4431"
    ]

    return ServerRunner('dquic', launch, 4431)


def dquic_multi_path_runner() -> ServerRunner:
    logging.info("Building dquic server...")

    # git_clone("genmeta", "dquic", "main")

    # 编译
    subprocess.run(
        ["cargo", "build", "--release", "--package",
            "h3-shim", "--example", "h3-server"],
        cwd=dquic_dir,
        check=True
    )

    launch = [
        os.path.join(dquic_dir,
                     "target", "release", "examples", "h3-server"),
        "-c", ecc_certs.server_cert,
        "-k", ecc_certs.server_key,
        "-b", "4096",  # 设置backlog
        "-l", "[::1]:4435",
        "-l", "127.0.0.1:4435"
    ]

    return ServerRunner('dquic-multi-path', launch, 4435)


def tquic_runner() -> ServerRunner:
    logging.info("Building tquic server...")

    git_clone("Tencent", "tquic", "v1.6.0")

    subprocess.run(
        ["cargo", "build", "--release", "--package",
            "tquic_tools", "--bin", "tquic_server"],
        cwd=tquic_dir,
        check=True
    )

    launch = [
        os.path.join(tquic_dir, "target", "release", "tquic_server"),
        "-c", ecc_certs.server_cert,
        "-k", ecc_certs.server_key,
        "-l", "[::1]:4432",
        "--log-level", "OFF",
    ]

    return ServerRunner('tquic', launch, 4432)


def quinn_runner() -> ServerRunner:
    logging.info("Building quinn server...")

    git_clone("hyperium", "h3", "h3-quinn-v0.0.9")

    subprocess.run(
        ["cargo", "build", "--release", "--example", "server"],
        cwd=quinn_dir,
        check=True
    )

    launch = [
        os.path.join(quinn_dir,
                     "target", "release", "examples", "server"),
        "-c", ecc_certs.server_cert_der,
        "-k", ecc_certs.server_key_der,
        "-l", "[::1]:4433",
        "-d", "."  # 实际上是rand-files
    ]

    return ServerRunner('quinn', launch, 4433)


def cf_quiche_runner() -> ServerRunner:
    logging.info("Building cloudflare-quiche server...")

    git_clone("cloudflare", "quiche", "0.23.4")

    subprocess.run(
        ["cargo", "build", "--release", "--bin", "quiche-server"],
        cwd=quiche_dir,
        check=True
    )

    launch = [
        os.path.join(quiche_dir,
                     "target", "release", "quiche-server"),
        "--key", ecc_certs.server_key,
        "--cert", ecc_certs.server_cert,
        "--listen", "[::1]:4434",
        "--root", ".",
        "--no-retry"
    ]

    return ServerRunner('cloudflare quiche', launch, 4434)


class H3Client:
    stress: int
    requests: int
    progress: bool

    def __init__(self, stress: int = 1024*30, requests: int = 8, progress: bool = False):
        logging.info("Building dquic client")
        subprocess.run(
            [
                "cargo", "build", "--package", "h3-shim",
                "--release", "--example", "h3-client",
            ],
            check=True
        )
        self.stress = stress
        self.requests = requests
        self.progress = progress

    def run_once(self, server_runner: ServerRunner, file_size: int, seq: int = 0) -> Result:
        logging.info(f"Launch {server_runner.name} server and client")
        # 在后台启动server
        log_dir = os.path.join(output_dir, "logs")
        if not os.path.exists(log_dir):
            os.makedirs(log_dir)

        client_log = f"client_{server_runner.name}_{file_size}KB_{seq}.log"
        client_log = open(os.path.join(log_dir, client_log), "w+")
        server_log = f"server_{server_runner.name}_{file_size}KB_{seq}.log"
        server_log = open(os.path.join(log_dir, server_log), "w+")

        server = server_runner.run(server_log)
        launch_client = [
            "cargo", "run", "--package", "h3-shim",
            "--release", "--example", "h3-client", "--",
                         "--conns", str(int(self.stress / file_size)),
                         "--reqs", str(self.requests),
                         "--roots", ecc_certs.root_cert,
                         "--progress", "true" if self.progress else "false",
                         "--ansi", "false",
                         f'https://localhost:{server_runner.listen_port}/{rand_files.gen(file_size)}'
        ]

        try:
            subprocess.run(
                launch_client,
                cwd=dquic_dir,
                env={**os.environ, "RUST_LOG": "counting"},
                stdout=client_log,
                text=True,
                timeout=15
            )
        except subprocess.TimeoutExpired:
            server.kill()
            server.wait()
            logging.warning(
                f"Timeout expired for running {server_runner.name} {file_size}KB")
            client_log.close()
            server_log.close()
            return Result(success=0, duration=0)

        server.kill()
        server.wait()
        client_log.seek(0)
        output = client_log.read()
        client_log.close()
        server_log.close()

        # Extract total_time and success_queries using regex
        match = re.search(
            r"success_queries=(\d+).*?total_time=(\d+\.?\d*)", output)
        if match:
            success_queries = int(match.group(1))
            total_time = float(match.group(2))
            return Result(success=int(success_queries), duration=total_time)
        else:
            logging.error(f"Failed to parse benchmark output: {output}")
            return Result(success=0, duration=0)

    def run_many(self, server_runner: ServerRunner, file_size: int, times: int = 3) -> list[Result]:
        results = []
        for seq in range(0, times):
            once = self.run_once(server_runner, file_size, seq)
            logging.info(
                f"Run {server_runner.name} {file_size}KB complete: {once}")
            results.append(once)
        return results


def run(*runners: ServerRunner) -> dict[dict[str, list[Result]]]:
    ecc_certs.gen()
    client = H3Client(stress=2048*15, requests=8, progress=True)

    return {
        runner.name: {
            file_size: client.run_many(runner, file_size, times=10)
            for file_size in [15, 30, 2048]
        }
        for runner in runners
    }


output_dir = os.path.join(root, "output")


def plot_results(results: dict[str, dict[str, list[Result]]]):
    import matplotlib.pyplot as plt
    # [实现名, [文件大小, 多次运行的结果]]
    plot_out_dir = os.path.join(output_dir, "plots")
    if not os.path.exists(plot_out_dir):
        os.makedirs(plot_out_dir)

    implementations = sorted(results.keys())
    file_sizes = sorted(results[implementations[0]].keys())

    for file_size in file_sizes:
        plt.figure(figsize=(10, 6))
        # 平均图
        qps_values = [
            Result.average(results[impl][file_size]).qps
            for impl in implementations
        ]
        bars = plt.bar(implementations, qps_values)

        plt.title(f"file size {file_size}KB")
        plt.xlabel("Implementations")
        plt.ylabel("QPS")
        plt.xticks(rotation=45)

        for bar in bars:
            height = bar.get_height()
            plt.text(bar.get_x() + bar.get_width()/2, height,
                     round(height, 2), ha='center', va='bottom')

        plt.tight_layout()
        plt.savefig(os.path.join(plot_out_dir, f"benchmark_{file_size}KB.png"))
        plt.close()

        # 每个实现的多次运行结果图
        for impl in implementations:
            plt.figure(figsize=(10, 6))
            qps_values = [result.qps for result in results[impl][file_size]]
            bars = plt.bar([i for i in range(len(qps_values))], qps_values)

            plt.title(f"{impl} file size {file_size}KB")
            plt.xlabel("Runs")
            plt.ylabel("QPS")
            plt.xticks(rotation=45)

            for bar in bars:
                height = bar.get_height()
                plt.text(bar.get_x() + bar.get_width()/2, height,
                         round(height, 2), ha='center', va='bottom')

            plt.tight_layout()
            plt.savefig(
                os.path.join(plot_out_dir, f"{impl}_{file_size}KB.png"))
            plt.close()


def save_results(results: dict[str, dict[str, list[Result]]]):
    """save results to json file"""
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    with open(os.path.join(output_dir, "results.json"), "w") as f:
        json.dump({
            impl: {
                size: [r.__dict__ for r in results_list]
                for size, results_list in sizes_results.items()
            }
            for impl, sizes_results in results.items()
        }, f, indent=2)


def load_results(*paths: str) -> dict[str, dict[str, list[Result]]]:
    """load and merge results from multiple json files"""
    merged = {}
    for path in paths:
        with open(path, "r") as f:
            results = {
                impl: {
                    size: [Result(r["success"], r["duration"]) for r in runs]
                    for size, runs in sizes_results.items()
                }
                for impl, sizes_results in json.load(f).items()
            }
            for impl, sizes in results.items():
                if impl not in merged:
                    merged[impl] = {}
                for size, runs in sizes.items():
                    if size not in merged[impl]:
                        merged[impl][size] = []
                    merged[impl][size].extend(runs)
    return merged


if __name__ == "__main__":
    logging.root.setLevel(logging.INFO)

    parser = argparse.ArgumentParser(
        description='QUIC implementation benchmark')
    subparsers = parser.add_subparsers(dest='command', required=True)

    runners = {
        'quic-go': go_quic_runner,
        'dquic': dquic_runner,
        'tquic': tquic_runner,
        'quinn': quinn_runner,
        'cf-quiche': cf_quiche_runner,
        'dquic-multi-path': dquic_multi_path_runner,
    }

    # Diaplay runners
    runners_parser = subparsers.add_parser(
        'runners', help='List available implementations')
    runners_parser.add_argument('-q', '--quiet', action='store_true',
                                help='Only display implementation names')

    # Run command
    run_parser = subparsers.add_parser(
        'run', help='Run benchmark and save results')
    run_parser.add_argument('implementations', nargs='*',
                            choices=list(runners.keys()),
                            help='Implementations to benchmark')
    run_parser.add_argument('--no-plot', action='store_true',
                            help='Skip plotting results')

    # plot command
    plot_parser = subparsers.add_parser(
        'plot', help='Load and plot results from files')
    plot_parser.add_argument('files', nargs='+', default=[os.path.join(output_dir, "results.json")],
                             help='Results JSON file paths')

    # Clean command
    clean_parser = subparsers.add_parser('clean', help='Clean generated files')
    clean_parser.add_argument('--all', action='store_true',
                              help='Also remove git cloned implementations')

    args = parser.parse_args()

    if args.command == 'runners':
        if not args.quiet:
            print("Available implementations:")
            for impl in runners.keys():
                print(f"- {impl}")
        else:
            print(
                '[' + ', '.join(f'"{impl}"' for impl in runners.keys()) + ']'
            )
        exit(0)
    elif args.command == 'run':
        selected_runners = [
            runners[impl]() for impl in args.implementations] if args.implementations else [r() for r in runners.values()]
        results = run(*selected_runners)
        save_results(results)
        if args.no_plot:
            exit(0)
    elif args.command == 'plot':
        results = load_results(*args.files)
    elif args.command == 'clean':
        paths = [rand_files.path, ecc_certs.path, output_dir]
        if args.all:
            paths.extend([quic_go_dir, tquic_dir, quinn_dir, quiche_dir])
        for path in paths:
            if os.path.exists(path):
                shutil.rmtree(path)
        exit(0)

    plot_results(results)

    print(results)


================================================
FILE: codecov.yml
================================================
coverage:
  status:
    patch: off
    project: off
  range: "70..100"


================================================
FILE: commitlint.config.js
================================================
module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    'header-max-length': [2, 'always', 160],
    'body-max-line-length': [2, 'always', 160],
    'footer-max-line-length': [2, 'always', 160],
  },
}


================================================
FILE: dquic/Cargo.toml
================================================
[package]
name = "dquic"
version = "0.5.0"
edition.workspace = true
description = "An IETF quic transport protocol implemented natively using async Rust"
readme = "README.md"
repository.workspace = true
license.workspace = true
keywords.workspace = true
categories.workspace = true
rust-version.workspace = true

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
arc-swap = { workspace = true }
bytes = { workspace = true }
dashmap = { workspace = true }
derive_more = { workspace = true, features = ["deref"] }
futures = { workspace = true }
qconnection = { workspace = true }
qresolve = { workspace = true }
rustls = { workspace = true }
thiserror = { workspace = true }
tokio = { workspace = true }
tokio-util = { workspace = true, features = ["rt"] }
tracing = { workspace = true }

[dev-dependencies]
clap = { workspace = true }
http = { workspace = true }
indicatif = { workspace = true }
postcard = { workspace = true }
qevent = { workspace = true, features = ["telemetry"] }
qtraversal = { workspace = true, features = ["test-ttl"] }
rustls = { workspace = true, features = ["ring"] }
rustls-native-certs = { workspace = true }
serde = { workspace = true }
tokio = { workspace = true, features = ["fs", "io-std", "rt-multi-thread"] }
tokio-util = { workspace = true, features = ["rt"] }
tracing-appender = { workspace = true }
x509-parser = { workspace = true }

# console-subscriber = "0.4"

[features]
default = ["datagram"]
telemetry = ["qconnection/telemetry"]
datagram = ["qconnection/datagram"]

[dev-dependencies.tracing-subscriber]
workspace = true
features = ["env-filter", "time"]


================================================
FILE: dquic/examples/echo-client.rs
================================================
use std::{
    borrow::Cow,
    path::{Path, PathBuf},
    sync::Arc,
    time::Duration,
};

use clap::Parser;
use dquic::prelude::{handy::ToCertificate, *};
use http::uri::Authority;
use indicatif::{MultiProgress, ProgressBar, ProgressDrawTarget, ProgressStyle};
use qevent::telemetry::handy::{LegacySeqLogger, NoopLogger};
use rustls::RootCertStore;
use tokio::{
    fs,
    io::{self, AsyncBufReadExt, AsyncWrite, AsyncWriteExt},
    task::JoinSet,
};
use tracing_subscriber::prelude::*;

#[derive(Parser, Debug)]
#[command(name = "server")]
struct Options {
    #[arg(long, help = "Save the qlog to a dir", value_name = "PATH")]
    qlog: Option<PathBuf>,
    #[arg(
        long,
        short,
        value_delimiter = ',',
        default_value = "tests/keychain/localhost/ca.cert",
        help = "Certificates of CA who issues the server certificate"
    )]
    roots: Vec<PathBuf>,
    #[arg(
        long,
        short,
        value_delimiter = ',',
        help = "files that will be sent to server, if not present, stdin will be used"
    )]
    files: Vec<PathBuf>,
    #[arg(
        long,
        short = 'p',
        action = clap::ArgAction::Set,
        help = "enable progress bar",
        default_value = "false",
        value_enum
    )]
    progress: bool,
    #[arg(
        long,
        default_value = "true",
        action = clap::ArgAction::Set,
        help = "Enable ANSI color output in logs"
    )]
    ansi: bool,
    #[arg(default_value = "localhost:4433", help = "Host and port to connect to")]
    auth: Authority,
}

#[tokio::main]
async fn main() {
    let options = Options::parse();
    let (non_blocking, _guard) = tracing_appender::non_blocking(std::io::stdout());
    tracing_subscriber::registry()
        // .with(
        //     console_subscriber::ConsoleLayer::builder()
        //         .server_addr("127.0.0.1:6670".parse::<SocketAddr>().unwrap())
        //         .spawn(),
        // )
        .with(
            tracing_subscriber::fmt::layer()
                .with_writer(non_blocking)
                .with_ansi(options.ansi)
                .with_filter(
                    tracing_subscriber::EnvFilter::builder()
                        .with_default_directive(match options.progress {
                            true => tracing::level_filters::LevelFilter::OFF.into(),
                            false => tracing::level_filters::LevelFilter::INFO.into(),
                        })
                        .from_env_lossy(),
                ),
        )
        .init();

    if let Err(error) = run(options).await {
        tracing::error!(?error);
        std::process::exit(1);
    };
}

type Error = Box<dyn std::error::Error + Send + Sync>;

async fn run(options: Options) -> Result<(), Error> {
    let qlogger: Arc<dyn qevent::telemetry::QLog + Send + Sync> = match options.qlog {
        Some(dir) => Arc::new(LegacySeqLogger::new(dir)),
        None => Arc::new(NoopLogger),
    };

    let mut roots = RootCertStore::empty();
    roots.add_parsable_certificates(rustls_native_certs::load_native_certs().certs);
    roots.add_parsable_certificates(options.roots.iter().flat_map(|path| path.to_certificate()));

    let client = Arc::new(
        QuicClient::builder()
            .with_root_certificates(roots)
            .without_cert()
            .with_parameters(handy::client_parameters())
            .with_qlog(qlogger)
            .defer_idle_timeout(Duration::from_secs(60))
            .enable_sslkeylog()
            .enable_0rtt()
            .build(),
    );

    match options.files {
        files if files.is_empty() => process(&client, &options.auth, options.progress).await,
        files => {
            let files = files.iter().map(|p| p.as_path());
            send_and_verify_files(&client, options.auth, files, options.progress).await
        }
    }
}

async fn send_and_verify_files(
    client: &Arc<QuicClient>,
    auth: Authority,
    files: impl Iterator<Item = &Path>,
    progress: bool,
) -> Result<(), Error> {
    let pbs = MultiProgress::new();
    if !progress {
        pbs.set_draw_target(ProgressDrawTarget::hidden());
    }
    let total_tx = pbs.add(new_pb("总↑", 0));
    let total_rx = pbs.add(new_pb("总↓️", 0));

    let mut echos = JoinSet::new();

    for path in files {
        let data = fs::read(path).await?;
        let (total_tx, total_rx) = (total_tx.clone(), total_rx.clone());
        total_tx.inc_length(data.len() as u64);
        total_rx.inc_length(data.len() as u64);

        let client = client.clone();
        let auth = auth.clone();

        let tx_pb = pbs.insert_before(&total_tx, new_pb("↑", data.len() as u64));
        let rx_pb = pbs.insert_before(&total_rx, new_pb("↓", data.len() as u64));
        echos.spawn(async move {
            let mut back = vec![];
            send_and_verify_echo(&client, &auth, &data, tx_pb, rx_pb, &mut back).await?;
            assert_eq!(back, data);
            total_tx.inc(data.len() as u64);
            total_rx.inc(data.len() as u64);
            Result::<(), Error>::Ok(())
        });
    }

    echos
        .join_all()
        .await
        .into_iter()
        .collect::<Result<(), Error>>()?;

    total_tx.finish();
    total_rx.finish();

    Ok(())
}

async fn process(client: &Arc<QuicClient>, auth: &Authority, progress: bool) -> Result<(), Error> {
    eprintln!(
        "Enter interactive mode. Input anything, enter, then server will echo it back. Input `exit` or `quit` to quit."
    );

    let mut stdin = io::BufReader::new(io::stdin());
    let mut stdout = io::stdout();

    loop {
        stdout.write_all(b"\n>").await?;
        stdout.flush().await?;

        let mut line = String::new();
        stdin.read_line(&mut line).await?;
        let line = line.trim();

        if line == "exit" || line == "quit" {
            break Ok(());
        }

        let tx_pb = new_pb("↑", line.len() as u64);
        let rx_pb = new_pb("↓️", line.len() as u64);
        if !progress {
            tx_pb.set_draw_target(ProgressDrawTarget::hidden());
            rx_pb.set_draw_target(ProgressDrawTarget::hidden());
        }
        send_and_verify_echo(client, auth, line.as_bytes(), tx_pb, rx_pb, &mut stdout).await?;
    }
}

fn new_pb(prefix: impl Into<Cow<'static, str>>, len: u64) -> ProgressBar {
    let style = ProgressStyle::default_bar()
        .template("{prefix} {wide_bar} {percent_precise}% {decimal_bytes_per_sec} ETA: {eta} {msg}")
        .unwrap();
    ProgressBar::new(len).with_style(style).with_prefix(prefix)
}

async fn send_and_verify_echo(
    client: &Arc<QuicClient>,
    auth: &Authority,
    data: &[u8],
    tx_pb: ProgressBar,
    rx_pb: ProgressBar,
    dst: &mut (impl AsyncWrite + Unpin),
) -> Result<(), Error> {
    let connection = client.connect(auth.host()).await?;

    let (sid, (reader, writer)) = connection.open_bi_stream().await?.unwrap();
    tracing::debug!(%sid, "opened stream");

    let mut reader = rx_pb.wrap_async_read(reader);
    let mut writer = tx_pb.wrap_async_write(writer);

    tokio::try_join!(
        async {
            writer.write_all(data).await?;
            writer.shutdown().await?;
            tx_pb.finish();
            Result::<(), Error>::Ok(())
        },
        async {
            io::copy(&mut reader, dst).await?;
            dst.flush().await?;
            rx_pb.finish();
            Result::<(), Error>::Ok(())
        }
    )
    .map(|_| ())
}


================================================
FILE: dquic/examples/echo-server.rs
================================================
use std::{path::PathBuf, sync::Arc, time::Duration};

use clap::Parser;
use dquic::{prelude::*, qinterface::io::IO};
use qevent::telemetry::handy::{LegacySeqLogger, NoopLogger};
use tokio::io::{self, AsyncWriteExt};
use tracing::info;
use tracing_subscriber::prelude::*;

#[derive(Parser, Debug)]
#[command(name = "server")]
struct Options {
    #[arg(long, help = "Save the qlog to a dir", value_name = "PATH")]
    qlog: Option<PathBuf>,
    #[arg(
        short,
        long,
        value_delimiter = ',',
        default_values = ["127.0.0.1:4433", "[::1]:4433"],
        help = "What BindUris to listen for new connections",
    )]
    listen: Vec<BindUri>,
    #[arg(
        long,
        short,
        default_value = "4096",
        help = "Maximum number of requests in the backlog. \
                If the backlog is full, new connections will be refused."
    )]
    backlog: usize,
    #[arg(
        long,
        default_value = "true",
        action = clap::ArgAction::Set,
        help = "Enable ANSI color output in logs"
    )]
    ansi: bool,
    #[command(flatten)]
    certs: Certs,
}

#[derive(Parser, Debug)]
struct Certs {
    #[arg(long, short, default_value = "localhost", help = "Server name.")]
    server_name: String,
    #[arg(
        long,
        short,
        default_value = "tests/keychain/localhost/server.cert",
        help = "Certificate for TLS. If present, `--key` is mandatory."
    )]
    cert: PathBuf,
    #[arg(
        long,
        short,
        default_value = "tests/keychain/localhost/server.key",
        help = "Private key for the certificate."
    )]
    key: PathBuf,
}

#[tokio::main]
async fn main() {
    let options = Options::parse();
    let (non_blocking, _guard) = tracing_appender::non_blocking(std::io::stdout());
    tracing_subscriber::registry()
        // .with(console_subscriber::spawn())
        .with(
            tracing_subscriber::fmt::layer()
                .with_writer(non_blocking)
                .with_ansi(options.ansi)
                .with_filter(
                    tracing_subscriber::EnvFilter::builder()
                        .with_default_directive(tracing::level_filters::LevelFilter::INFO.into())
                        .from_env_lossy(),
                ),
        )
        .init();

    if let Err(error) = run(options).await {
        tracing::info!(?error);
        std::process::exit(1);
    }
}

async fn run(options: Options) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    let qlogger: Arc<dyn qevent::telemetry::QLog + Send + Sync> = match options.qlog {
        Some(dir) => Arc::new(LegacySeqLogger::new(dir)),
        None => Arc::new(NoopLogger),
    };

    let listeners = QuicListeners::builder()
        .without_client_cert_verifier()
        .with_parameters(handy::server_parameters())
        .with_qlog(qlogger)
        .defer_idle_timeout(Duration::from_secs(0))
        .enable_0rtt()
        .listen(options.backlog)?;
    listeners
        .add_server(
            options.certs.server_name.as_str(),
            options.certs.cert.as_path(),
            options.certs.key.as_path(),
            options.listen,
            None,
        )
        .await?;

    tracing::info!(
        "Listening on {}",
        listeners
            .get_server(options.certs.server_name.as_str())
            .unwrap()
            .bind_interfaces()
            .iter()
            .next()
            .unwrap()
            .1
            .borrow()
            .bound_addr()?
    );

    serve_echo(listeners).await?;
    Ok(())
}

async fn serve_echo(listeners: Arc<QuicListeners>) -> Result<(), ListenersShutdown> {
    async fn handle_stream(mut reader: StreamReader, mut writer: StreamWriter) -> io::Result<()> {
        io::copy(&mut reader, &mut writer).await?;
        writer.shutdown().await?;
        tracing::debug!("stream copy done");

        io::Result::Ok(())
    }

    loop {
        let (connection, _server, pathway, ..) = listeners.accept().await?;
        info!(source = ?pathway.remote(), "accepted new connection");
        tokio::spawn(async move {
            while let Ok((_sid, (reader, writer))) = connection.accept_bi_stream().await {
                tokio::spawn(handle_stream(reader, writer));
            }
        });
    }
}


================================================
FILE: dquic/examples/http-client.rs
================================================
use std::{path::PathBuf, sync::Arc};

use clap::Parser;
use dquic::prelude::{handy::ToCertificate, *};
use http::{Uri, uri::Parts};
use qevent::telemetry::handy::{LegacySeqLogger, NoopLogger};
use tokio::{
    fs,
    io::{self, AsyncBufReadExt, AsyncWriteExt, BufReader},
};
use tracing_subscriber::prelude::*;

#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Options {
    #[arg(long, help = "Save the qlog to a dir", value_name = "PATH")]
    qlog: Option<PathBuf>,
    #[arg(
        long,
        short,
        value_delimiter = ',',
        default_value = "tests/keychain/localhost/ca.cert",
        help = "Certificates of CA who issues the server certificate"
    )]
    roots: Vec<PathBuf>,
    #[arg(long, help = "Skip verification of server certificate")]
    skip_verify: bool,
    #[arg(
        long,
        short,
        value_delimiter = ',',
        default_value = "quic",
        help = "ALPNs to use for the connection"
    )]
    alpns: Vec<Vec<u8>>,
    #[arg(
        long,
        default_value = "true",
        action = clap::ArgAction::Set,
        help = "Enable ANSI color output in logs"
    )]
    ansi: bool,
    #[arg(long, help = "Save the response to a dir", value_name = "PATH")]
    save: Option<PathBuf>,
    #[arg(
        value_delimiter = ',',
        default_value = "http://localhost:4433/",
        help = "Uri to request. If only one uri is present and path is not specified, enter process mode"
    )]
    uris: Vec<Uri>,
}

#[tokio::main]
async fn main() {
    let options = Options::parse();
    let (non_blocking, _guard) = tracing_appender::non_blocking(std::io::stdout());
    tracing_subscriber::registry()
        // .with(
        //     console_subscriber::ConsoleLayer::builder()
        //         .server_addr("127.0.0.1:6670".parse::<SocketAddr>().unwrap())
        //         .spawn(),
        // )
        .with(
            tracing_subscriber::fmt::layer()
                .with_writer(non_blocking)
                .with_ansi(options.ansi)
                .with_filter(
                    tracing_subscriber::EnvFilter::builder()
                        .with_default_directive(tracing::level_filters::LevelFilter::INFO.into())
                        .from_env_lossy(),
                ),
        )
        .init();

    if let Err(error) = run(options).await {
        tracing::error!(?error);
        std::process::exit(1);
    }
}

type Error = Box<dyn std::error::Error + Send + Sync>;

async fn run(options: Options) -> Result<(), Error> {
    if options.uris.is_empty() {
        return Err("no uri specified".into());
    }

    let qlogger: Arc<dyn qevent::telemetry::QLog + Send + Sync> = match options.qlog {
        Some(dir) => Arc::new(LegacySeqLogger::new(dir)),
        None => Arc::new(NoopLogger),
    };

    let client_builder = if options.skip_verify {
        tracing::warn!("skip server verify");
        QuicClient::builder().without_verifier()
    } else {
        tracing::info!("load ca certs");
        let mut roots = rustls::RootCertStore::empty();
        roots.add_parsable_certificates(rustls_native_certs::load_native_certs().certs);
        roots
            .add_parsable_certificates(options.roots.iter().flat_map(|path| path.to_certificate()));
        QuicClient::builder().with_root_certificates(roots)
    };

    let client = Arc::new(
        client_builder
            .with_qlog(qlogger)
            .without_cert()
            .with_parameters(handy::client_parameters())
            .with_alpns(options.alpns)
            .enable_sslkeylog()
            .build(),
    );

    if options.uris.len() == 1 && options.uris[0].path() == "/" {
        return process(&client, &options.uris[0], options.save).await;
    } else {
        for uri in options.uris {
            download(&client, uri, options.save.as_ref()).await?;
        }
    }

    Ok(())
}

async fn process(
    client: &Arc<QuicClient>,
    base_uri: &Uri,
    save: Option<PathBuf>,
) -> Result<(), Error> {
    let mut stdin = BufReader::new(io::stdin());
    eprintln!(
        "Enter interactive mode. Input content to request (e.g: Cargo.toml), input `exit` or `quit` to quit."
    );
    loop {
        let mut input = String::new();
        _ = stdin.read_line(&mut input).await?;

        let content = input.trim();
        if content.is_empty() {
            continue;
        }

        if content == "exit" || content == "quit" {
            return Ok(());
        }

        let mut uri_parts = Parts::default();
        uri_parts.scheme = base_uri.scheme().cloned();
        uri_parts.authority = base_uri.authority().cloned();
        uri_parts.path_and_query = Some(format!("/{content}").parse()?);
        download(client, Uri::from_parts(uri_parts)?, save.as_ref()).await?;
    }
}

async fn download(client: &Arc<QuicClient>, uri: Uri, save: Option<&PathBuf>) -> Result<(), Error> {
    let authority = uri.authority().ok_or("authority must be present in uri")?;

    let file_path = uri.path().strip_prefix('/');
    let file_path = file_path.ok_or_else(|| format!("invalid path `{}`", uri.path()))?;

    let connection = client.connect(authority.host()).await?;
    let (_sid, (mut response, mut request)) = connection
        .open_bi_stream()
        .await?
        .expect("very very hard to exhaust the available stream ids");
    request
        .write_all(format!("GET /{file_path}").as_bytes())
        .await?;
    request.shutdown().await?;

    match save.map(|dir| dir.join(file_path)) {
        Some(path) => io::copy(&mut response, &mut fs::File::create(path).await?).await?,
        None => io::copy(&mut response, &mut io::stdout()).await?,
    };

    _ = connection.close("Bye bye", 0);

    tracing::info!("Saved to file {file_path}");
    Ok(())
}


================================================
FILE: dquic/examples/http-server.rs
================================================
use std::{path::PathBuf, sync::Arc};

use clap::Parser;
use dquic::{prelude::*, qinterface::io::IO};
use tokio::{
    fs,
    io::{self, AsyncReadExt, AsyncWriteExt},
};
use tracing_subscriber::prelude::*;

#[derive(Parser, Debug)]
#[command(name = "server")]
struct Options {
    #[arg(
        name = "dir",
        short,
        long,
        help = "Root directory of the files to serve. \
                If omitted, server will respond OK.",
        default_value = "./"
    )]
    root: PathBuf,
    #[arg(long, help = "Save the qlog to a dir", value_name = "PATH")]
    qlog: Option<PathBuf>,
    #[arg(
        short,
        long,
        value_delimiter = ',',
        default_values = ["127.0.0.1:4433", "[::1]:4433"],
        help = "What BindUris to listen for new connections"
    )]
    listen: Vec<BindUri>,
    #[arg(
        long,
        short,
        value_delimiter = ',',
        default_value = "quic",
        help = "ALPNs to use for the connection"
    )]
    alpns: Vec<Vec<u8>>,
    #[arg(
        long,
        short,
        default_value = "4096",
        help = "Maximum number of requests in the backlog. \
                If the backlog is full, new connections will be refused."
    )]
    backlog: usize,
    #[arg(
        long,
        default_value = "true",
        action = clap::ArgAction::Set,
        help = "Enable ANSI color output in logs"
    )]
    ansi: bool,
    #[command(flatten)]
    certs: Certs,
}

#[derive(Parser, Debug)]
struct Certs {
    #[arg(long, short, default_value = "localhost", help = "Server name.")]
    server_name: String,
    #[arg(
        long,
        short,
        default_value = "tests/keychain/localhost/server.cert",
        help = "Certificate for TLS. If present, `--key` is mandatory."
    )]
    cert: PathBuf,
    #[arg(
        long,
        short,
        default_value = "tests/keychain/localhost/server.key",
        help = "Private key for the certificate."
    )]
    key: PathBuf,
}

type Error = Box<dyn std::error::Error + Send + Sync>;

fn main() {
    let options = Options::parse();
    let (non_blocking, _guard) = tracing_appender::non_blocking(std::io::stdout());
    tracing_subscriber::registry()
        // .with(console_subscriber::spawn())
        .with(
            tracing_subscriber::fmt::layer()
                .with_writer(non_blocking)
                .with_ansi(options.ansi)
                .with_filter(
                    tracing_subscriber::EnvFilter::builder()
                        .with_default_directive(tracing::level_filters::LevelFilter::INFO.into())
                        .from_env_lossy(),
                ),
        )
        .init();

    let rt = tokio::runtime::Builder::new_current_thread()
        .enable_all()
        // default value 512 out of macos ulimit
        .max_blocking_threads(256)
        .build()
        .expect("failed to build tokio runtime");

    if let Err(error) = rt.block_on(run(options)) {
        tracing::info!(?error);
        std::process::exit(1);
    }
}

async fn run(options: Options) -> Result<(), Error> {
    let qlogger: Arc<dyn qevent::telemetry::QLog + Send + Sync> = match options.qlog {
        Some(dir) => Arc::new(handy::LegacySeqLogger::new(dir)),
        None => Arc::new(handy::NoopLogger),
    };

    let listeners = QuicListeners::builder()
        .with_qlog(qlogger)
        .without_client_cert_verifier()
        .with_parameters(handy::server_parameters())
        .with_alpns(options.alpns)
        .listen(options.backlog)?;
    listeners
        .add_server(
            options.certs.server_name.as_str(),
            options.certs.cert.as_path(),
            options.certs.key.as_path(),
            options.listen,
            None,
        )
        .await?;

    tracing::info!(
        "Listening on {}",
        listeners
            .get_server(options.certs.server_name.as_str())
            .unwrap()
            .bind_interfaces()
            .iter()
            .next()
            .unwrap()
            .1
            .borrow()
            .bound_addr()?
    );

    loop {
        let (connection, _server, _pathway, _link) = listeners.accept().await?;
        tokio::spawn(serve_files(connection));
    }
}

async fn serve_files(connection: Connection) -> Result<(), Error> {
    async fn serve_file(mut reader: StreamReader, mut writer: StreamWriter) -> Result<(), Error> {
        let mut request = String::new();
        reader.read_to_string(&mut request).await?;
        tracing::info!("received request: {request}");

        // HTTP/0.9 is very simple - just a GET request with a path
        let serve = async {
            match request.trim().strip_prefix("GET /") {
                Some(path) => {
                    tracing::debug!(?path, "Received HTTP/0.9 request");
                    let mut file = fs::File::open(PathBuf::from_iter(["./", path])).await?;
                    io::copy(&mut file, &mut writer).await.map(|_| ())
                }
                None => Err(io::Error::other(format!(
                    "Invalid HTTP/0.9 request: {request}",
                ))),
            }
        };

        if let Err(error) = serve.await {
            tracing::warn!("failed to serve request: {}", error);
        }

        _ = writer.shutdown().await;

        Ok(())
    }

    loop {
        let (_sid, (reader, writer)) = connection.accept_bi_stream().await?;
        tokio::spawn(serve_file(reader, writer));
    }
}


================================================
FILE: dquic/examples/traversal-client.rs
================================================
// use std::{io, net::SocketAddr};

// use clap::Parser;
// use dquic::{
//     prelude::{
//         Connection, EndpointAddr, ParameterId, QuicClient, EndpointAddr, handy::ToCertificate,
//     },
//     qbase::param::ClientParameters,
//     qtraversal::iface::TraversalFactory,
// };
// use rustls::RootCertStore;
// use tokio::{
//     io::{AsyncReadExt, AsyncWriteExt},
//     task::JoinSet,
// };
// use tracing::{info, warn};
// use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};

// #[derive(Parser)]
// struct Options {
//     #[arg(long)]
//     bind1: SocketAddr,
//     #[arg(long)]
//     bind2: SocketAddr,
//     #[arg(long)]
//     server_outer: SocketAddr,
//     #[arg(long)]
//     server_agent: SocketAddr,
//     #[arg(long, default_value = "nat.genmeta.net:20004")]
//     stun_server: String,
// }

// pub type Error = Box<dyn std::error::Error + Send + Sync>;

// #[tokio::main]
// pub async fn main() -> io::Result<()> {
//     init_logger()?;
//     let default_panic = std::panic::take_hook();
//     std::panic::set_hook(Box::new(move |info| {
//         default_panic(info);
//         info!("panic: {}", info);
//         std::process::exit(1);
//     }));
//     let ops = Options::parse();
//     let server_ep = EndpointAddr::Agent {
//         agent: ops.server_agent,
//         outer: ops.server_outer,
//     };

//     let mut roots = RootCertStore::empty();
//     roots.add_parsable_certificates(
//         include_bytes!("../../../tests/keychain/localhost/ca.cert").to_certificate(),
//     );

//     let stun_servers: Vec<SocketAddr> = tokio::net::lookup_host(&ops.stun_server).await?.collect();
//     if stun_servers.is_empty() {
//         return Err(io::Error::other("failed to resolve stun server"));
//     }

//     let factory = TraversalFactory::initialize_global(stun_servers).unwrap();
//     let client = QuicClient::builder()
//         .with_root_certificates(roots)
//         .without_cert()
//         .enable_sslkeylog()
//         // .with_qlog(Arc::new(DefaultSeqLogger::new(PathBuf::from("qlog"))))
//         .with_iface_factory(factory.as_ref().clone())
//         .with_parameters(client_stream_unlimited_parameters())
//         .bind(&[ops.bind1, ops.bind2][..])
//         .await
//         .build();

//     let mut handle_set = JoinSet::new();
//     for _ in 0..1 {
//         info!(
//             "server ep {:?}, bind {} {}",
//             server_ep, ops.bind1, ops.bind2
//         );
//         let connection = client
//             .connected_to("localhost", [server_ep])
//             .await
//             .map_err(io::Error::other)?;

//         const DATA: &[u8] = include_bytes!("./client.rs");
//         handle_set.spawn(async move {
//             send_and_verify_echo(&connection, DATA).await.unwrap();
//             // 等待打洞结束
//             tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;
//             warn!("finish one connection");
//         });
//     }
//     let _et = handle_set.join_all().await;
//     Ok(())
// }

// async fn send_and_verify_echo(connection: &Connection, data: &[u8]) -> Result<(), Error> {
//     let (_sid, (mut reader, mut writer)) = connection.open_bi_stream().await?.unwrap();
//     tracing::debug!("stream opened");

//     let mut back = Vec::new();
//     tokio::try_join!(
//         async {
//             writer.write_all(data).await?;
//             writer.shutdown().await?;
//             tracing::info!("xxxxx write done");
//             Result::<(), Error>::Ok(())
//         },
//         async {
//             reader.read_to_end(&mut back).await?;
//             assert_eq!(back, data);
//             tracing::info!("xxxx read done");
//             Result::<(), Error>::Ok(())
//         }
//     )
//     .map(|_| ())
// }

// fn client_stream_unlimited_parameters() -> ClientParameters {
//     let mut params = ClientParameters::default();
//     _ = params.set(ParameterId::ActiveConnectionIdLimit, 10u32);
//     _ = params.set(ParameterId::InitialMaxData, 1u32 << 20);
//     _ = params.set(ParameterId::InitialMaxStreamDataBidiLocal, 1u32 << 20);
//     _ = params.set(ParameterId::InitialMaxStreamDataBidiRemote, 1u32 << 20);
//     _ = params.set(ParameterId::InitialMaxStreamDataUni, 1u32 << 20);
//     _ = params.set(ParameterId::InitialMaxStreamsBidi, 100u32);
//     _ = params.set(ParameterId::InitialMaxStreamsUni, 100u32);
//     params
// }

// pub fn init_logger() -> std::io::Result<()> {
//     let filter = tracing_subscriber::filter::filter_fn(|metadata| {
//         !metadata.target().contains("netlink_packet_route")
//     });

//     let _ = tracing_subscriber::registry()
//         .with(tracing_subscriber::Layer::with_filter(
//             tracing_subscriber::fmt::layer()
//                 .with_target(true)
//                 .with_ansi(false)
//                 .with_file(true)
//                 .with_line_number(true),
//             filter,
//         ))
//         .try_init();
//     Ok(())
// }

fn main() {}


================================================
FILE: dquic/examples/traversal-server.rs
================================================
// use std::{io, net::SocketAddr, sync::Arc};

// use clap::Parser;
// use dquic::{
//     prelude::{Connection, ParameterId, QuicListeners, StreamReader, StreamWriter},
//     qbase::param::ServerParameters,
//     qtraversal,
// };
// use qtraversal::iface::TraversalFactory;
// use tokio::io::AsyncWriteExt;
// use tracing::{Instrument, info, info_span};
// use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};

// #[derive(clap::Parser)]
// struct Options {
//     #[arg(long, default_value = "192.168.1.4:6000")]
//     bind1: SocketAddr,
//     #[arg(long, default_value = "[2409:8a00:1850:be40:1037:3cbd:ec40:11c6]:6000")]
//     bind2: SocketAddr,
//     #[arg(long, default_value = "nat.genmeta.net:20004")]
//     stun_server: String,
// }

// #[tokio::main]
// pub async fn main() -> io::Result<()> {
//     init_logger()?;
//     let default_panic = std::panic::take_hook();
//     std::panic::set_hook(Box::new(move |info| {
//         default_panic(info);
//         info!("panic: {}", info);
//         std::process::exit(1);
//     }));
//     let ops = Options::parse();

//     let stun_servers: Vec<SocketAddr> = tokio::net::lookup_host(&ops.stun_server).await?.collect();
//     if stun_servers.is_empty() {
//         return Err(io::Error::other("failed to resolve stun server"));
//     }

//     let factory = TraversalFactory::initialize_global(stun_servers).unwrap();
//     let server = QuicListeners::builder()?
//         // .with_single_cert(
//         //     include_bytes!("../../../tests/keychain/localhost/server.cert"),
//         //     include_bytes!("../../../tests/keychain/localhost/server.key"),
//         // )
//         .with_iface_factory(factory.as_ref().clone())
//         .with_parameters(server_stream_unlimited_parameters())
//         .without_client_cert_verifier()
//         .listen(1000);

//     server
//         .add_server(
//             "localhost",
//             include_bytes!("../../../tests/keychain/localhost/server.cert"),
//             include_bytes!("../../../tests/keychain/localhost/server.key"),
//             [ops.bind1],
//             None,
//         )
//         .await?;

//     launch(server).await?;

//     Ok(())
// }

// pub fn server_stream_unlimited_parameters() -> ServerParameters {
//     let mut params = ServerParameters::default();
//     _ = params.set(ParameterId::ActiveConnectionIdLimit, 10u32);
//     _ = params.set(ParameterId::InitialMaxData, 1u32 << 20);
//     _ = params.set(ParameterId::InitialMaxStreamDataBidiLocal, 1u32 << 20);
//     _ = params.set(ParameterId::InitialMaxStreamDataBidiRemote, 1u32 << 20);
//     _ = params.set(ParameterId::InitialMaxStreamDataUni, 1u32 << 20);
//     _ = params.set(ParameterId::InitialMaxStreamsBidi, 100u32);
//     _ = params.set(ParameterId::InitialMaxStreamsUni, 100u32);
//     params
// }

// pub async fn launch(server: Arc<QuicListeners>) -> io::Result<()> {
//     async fn handle_connection(conn: Arc<Connection>) -> io::Result<()> {
//         loop {
//             let (sid, (reader, writer)) = conn.accept_bi_stream().await?;
//             tokio::spawn(
//                 handle_stream(reader, writer).instrument(info_span!("handle_stream",%sid)),
//             );
//         }
//     }

//     async fn handle_stream(mut reader: StreamReader, mut writer: StreamWriter) -> io::Result<()> {
//         tokio::io::copy(&mut reader, &mut writer).await?;
//         writer.shutdown().await?;
//         tracing::info!("stream copy done");

//         io::Result::Ok(())
//     }

//     loop {
//         let (connection, _name, pathway, _link) = server
//             .accept()
//             .await
//             .map_err(|_e| io::Error::other("accept error"))?;
//         info!(source = ?pathway.remote(), "accepted new connection");
//         tokio::spawn(handle_connection(Arc::new(connection)));
//     }
// }

// pub fn init_logger() -> std::io::Result<()> {
//     let filter = tracing_subscriber::filter::filter_fn(|metadata| {
//         !metadata.target().contains("netlink_packet_route")
//     });

//     let _ = tracing_subscriber::registry()
//         .with(tracing_subscriber::Layer::with_filter(
//             tracing_subscriber::fmt::layer()
//                 .with_target(true)
//                 .with_ansi(false)
//                 .with_file(true)
//                 .with_line_number(true),
//             filter,
//         ))
//         .try_init();
//     Ok(())
// }

fn main() {}


================================================
FILE: dquic/src/cert.rs
================================================
use std::path::Path;

use rustls::pki_types::{CertificateDer, PrivateKeyDer, pem::PemObject};

pub trait ToCertificate {
    fn to_certificate(self) -> Vec<CertificateDer<'static>>;
}

impl ToCertificate for Vec<CertificateDer<'static>> {
    fn to_certificate(self) -> Vec<CertificateDer<'static>> {
        self
    }
}

impl ToCertificate for &[CertificateDer<'static>] {
    fn to_certificate(self) -> Vec<CertificateDer<'static>> {
        self.to_vec().to_certificate()
    }
}

impl<const N: usize> ToCertificate for [CertificateDer<'static>; N] {
    fn to_certificate(self) -> Vec<CertificateDer<'static>> {
        self.to_vec().to_certificate()
    }
}

impl ToCertificate for CertificateDer<'static> {
    fn to_certificate(self) -> Vec<CertificateDer<'static>> {
        vec![self]
    }
}

impl ToCertificate for &Path {
    fn to_certificate(self) -> Vec<CertificateDer<'static>> {
        let data = std::fs::read(self).expect("Failed to read certificate file");
        if let Ok(certs) = CertificateDer::pem_slice_iter(&data).collect::<Result<Vec<_>, _>>()
            && !certs.is_empty()
        {
            return certs;
        }

        vec![CertificateDer::from(data)]
    }
}

impl ToCertificate for &[u8] {
    fn to_certificate(self) -> Vec<CertificateDer<'static>> {
        if let Ok(certs) = CertificateDer::pem_slice_iter(self).collect::<Result<Vec<_>, _>>()
            && !certs.is_empty()
        {
            return certs;
        }

        vec![CertificateDer::from(self.to_vec())]
    }
}

impl<const N: usize> ToCertificate for &[u8; N] {
    fn to_certificate(self) -> Vec<CertificateDer<'static>> {
        <&[u8]>::to_certificate(self)
    }
}

pub trait ToPrivateKey {
    fn to_private_key(self) -> PrivateKeyDer<'static>;
}

impl ToPrivateKey for PrivateKeyDer<'static> {
    fn to_private_key(self) -> PrivateKeyDer<'static> {
        self
    }
}

impl ToPrivateKey for &PrivateKeyDer<'static> {
    fn to_private_key(self) -> PrivateKeyDer<'static> {
        self.clone_key()
    }
}

impl ToPrivateKey for &Path {
    fn to_private_key(self) -> PrivateKeyDer<'static> {
        let data = std::fs::read(self).expect("failed to read private key file");
        if let Ok(key) = PrivateKeyDer::from_pem_slice(&data) {
            return key;
        }

        PrivateKeyDer::try_from(data)
            .expect("failed to parse private key file as pem or der format")
    }
}

impl ToPrivateKey for &[u8] {
    fn to_private_key(self) -> PrivateKeyDer<'static> {
        if let Ok(key) = PrivateKeyDer::from_pem_slice(self) {
            return key;
        }

        PrivateKeyDer::try_from(self.to_vec())
            .expect("failed to parse private key file as pem or der format")
    }
}

impl<const N: usize> ToPrivateKey for &[u8; N] {
    fn to_private_key(self) -> PrivateKeyDer<'static> {
        <&[u8]>::to_private_key(self)
    }
}


================================================
FILE: dquic/src/client.rs
================================================
use std::{
    collections::HashMap,
    io,
    net::SocketAddr,
    str::FromStr,
    sync::{
        Arc,
        atomic::{AtomicBool, Ordering},
    },
    time::Duration,
};

use dashmap::DashMap;
use futures::StreamExt;
use qbase::{net::Family, param::ClientParameters, token::TokenSink};
use qconnection::{
    self,
    qbase::net::AddrFamily,
    qinterface::{component::location::Locations, io::IO},
};
use qevent::telemetry::QLog;
use qinterface::{
    BindInterface, Interface, bind_uri::BindUri, component::route::QuicRouter, device::Devices,
    io::ProductIO, manager::InterfaceManager,
};
use qresolve::Source;
use rustls::{
    ConfigBuilder, WantsVerifier,
    client::{ResolvesClientCert, WantsClientCert},
};
use thiserror::Error;

use crate::{prelude::*, *};

type TlsClientConfig = rustls::ClientConfig;
type TlsClientConfigBuilder<T> = ConfigBuilder<TlsClientConfig, T>;

/// A QUIC client for initiating connections to servers.
///
/// ## Creating Clients
///
/// Use [`QuicClient::builder`] to configure and create a client instance.
/// Configure interfaces, TLS settings, and connection behavior before building.
///
/// ## Interface Management
///
/// - **Automatic binding**: If no interfaces are bound, the client automatically binds to system-assigned addresses
/// - **Manual binding**: Use [`QuicClientBuilder::bind`] to bind specific interfaces
///
/// ## Connection Handling
///
/// Call [`QuicClient::connect`] to establish connections. The client supports:
/// - **Automatic interface selection**: Matches interface with server endpoint address
#[derive(Clone)]
pub struct QuicClient {
    network: common::Network,
    bind_ifaces: DashMap<BindUri, BindInterface>,
    manual_bind: Arc<AtomicBool>,

    // quic config(in initialize order)
    _prefer_versions: Vec<u32>,
    token_sink: Arc<dyn TokenSink>,
    parameters: ClientParameters,
    tls_config: TlsClientConfig,
    stream_strategy_factory: Arc<dyn ProductStreamsConcurrencyController>,
    defer_idle_timeout: Duration,
    qlogger: Arc<dyn QLog + Send + Sync>,
}

#[derive(Debug, Error)]
pub enum ConnectServerError {
    #[error("DNS lookup failed")]
    Dns {
        #[from]
        source: io::Error,
    },
    #[error("Failed to bind interface for client connection")]
    BindInterface {
        #[from]
        source: BindInterfaceError,
    },
}

#[derive(Debug, Error)]
#[error(
    "Failed to bind interface `{}` for client connection",
    bind_uri.as_ref().map_or(String::from("<no bind uri generated>"), |bind_uri| bind_uri.to_string())
)]
pub struct BindInterfaceError {
    bind_uri: Option<BindUri>,
    #[source]
    bind_error: io::Error,
}

impl QuicClient {
    #[inline]
    pub fn bind_ifaces(&self) -> HashMap<BindUri, BindInterface> {
        self.bind_ifaces
            .iter()
            .map(|entry| (entry.key().clone(), entry.value().clone()))
            .collect()
    }

    pub async fn bind(&self, bind_uri: impl Into<BindUri>) -> BindInterface {
        let bind_interface = self.network.bind(bind_uri.into()).await;
        self.bind_ifaces
            .insert(bind_interface.bind_uri(), bind_interface.clone());
        self.manual_bind.store(true, Ordering::Relaxed);
        bind_interface
    }

    #[inline]
    pub fn unbind(&self, bind_uri: &BindUri) -> Option<BindInterface> {
        self.bind_ifaces.remove(bind_uri).map(|(_, iface)| iface)
    }

    /// Creates a new QUIC connection to the specified server without any initial paths.
    ///
    /// This method initializes the connection state but does not start the handshake
    /// because no network paths are established yet. You must manually add paths
    /// using [`Connection::add_path`] to initiate communication.
    ///
    /// This is useful for advanced scenarios where you need fine-grained control
    /// over which interfaces and paths are used for the connection.
    pub fn new_connection(&self, server_name: impl Into<String>) -> Connection {
        Connection::new_client(server_name.into(), self.token_sink.clone())
            .with_parameters(self.parameters.clone())
            .with_tls_config(self.tls_config.clone())
            .with_streams_concurrency_strategy(self.stream_strategy_factory.as_ref())
            .with_zero_rtt(self.tls_config.enable_early_data)
            .with_iface_factory(self.network.iface_factory.clone())
            .with_iface_manager(self.network.iface_manager.clone())
            .with_quic_router(self.network.quic_router.clone())
            .with_locations(self.network.locations.clone())
            // todo
            // .with_stun_servers()
            .with_defer_idle_timeout(self.defer_idle_timeout)
            .with_cids(ConnectionId::random_gen(8))
            .with_qlog(self.qlogger.clone())
            .run()
    }

    /// Builds a [`BindUri`] from the DNS [`Source`] and endpoint address.
    ///
    /// - For [`Source::Mdns`]: binds to the discovering NIC (e.g., `iface://v4.en0:0`).
    /// - For other sources: binds to a wildcard address matching the endpoint family.
    fn bind_uri_for(source: &Source, ep: &EndpointAddr) -> BindUri {
        match source {
            Source::Mdns { nic, family } => {
                let f = match family {
                    Family::V4 => "v4",
                    Family::V6 => "v6",
                };
                BindUri::from_str(&format!("iface://{f}.{nic}:0"))
                    .expect("iface URI should be valid")
                    .alloc_port()
            }
            _ => match ep.family() {
                Family::V4 => BindUri::from_str("inet://0.0.0.0:0")
                    .expect("URL should be valid")
                    .alloc_port(),
                Family::V6 => BindUri::from_str("inet://[::]:0")
                    .expect("URL should be valid")
                    .alloc_port(),
            },
        }
    }

    /// Ensures at least one interface exists for the given endpoint.
    async fn ensure_iface_for(&self, source: &Source, ep: &EndpointAddr) {
        if self.manual_bind.load(Ordering::Relaxed) {
            return;
        }
        if self.bind_ifaces.is_empty() {
            let bind_uri = Self::bind_uri_for(source, ep);
            let iface = self.network.bind(bind_uri).await;
            self.bind_ifaces.insert(iface.bind_uri(), iface);
        }
    }

    /// Returns matching bound interfaces or auto-binds a new one.
    async fn select_or_bind_ifaces(
        &self,
        source: &Source,
        ep: &EndpointAddr,
    ) -> Result<Vec<(SocketAddr, Interface)>, BindInterfaceError> {
        let iface_matches_source =
            |iface: &Interface| match source {
                Source::Mdns { nic, family } => iface.bind_uri().as_iface_bind_uri().is_some_and(
                    |(iface_family, iface_name, _)| {
                        iface_family == *family && iface_name == nic.as_ref()
                    },
                ),
                _ => true,
            };

        if self.manual_bind.load(Ordering::Relaxed) {
            let ifaces = self
                .bind_ifaces
                .iter()
                .map(|entry| entry.value().borrow())
                .filter(|iface| iface_matches_source(iface))
                .filter_map(|iface| Some((iface.bound_addr().ok()?, iface)))
                .filter(|(addr, _)| addr.family() == ep.family())
                .collect::<Vec<_>>();
            Ok(ifaces)
        } else {
            let ifaces = self
                .bind_ifaces
                .iter()
                .map(|entry| entry.value().borrow())
                .filter(|iface| iface_matches_source(iface))
                .filter_map(|iface| Some((iface.bound_addr().ok()?, iface)))
                .filter(|(addr, _)| addr.family() == ep.family())
                .collect::<Vec<_>>();
            if !ifaces.is_empty() {
                return Ok(ifaces);
            }
            let bind_uri = Self::bind_uri_for(source, ep);
            let iface = self.network.bind(bind_uri.clone()).await.borrow();
            let bound_addr = iface.bound_addr().map_err(|source| BindInterfaceError {
                bind_uri: Some(bind_uri),
                bind_error: source,
            })?;
            Ok(vec![(bound_addr, iface)])
        }
    }

    /// Probes and generates potential network paths to the given server endpoints.
    ///
    /// Each endpoint is paired with its DNS [`Source`] so that the correct network
    /// interface can be selected:
    ///
    /// - **Direct endpoints**: selects matching bound interfaces or auto-binds a new one,
    ///   then constructs [`Link`] and [`Pathway`] for each.
    /// - **Agent endpoints**: ensures an interface exists but does **not** build a path —
    ///   the puncher system handles Agent paths after STUN discovery.
    ///
    /// Returns a list of `(Interface, Link, Pathway)` tuples for Direct endpoints only.
    ///
    /// ### Example
    ///
    /// ```no_run
    /// # use dquic::prelude::*;
    /// # use dquic::qresolve::Source;
    /// # async fn example(quic_client: &QuicClient) -> Result<(), Box<dyn std::error::Error>> {
    /// let server_addresses: Vec<_> = tokio::net::lookup_host("genmeta.net:443")
    ///     .await?
    ///     .map(|addr| (Source::System, addr.into()))
    ///     .collect();
    /// let paths = quic_client.probe(server_addresses).await?;
    /// let connection = quic_client.new_connection("genmeta.net");
    /// for (iface, link, pathway) in paths {
    ///     connection.add_path(iface.bind_uri(), link, pathway)?;
    /// }
    /// # Ok(())
    /// # }
    /// ```
    pub async fn probe(
        &self,
        server_eps: impl IntoIterator<Item = (Source, EndpointAddr)>,
    ) -> Result<Vec<(Interface, Link, Pathway)>, BindInterfaceError> {
        let server_eps = server_eps.into_iter().collect::<Vec<_>>();

        let mut paths = vec![];
        for (source, server_ep) in server_eps {
            if matches!(server_ep, EndpointAddr::Agent { .. }) {
                self.ensure_iface_for(&source, &server_ep).await;
            } else {
                let ifaces = self.select_or_bind_ifaces(&source, &server_ep).await?;

                paths.extend(ifaces.into_iter().map(move |(bound_addr, iface)| {
                    let dst = *server_ep;
                    let link = Link::new(bound_addr, dst);
                    let pathway = Pathway::new(bound_addr.into(), server_ep);
                    (iface, link, pathway)
                }));
            }
        }

        Ok(paths)
    }

    /// Processes a single server endpoint for the given connection:
    /// 1. Registers the peer endpoint (with its DNS source) in the connection's address book.
    /// 2. Probes for immediate paths (Direct endpoints) or ensures an interface
    ///    is bound (Agent endpoints).  See [`Self::probe`] for details.
    /// 3. Adds any resulting Direct paths to the connection.
    ///
    /// Returns `true` if at least one Direct path was added.
    async fn setup_server_endpoint(
        &self,
        connection: &Connection,
        source: Source,
        server_ep: EndpointAddr,
    ) -> Result<bool, BindInterfaceError> {
        // Register the peer endpoint with its DNS source — the puncher will
        // only auto-create paths with local endpoints matching the source constraint
        // (e.g. mDNS endpoints are restricted to the discovering NIC).
        _ = connection.add_peer_endpoint(server_ep, source.clone());

        // probe() handles both Direct and Agent uniformly:
        //   Direct → select/bind interface, construct Link & Pathway, return paths.
        //   Agent  → ensure an interface is bound, return empty paths.
        let paths = self.probe([(source, server_ep)]).await?;
        let has_direct_path = !paths.is_empty();
        for (iface, link, pathway) in paths {
            _ = connection.add_path(iface.bind_uri(), link, pathway);
        }
        Ok(has_direct_path)
    }

    /// Connects to a server using specific endpoint addresses.
    ///
    /// This method combines [`QuicClient::probe`] and [`QuicClient::new_connection`].
    /// It creates a connection and automatically adds paths for all the provided
    /// server endpoints.
    ///
    /// The returned [`Connection`] may not have completed the handshake yet.
    /// However, any asynchronous operations on the connection (like opening streams)
    /// will automatically wait for the handshake to complete.
    ///
    /// If `server_eps` is empty, this is equivalent to calling [`QuicClient::new_connection`]
    /// and the connection will remain idle until paths are added.
    ///
    /// This variant preserves the DNS [`Source`] so that the correct network interface
    /// is selected for each endpoint (e.g., mDNS endpoints bind to the discovering NIC).
    pub async fn connected_to_with_source(
        &self,
        server_name: impl Into<String>,
        server_eps: impl IntoIterator<Item = (Source, EndpointAddr)>,
    ) -> Result<Connection, ConnectServerError> {
        let connection = self.new_connection(server_name);
        _ = connection.subscribe_local_address();
        for (source, server_ep) in server_eps {
            self.setup_server_endpoint(&connection, source, server_ep)
                .await
                .map_err(|source| ConnectServerError::BindInterface { source })?;
        }
        Ok(connection)
    }

    /// Connects to a server by its hostname and optional port.
    ///
    /// This is the most convenient way to establish a connection. It performs the following steps:
    /// 1. Parses the server string (e.g., "example.com" or "example.com:443").
    ///    Defaults to port 443 if not specified.
    /// 2. Performs an asynchronous DNS lookup to resolve the hostname to IP addresses.
    /// 3. Calls [`QuicClient::connected_to_with_source`] with the resolved addresses.
    ///
    /// The returned [`Connection`] may not have completed the handshake yet.
    /// Asynchronous operations on the connection will wait for the handshake.
    pub async fn connect(self: &Arc<Self>, server: &str) -> Result<Connection, ConnectServerError> {
        let mut server_eps = self
            .network
            .resolver
            .lookup(server)
            .await
            .map_err(|source| ConnectServerError::Dns { source })?;

        let connection = self.new_connection(server);
        if connection.subscribe_local_address().is_err() {
            // connection already closed, return immediately (not connect error)
            return Ok(connection);
        }

        let mut last_error: Option<ConnectServerError> = None;

        // Consume the DNS stream until we get at least one Direct path,
        // or exhaust all endpoints (Agent-only is acceptable).
        //
        // `last_error` doubles as a "no viable endpoint yet" sentinel:
        // - On `Ok(false)` (Agent registered): clear it — we have a viable fallback.
        // - On `Err`: set/keep it — probe failure, keep looking.
        // - On stream exhaustion: if still `Some`, nothing viable → propagate error.
        while let Some((source, server_ep)) = server_eps.next().await {
            match self
                .setup_server_endpoint(&connection, source, server_ep)
                .await
            {
                Ok(true) => {
                    last_error = None; // Got a Direct path, proceed.
                    break;
                }
                Ok(false) => {
                    // Agent endpoint registered — even if later Direct probes fail,
                    // the puncher can still establish paths asynchronously.
                    last_error = None;
                }
                Err(error) => {
                    last_error.get_or_insert(error.into());
                }
            }
        }
        if let Some(error) = last_error {
            return Err(error);
        }

        // Background task: keep consuming the DNS stream for late-arriving endpoints.
        tokio::spawn({
            let connection = connection.clone();
            let client = self.clone();
            async move {
                while let Some((source, server_ep)) = server_eps.next().await {
                    _ = client
                        .setup_server_endpoint(&connection, source, server_ep)
                        .await;
                }
            }
        });

        Ok(connection)
    }
}

/// Builder for [`QuicClient`].
#[derive(Clone)]
pub struct QuicClientBuilder<T> {
    network: common::Network,

    // client
    bind_ifaces: DashMap<BindUri, BindInterface>,
    manual_bind: bool,
    // client: quic config(in initialize order)
    prefer_versions: Vec<u32>,
    token_sink: Arc<dyn TokenSink>,
    parameters: ClientParameters,
    tls_config: T,
    stream_strategy_factory: Arc<dyn ProductStreamsConcurrencyController>,
    defer_idle_timeout: Duration,
    qlogger: Arc<dyn QLog + Send + Sync>,
}

impl QuicClient {
    /// Create a new [`QuicClient`] builder.
    pub fn builder() -> QuicClientBuilder<TlsClientConfigBuilder<WantsVerifier>> {
        Self::builder_with_tls(TlsClientConfig::builder_with_protocol_versions(&[
            &rustls::version::TLS13,
        ]))
    }

    /// Create a [`QuicClient`] builder with custom crypto provider.
    pub fn builder_with_crypto_provider(
        provider: Arc<rustls::crypto::CryptoProvider>,
    ) -> QuicClientBuilder<TlsClientConfigBuilder<WantsVerifier>> {
        Self::builder_with_tls(
            TlsClientConfig::builder_with_provider(provider)
                .with_protocol_versions(&[&rustls::version::TLS13])
                .unwrap(),
        )
    }

    /// Start to build a QuicClient with the given TLS configuration.
    ///
    /// This is useful when you want to customize the TLS configuration, or integrate qm-quic with other crates.
    pub fn builder_with_tls<T>(tls_config: T) -> QuicClientBuilder<T> {
        QuicClientBuilder {
            // network
            network: common::Network::default(),

            // client
            bind_ifaces: DashMap::new(),
            manual_bind: false,
            // client: quic config(in initialize order)
            prefer_versions: vec![1],
            token_sink: Arc::new(handy::NoopTokenRegistry),
            parameters: handy::client_parameters(),
            tls_config,
            stream_strategy_factory: Arc::new(handy::ConsistentConcurrency::new),
            defer_idle_timeout: Duration::ZERO,
            qlogger: Arc::new(handy::NoopLogger),
        }
    }
}

impl<T> QuicClientBuilder<T> {
    pub fn with_resolver(mut self, resolver: Arc<dyn Resolve + Send + Sync>) -> Self {
        self.network.resolver = resolver;
        self
    }

    pub fn physical_ifaces(mut self, physical_ifaces: &'static Devices) -> Self {
        self.network.devices = physical_ifaces;
        self
    }

    /// Specify how client bind interfaces.
    ///
    /// The given factory will be used by [`Self::bind`],
    /// and/or [`QuicClient::connect`] if no interface bound when client built.
    ///
    /// The default quic interface is provided by [`handy::DEFAULT_IO_FACTORY`].
    /// For Unix and Windows targets, this is a high performance UDP library supporting GSO and GRO
    /// provided by `qudp` crate. For other platforms, please specify you own factory.
    pub fn with_iface_factory(mut self, iface_factory: Arc<dyn ProductIO>) -> Self {
        self.network.iface_factory = iface_factory;
        self
    }

    /// Specify the interfaces manager for the client.
    pub fn with_iface_manager(mut self, iface_manager: Arc<InterfaceManager>) -> Self {
        self.network.iface_manager = iface_manager;
        self
    }

    pub fn with_router(mut self, router: Arc<QuicRouter>) -> Self {
        self.network.quic_router = router;
        self
    }

    pub fn with_stun(mut self, server: impl Into<Arc<str>>) -> Self {
        self.network.stun_server = Some(server.into());
        self
    }

    /// Specify the locations for interface sharing.
    ///
    /// The given locations is shared by all connections created by this client.
    pub fn with_locations(mut self, locations: Arc<Locations>) -> Self {
        self.network.locations = locations;
        self
    }

    /// Create quic interfaces bound on given address.
    ///
    /// If the bind failed, the error will be returned immediately.
    ///
    /// The default quic interface is provided by [`handy::DEFAULT_IO_FACTORY`].
    /// For Unix and Windows targets, this is a high performance UDP library supporting GSO and GRO
    /// provided by `qudp` crate. For other platforms, please specify you own factory with
    /// [`QuicClientBuilder::with_iface_factory`].
    ///
    /// If you dont bind any address, each time the client initiates a new connection,
    /// the client will use bind a new interface on address and port that dynamic assigned by the system.
    ///
    /// To know more about how the client selects the interface when initiates a new connection,
    /// read [`QuicClient::connect`].
    ///
    /// If you call this multiple times, only the last set of interface will be used,
    /// previous bound interface will be freed immediately.
    ///
    /// If all interfaces are closed, clients will no longer be able to initiate new connections.
    pub async fn bind(mut self, bind_uris: impl IntoIterator<Item = impl Into<BindUri>>) -> Self {
        self.bind_ifaces = self
            .network
            .bind_many(bind_uris)
            .await
            .map(|bind_iface| (bind_iface.bind_uri(), bind_iface))
            .collect()
            .await;
        self.manual_bind = true;
        self
    }

    /// (WIP)Specify the quic versions that the client prefers.
    ///
    /// If you call this multiple times, only the last call will take effect.
    pub fn prefer_versions(mut self, versions: impl IntoIterator<Item = u32>) -> Self {
        self.prefer_versions.clear();
        self.prefer_versions.extend(versions);
        self
    }

    /// Specify the token sink for the client.
    ///
    /// The token sink is used to storage the tokens that the client received from the server. The client will use the
    /// tokens to prove it self to the server when it reconnects to the server. read [address verification] in quic rfc
    /// for more information.
    ///
    /// [address verification](https://www.rfc-editor.org/rfc/rfc9000.html#name-address-validation)
    pub fn with_token_sink(self, token_sink: Arc<dyn TokenSink>) -> Self {
        Self { token_sink, ..self }
    }

    /// Specify the [transport parameters] for the client.
    ///
    /// If you call this multiple times, only the last `parameters` will be used.
    ///
    /// Usually, you don't need to call this method, because the client will use a set of default parameters.
    ///
    /// [transport parameters](https://www.rfc-editor.org/rfc/rfc9000.html#name-transport-parameter-definit)
    pub fn with_parameters(self, parameters: ClientParameters) -> Self {
        Self { parameters, ..self }
    }

    fn map_tls<T1>(self, f: impl FnOnce(T) -> T1) -> QuicClientBuilder<T1> {
        QuicClientBuilder {
            network: self.network,
            bind_ifaces: self.bind_ifaces,
            manual_bind: self.manual_bind,
            prefer_versions: self.prefer_versions,
            token_sink: self.token_sink,
            parameters: self.parameters,
            tls_config: f(self.tls_config),
            stream_strategy_factory: self.stream_strategy_factory,
            defer_idle_timeout: self.defer_idle_timeout,
            qlogger: self.qlogger,
        }
    }

    pub fn with_name(mut self, name: impl Into<String>) -> Self {
        self.parameters
            .set(ParameterId::ClientName, name.into())
            .expect("parameter 0xffee belong_to client and has type String");
        self
    }

    /// Provide an option to defer an idle timeout.
    ///
    /// This facility could be used when the application wishes to avoid losing
    /// state that has been associated with an open connection but does not expect
    /// to exchange application data for some time.
    ///
    /// See [Deferring Idle Timeout](https://datatracker.ietf.org/doc/html/rfc9000#name-deferring-idle-timeout)
    /// of [RFC 9000](https://datatracker.ietf.org/doc/html/rfc9000)
    /// for more information.
    pub fn defer_idle_timeout(mut self, duration: Duration) -> Self {
        self.defer_idle_timeout = duration;
        self
    }

    /// Specify the streams concurrency strategy controller for the client.
    ///
    /// The streams controller is used to control the concurrency of data streams. `controller` is a closure that accept
    /// (initial maximum number of bidirectional streams, initial maximum number of unidirectional streams) configured in
    /// [transport parameters] and return a `ControlConcurrency` object.
    ///
    /// If you call this multiple times, only the last `controller` will be used.
    ///
    /// [transport parameters](https://www.rfc-editor.org/rfc/rfc9000.html#name-transport-parameter-definit)
    pub fn with_streams_concurrency_strategy(
        self,
        stream_strategy_factory: Arc<dyn ProductStreamsConcurrencyController>,
    ) -> Self {
        Self {
            stream_strategy_factory,
            ..self
        }
    }

    /// Specify qlog collector for server connections.
    ///
    /// If you call this multiple times, only the last `logger` will be used.
    ///
    /// Pre-implemented loggers:
    /// - [`LegacySeqLogger`]: Generates qlog files compatible with [qvis] visualization.
    ///   - `LegacySeqLogger::new(PathBuf::from("/dir"))`: Write to files `{connection_id}_{role}.sqlog` in `dir`
    ///   - `LegacySeqLogger::new(tokio::io::stdout())`: Stream to stdout
    ///   - `LegacySeqLogger::new(tokio::io::stderr())`: Stream to stderr
    ///
    ///   Output format: JSON-SEQ ([RFC7464]), one JSON event per line.
    ///
    /// - [`handy::NoopLogger`] (default): Ignores all qlog events (default, recommended for production).
    ///
    /// [qvis]: https://qvis.quictools.info/
    /// [RFC7464]: https://www.rfc-editor.org/rfc/rfc7464
    /// [`LegacySeqLogger`]: qevent::telemetry::handy::LegacySeqLogger
    pub fn with_qlog(self, qlogger: Arc<dyn QLog + Send + Sync>) -> Self {
        Self { qlogger, ..self }
    }
}

impl QuicClientBuilder<TlsClientConfigBuilder<WantsVerifier>> {
    /// Choose how to verify server certificates.
    ///
    /// Read [TlsClientConfigBuilder::with_root_certificates] for more information.
    pub fn with_root_certificates(
        self,
        root_store: impl Into<Arc<rustls::RootCertStore>>,
    ) -> QuicClientBuilder<TlsClientConfigBuilder<WantsClientCert>> {
        self.map_tls(|tls_config_builder| tls_config_builder.with_root_certificates(root_store))
    }

    /// Choose how to verify server certificates using a webpki verifier.
    ///
    /// Read [TlsClientConfigBuilder::with_webpki_verifier] for more information.
    pub fn with_webpki_verifier(
        self,
        verifier: Arc<rustls::client::WebPkiServerVerifier>,
    ) -> QuicClientBuilder<TlsClientConfigBuilder<WantsClientCert>> {
        self.map_tls(|tls_config_builder| tls_config_builder.with_webpki_verifier(verifier))
    }

    /// Replace the default server certificate verifier with a custom one.
    ///
    /// This exposes rustls' low-level custom verifier hook. The provided
    /// verifier becomes fully responsible for server certificate validation,
    /// including any WebPKI, OCSP, pinning, or private PKI checks you require.
    pub fn with_custom_server_cert_verifier(
        self,
        verifier: Arc<dyn rustls::client::danger::ServerCertVerifier>,
    ) -> QuicClientBuilder<TlsClientConfigBuilder<WantsClientCert>> {
        self.map_tls(|tls_config_builder| {
            tls_config_builder
                .dangerous()
                .with_custom_certificate_verifier(verifier)
        })
    }

    /// Dangerously disable server certificate verification.
    pub fn without_verifier(self) -> QuicClientBuilder<TlsClientConfigBuilder<WantsClientCert>> {
        #[derive(Debug)]
        struct DangerousServerCertVerifier;

        impl rustls::client::danger::ServerCertVerifier for DangerousServerCertVerifier {
            fn verify_server_cert(
                &self,
                _: &rustls::pki_types::CertificateDer<'_>,
                _: &[rustls::pki_types::CertificateDer<'_>],
                _: &rustls::pki_types::ServerName<'_>,
                _: &[u8],
                _: rustls::pki_types::UnixTime,
            ) -> Result<rustls::client::danger::ServerCertVerified, rustls::Error> {
                Ok(rustls::client::danger::ServerCertVerified::assertion())
            }

            fn verify_tls12_signature(
                &self,
                _: &[u8],
                _: &rustls::pki_types::CertificateDer<'_>,
                _: &rustls::DigitallySignedStruct,
            ) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error>
            {
                Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
            }

            fn verify_tls13_signature(
                &self,
                _: &[u8],
                _: &rustls::pki_types::CertificateDer<'_>,
                _: &rustls::DigitallySignedStruct,
            ) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error>
            {
                Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
            }

            fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
                vec![
                    rustls::SignatureScheme::RSA_PKCS1_SHA1,
                    rustls::SignatureScheme::ECDSA_SHA1_Legacy,
                    rustls::SignatureScheme::RSA_PKCS1_SHA256,
                    rustls::SignatureScheme::ECDSA_NISTP256_SHA256,
                    rustls::SignatureScheme::RSA_PKCS1_SHA384,
                    rustls::SignatureScheme::ECDSA_NISTP384_SHA384,
                    rustls::SignatureScheme::RSA_PKCS1_SHA512,
                    rustls::SignatureScheme::ECDSA_NISTP521_SHA512,
                    rustls::SignatureScheme::RSA_PSS_SHA256,
                    rustls::SignatureScheme::RSA_PSS_SHA384,
                    rustls::SignatureScheme::RSA_PSS_SHA512,
                    rustls::SignatureScheme::ED25519,
                    rustls::SignatureScheme::ED448,
                ]
            }
        }

        self.map_tls(|tls_config_builder| {
            tls_config_builder
                .dangerous()
                .with_custom_certificate_verifier(Arc::new(DangerousServerCertVerifier))
        })
    }
}

impl QuicClientBuilder<TlsClientConfigBuilder<WantsClientCert>> {
    /// Sets a single certificate chain and matching private key for use
    /// in client authentication.
    ///
    /// Read [TlsClientConfigBuilder::with_single_cert] for more information.
    pub fn with_cert(
        self,
        cert: impl handy::ToCertificate,
        key: impl handy::ToPrivateKey,
    ) -> QuicClientBuilder<TlsClientConfig> {
        self.map_tls(|tls_config_builder| {
            tls_config_builder
                .with_client_auth_cert(cert.to_certificate(), key.to_private_key())
                .expect("The private key was wrong encoded or failed validation")
        })
    }

    /// Do not support client auth.
    pub fn without_cert(self) -> QuicClientBuilder<TlsClientConfig> {
        self.map_tls(|tls_config_builder| tls_config_builder.with_no_client_auth())
    }
    /// Sets a custom [`ResolvesClientCert`].
    pub fn with_cert_resolver(
        self,
        cert_resolver: Arc<dyn ResolvesClientCert>,
    ) -> QuicClientBuilder<TlsClientConfig> {
        self.map_tls(|tls_config_builder| {
            tls_config_builder.with_client_cert_resolver(cert_resolver)
        })
    }
}

impl QuicClientBuilder<TlsClientConfig> {
    /// Specify the [alpn-protocol-ids] that will be sent in `ClientHello`.
    ///
    /// By default, its empty and the APLN extension wont be sent.
    ///
    /// If you call this multiple times, all the `alpn_protocol` will be used.
    ///
    /// [alpn-protocol-ids](https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids)
    pub fn with_alpns(mut self, alpns: impl IntoIterator<Item = impl Into<Vec<u8>>>) -> Self {
        self.tls_config
            .alpn_protocols
            .extend(alpns.into_iter().map(Into::into));
        self
    }

    /// Enable the `keylog` feature.
    ///
    /// This is useful when you want to debug the TLS connection.
    ///
    /// The keylog file will be in the file that environment veriable `SSLKEYLOGFILE` pointed to.
    ///
    /// Read [`rustls::KeyLogFile`] for more information.
    pub fn enable_sslkeylog(mut self) -> Self {
        self.tls_config.key_log = Arc::new(rustls::KeyLogFile::new());
        self
    }

    pub fn enable_0rtt(mut self) -> Self {
        self.tls_config.enable_early_data = true;
        self
    }

    /// Build the QuicClient, ready to initiates connect to the servers.
    pub fn build(self) -> QuicClient {
        QuicClient {
            network: self.network,
            bind_ifaces: self.bind_ifaces,
            manual_bind: Arc::new(AtomicBool::new(self.manual_bind)),
            _prefer_versions: self.prefer_versions,
            token_sink: self.token_sink,
            parameters: self.parameters,
            tls_config: self.tls_config,
            stream_strategy_factory: self.stream_strategy_factory,
            defer_idle_timeout: self.defer_idle_timeout,
            qlogger: self.qlogger,
        }
    }
}


================================================
FILE: dquic/src/common.rs
================================================
use std::{net::SocketAddr, sync::Arc};

use futures::{Stream, StreamExt, stream};
use qconnection::{
    prelude::{EndpointAddr, handy},
    qinterface::{
        BindInterface, Interface,
        bind_uri::BindUri,
        component::{
            Components,
            alive::RebindOnNetworkChangedComponent,
            location::{Locations, LocationsComponent},
            route::{QuicRouter, QuicRouterComponent},
        },
        device::Devices,
        io::ProductIO,
        manager::InterfaceManager,
    },
    qtraversal::{
        nat::{client::StunClientsComponent, router::StunRouterComponent},
        route::{ForwardersComponent, ReceiveAndDeliverPacketComponent},
    },
};
use qresolve::{Family, Resolve, SystemResolver};

#[derive(Clone)]
pub struct Network {
    pub resolver: Arc<dyn Resolve + Send + Sync>,
    pub devices: &'static Devices,
    pub iface_factory: Arc<dyn ProductIO>,
    pub iface_manager: Arc<InterfaceManager>,
    pub quic_router: Arc<QuicRouter>,
    pub stun_server: Option<Arc<str>>,
    pub locations: Arc<Locations>,
}

impl Default for Network {
    fn default() -> Self {
        Self {
            resolver: Arc::new(SystemResolver),
            devices: Devices::global(),
            iface_factory: Arc::new(handy::DEFAULT_IO_FACTORY),
            iface_manager: InterfaceManager::global().clone(),
            quic_router: QuicRouter::global().clone(),
            stun_server: None,
            locations: Arc::new(Locations::new()),
        }
    }
}

impl Network {
    /// 只取第一个可用的 STUN agent 即返回,后续由 StunClientsComponent 自动补充到 MIN_AGENTS
    async fn lookup_first_agent(
        &self,
        stun_server: &str,
        family: Family,
    ) -> Option<Vec<SocketAddr>> {
        let stream = self.resolver.lookup(stun_server).await.ok()?;
        let mut stream = std::pin::pin!(stream);
        while let Some((_source, ep)) = stream.next().await {
            let EndpointAddr::Direct { addr } = ep else {
                continue;
            };
            if match family {
                Family::V4 => addr.is_ipv4(),
                Family::V6 => addr.is_ipv6(),
            } {
                tracing::trace!("resolved first stun agent for {stun_server}: {addr}");
                return Some(vec![addr]);
            }
        }
        None
    }

    fn init_iface_components(
        &self,
        bind_iface: &BindInterface,
        stun_agent: Option<(Arc<str>, Vec<SocketAddr>)>,
    ) {
        bind_iface.with_components_mut(move |components: &mut Components, iface: &Interface| {
            // rebind interface on network changed
            components.init_with(|| RebindOnNetworkChangedComponent::new(iface, self.devices));
            // quic packet router
            let quic_router = components
                .init_with(|| QuicRouterComponent::new(self.quic_router.clone()))
                .router();

            let locations = components
                .init_with(|| LocationsComponent::new(iface.downgrade(), self.locations.clone()))
                .clone();

            match stun_agent {
                // stun enabled:
                Some((stun_server, stun_agents)) => {
                    // initial stun router
                    let stun_router = components
                        .init_with(|| StunRouterComponent::new(iface.downgrade()))
                        .router();
                    // initial stun clients (后续会自动补充到 MIN_AGENTS)
                    let clients = components
                        .init_with(|| {
                            StunClientsComponent::new(
                                iface.downgrade(),
                                stun_router.clone(),
                                self.resolver.clone(),
                                stun_server,
                                stun_agents,
                                Some(locations.clone()),
                            )
                        })
                        .clone();
                    // initial forwarder
                    let relay = bind_iface
                        .bind_uri()
                        .relay()
                        .and_then(|r| r.parse::<SocketAddr>().ok());

                    let forwarder = if let Some(relay) = relay {
                        components
                            .init_with(|| ForwardersComponent::new_server(relay))
                            .forwarder()
                    } else {
                        components
                            .init_with(|| ForwardersComponent::new_client(clients))
                            .forwarder()
                    };

                    // initial receive and deliver packet component(quic, stun and forwarder)
                    components.init_with(|| {
                        ReceiveAndDeliverPacketComponent::builder(iface.downgrade())
                            .quic_router(quic_router)
                            .stun_router(stun_router)
                            .forwarder(forwarder)
                            .init()
                    });
                }
                // no stun: receive and deliver quic only
                None => {
                    components.init_with(|| {
                        ReceiveAndDeliverPacketComponent::builder(iface.downgrade())
                            .quic_router(quic_router)
                            .init()
                    });
                }
            };
        });
    }

    pub async fn bind(&self, bind_uri: BindUri) -> BindInterface {
        let stun_server = if let Some(server) = bind_uri.stun_server() {
            Some(Arc::from(server))
        } else if let Some("false") = bind_uri.prop(BindUri::STUN_PROP).as_deref() {
            None
        } else {
            self.stun_server.clone()
        };

        let family = bind_uri.family();
        let stun_agents = match &stun_server {
            Some(server) => self
                .lookup_first_agent(server.as_ref(), family)
                .await
                .unwrap_or_default(),
            None => vec![],
        };

        let factory = self.iface_factory.clone();
        let bind_iface = self.iface_manager.bind(bind_uri, factory).await;
        self.init_iface_components(&bind_iface, stun_server.map(|s| (s, stun_agents)));

        bind_iface
    }

    pub async fn bind_many(
        &self,
        bind_uris: impl IntoIterator<Item = impl Into<BindUri>>,
    ) -> impl Stream<Item = BindInterface> {
        stream::iter(bind_uris).then(async |bind_uri| self.bind(bind_uri.into()).await)
    }
}


================================================
FILE: dquic/src/lib.rs
================================================
#![doc=include_str!("../README.md")]

pub mod prelude {
    pub use ::qconnection;
    pub use qconnection::prelude::*;
    pub use qresolve::Resolve;

    pub use crate::{
        client::{BindInterfaceError, ConnectServerError, QuicClient},
        server::{ListenError, ListenersShutdown, QuicListeners, Server, ServerError},
    };

    pub mod handy {
        pub use qconnection::prelude::handy::*;
        pub use qresolve::SystemResolver;

        pub use crate::cert::{ToCertificate, ToPrivateKey};
    }
}

pub mod builder {
    pub use qconnection::builder::*;

    pub use crate::{client::QuicClientBuilder, server::QuicListenersBuilder};
}

// Hidden modules used to integrate the code examples from the README into the cargo test
mod doc {
    #[doc=include_str!("../README_CN.md")]
    mod zh {}

    // Omitted: Duplicate with crate documentation
    // #[doc=include_str!("../../README.md")]
    // mod en {}
}

pub use ::qconnection::{self, qbase, qdatagram, qevent, qinterface, qrecovery, qtraversal};
pub use ::qresolve;

mod cert;
mod client;
mod common;
mod server;


================================================
FILE: dquic/src/server.rs
================================================
use std::{
    collections::HashMap,
    fmt::Debug,
    io,
    ops::{Deref, DerefMut},
    pin::pin,
    sync::Arc,
    time::Duration,
};

use arc_swap::ArcSwap;
use dashmap::DashMap;
use futures::StreamExt;
use qbase::{
    packet::{DataHeader, GetDcid, Packet, long::DataHeader as LongHeader},
    param::ServerParameters,
    token::TokenProvider,
    util::BoundQueue,
};
use qconnection::{
    self,
    qinterface::{self, bind_uri::BindUri, component::location::Locations, device::Devices},
    tls::AcceptAllClientAuther,
};
use qevent::telemetry::QLog;
use qinterface::{
    BindInterface,
    component::route::{QuicRouter, Way},
    io::ProductIO,
    manager::InterfaceManager,
};
use rustls::{
    ConfigBuilder, ServerConfig as TlsServerConfig, WantsVerifier,
    server::{NoClientAuth, ResolvesServerCert, danger::ClientCertVerifier},
    sign::CertifiedKey,
};
use thiserror::Error;
use tokio::sync::{OwnedSemaphorePermit, Semaphore};
use tracing::Instrument;

use crate::{prelude::*, *};

/// Errors that can occur during server management operations.
#[derive(Debug, thiserror::Error)]
pub enum ServerError {
    /// The server with the specified name already exists.
    #[error("Server '{server}' already exists")]
    ServerAlreadyExists { server: String },

    /// The server with the specified name was not found.
    #[error("Server '{server}' not found")]
    ServerNotFound { server: String },

    /// Failed to load the private key for the server.
    #[error("Failed to load private key for server '{server}': {source}")]
    InvalidCertOrKey {
        server: String,
        #[source]
        source: rustls::Error,
    },
}

impl From<ServerError> for io::Error {
    fn from(error: ServerError) -> Self {
        let kind = match &error {
            ServerError::ServerAlreadyExists { .. } => io::ErrorKind::AlreadyExists,
            ServerError::ServerNotFound { .. } => io::ErrorKind::NotFound,
            ServerError::InvalidCertOrKey { .. } => io::ErrorKind::InvalidInput,
        };
        io::Error::new(kind, error)
    }
}

/// Errors that can occur during QuicListeners builder creation.
#[derive(Debug, thiserror::Error)]
pub enum ListenError {
    /// A QuicListeners instance is already running globally.
    #[error("A QuicListeners is already running on the router")]
    AlreadyRunning,
}

impl From<ListenError> for io::Error {
    fn from(error: ListenError) -> Self {
        match error {
            ListenError::AlreadyRunning => io::Error::new(io::ErrorKind::AlreadyExists, error),
        }
    }
}

type TlsServerConfigBuilder<T> = ConfigBuilder<TlsServerConfig, T>;

#[derive(Debug, Default)]
pub struct VirtualHosts(Arc<DashMap<String, Server>>);

impl ResolvesServerCert for VirtualHosts {
    fn resolve(&self, client_hello: rustls::server::ClientHello) -> Option<Arc<CertifiedKey>> {
        self.0
            .get(client_hello.server_name()?)
            .map(|server| server.certified_key())
    }
}

pub struct Server {
    network: common::Network,
    bind_ifaces: DashMap<BindUri, BindInterface>,
    // todo: [update] change to LocalAgent
    certified_key: ArcSwap<CertifiedKey>,
}

impl std::fmt::Debug for Server {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("Server")
            .field("bind_ifaces", &self.bind_ifaces)
            .field("certified_key", &self.certified_key())
            .finish()
    }
}

impl Server {
    pub fn bind_interfaces(&self) -> HashMap<BindUri, BindInterface> {
        self.bind_ifaces
            .iter()
            .map(|entry| (entry.key().clone(), entry.value().clone()))
            .collect()
    }

    pub async fn bind(&self, bind_uris: impl IntoIterator<Item = impl Into<BindUri>>) {
        let mut bind_ifaces = pin!(self.network.bind_many(bind_uris).await);
        while let Some(bind_iface) = bind_ifaces.next().await {
            self.bind_ifaces.insert(bind_iface.bind_uri(), bind_iface);
        }
    }

    pub fn get_iface(&self, bind_uri: &BindUri) -> Option<BindInterface> {
        self.bind_ifaces
            .get(bind_uri)
            .map(|iface| iface.value().clone())
    }

    pub fn remove_iface(&self, bind_uri: &BindUri) -> Option<BindInterface> {
        self.bind_ifaces.remove(bind_uri).map(|entry| entry.1)
    }

    pub fn certified_key(&self) -> Arc<CertifiedKey> {
        self.certified_key.load_full()
    }

    pub fn update_ocsp(&self, ocsp: Option<Vec<u8>>) {
        self.certified_key.rcu(|current| CertifiedKey {
            cert: current.cert.clone(),
            key: current.key.clone(),
            ocsp: ocsp.clone(),
        });
    }
}

type Incomings = BoundQueue<((Connection, String, Pathway, Link), OwnedSemaphorePermit)>;

/// A QUIC listener that can serve multiple virtual servers, accepting incoming connections.
///
/// ## Creating Listeners
///
/// Use [`QuicListenersBuilder`] to configure the listener, then call [`QuicListenersBuilder::listen`]
/// to start accepting connections.
///
/// **Note**: Only one [`QuicListeners`] instance can run at a time globally.
/// To stop the listeners, call [`QuicListeners::shutdown`] or drop all references to the [`Arc<QuicListeners>`].
///
/// ## Managing Servers
///
/// Add multiple virtual servers by calling [`QuicListeners::add_server`] multiple times.
/// Each server is identified by its server name (SNI) and handles connections independently.
///
/// - Servers can share the same network interfaces
/// - Servers can be added without initially binding to any interface
///
/// ## Connection Handling
///
/// Call [`QuicListeners::accept`] to receive incoming connections. The listener automatically:
/// - Routes connections to the appropriate server based on SNI (Server Name Indication)
/// - Rejects connections if the target server isn't listening on the receiving interface
/// - Returns connections that may still be completing their QUIC handshake
#[derive(Clone)]
pub struct QuicListeners {
    network: common::Network,

    // server
    servers: Arc<DashMap<String, Server>>, // must be empty while building
    incomings: Arc<Incomings>,             // identify the building QuicListeners
    backlog: Arc<Semaphore>,               // limit the number of concurrent connections
    // server: quic config(in initialize order)
    _supported_versions: Vec<u32>,
    token_provider: Arc<dyn TokenProvider>,
    parameters: ServerParameters,
    anti_port_scan: bool,
    client_auther: Arc<dyn AuthClient>,
    tls_config: TlsServerConfig,
    stream_strategy_factory: Arc<dyn ProductStreamsConcurrencyController>,
    defer_idle_timeout: Duration,
    qlogger: Arc<dyn QLog + Send + Sync>,
}

impl QuicListeners {
    /// Add a virtual server with its certificate chain and private key.
    ///
    /// Creates a new virtual host identified by its server name (SNI). The server will use the
    /// certificate chain and private key that matches the SNI in the client's `ClientHello` message.
    /// If no matching server is found, the connection will be rejected.
    ///
    /// A server can be added without binding to any interface initially, but will not accept
    /// connections until interfaces are added via [`bind`]. This allows flexible
    /// server configuration and hot-swapping of network bindings.
    ///
    /// [`bind`]: Server::bind
    pub async fn add_server(
        &self,
        server_name: impl Into<String>,
        cert_chain: impl handy::ToCertificate,
        private_key: impl handy::ToPrivateKey,
        bind_uris: impl IntoIterator<Item = impl Into<BindUri>>,
        ocsp: impl Into<Option<Vec<u8>>>,
    ) -> Result<(), ServerError> {
        let server = server_name.into();

        let server_entry = match self.servers.entry(server.clone()) {
            dashmap::Entry::Vacant(entry) => entry,
            dashmap::Entry::Occupied(..) => {
                return Err(ServerError::ServerAlreadyExists { server });
            }
        };

        let cert = cert_chain.to_certificate();
        let key = self
            .tls_config
            .crypto_provider()
            .key_provider
            .load_private_key(private_key.to_private_key())
            .map_err(|e| ServerError::InvalidCertOrKey {
                server: server.clone(),
                source: e,
            })?;
        let ocsp = ocsp.into();
        let certified_key = CertifiedKey { cert, key, ocsp };

        certified_key
            .keys_match()
            .map_err(|source| ServerError::InvalidCertOrKey {
                server: server.clone(),
                source,
            })?;
        let certified_key = Arc::new(certified_key);

        let bind_uris = bind_uris.into_iter();

        let server = Server {
            network: self.network.clone(),
            bind_ifaces: DashMap::with_capacity(bind_uris.size_hint().0),
            certified_key: ArcSwap::new(certified_key),
        };
        server.bind(bind_uris).await;
        server_entry.insert(server);

        Ok(())
    }

    /// Remove a virtual server and all its associated interfaces.
    ///
    /// Completely removes a server from the listeners, including all network interfaces
    /// it was bound to (if the interface is not used by other servers).
    /// This is the inverse operation of [`add_server`] and provides a clean
    /// way to decommission a virtual host.
    ///
    /// Returns `true` if the server existed and was removed, `false` if no server with the
    /// specified name was found. You must remove an existing server before adding a new
    /// one with the same name.
    ///
    /// [`add_server`]: QuicListeners::add_server
    pub fn remove_server(&self, server_name: &str) -> bool {
        self.servers.remove(server_name).is_some()
    }

    /// Get the server by its name.
    pub fn get_server<'l>(&'l self, server_name: &str) -> Option<impl Deref<Target = Server> + 'l> {
        self.servers.get(server_name)
    }

    /// Get a mutable reference to the server by its name.
    pub fn get_server_mut<'l>(
        &'l self,
        server_name: &str,
    ) -> Option<impl DerefMut<Target = Server> + 'l> {
        self.servers.get_mut(server_name)
    }

    pub fn servers(&self) -> Vec<String> {
        self.servers
            .iter()
            .map(|entry| entry.key().clone())
            .collect()
    }
}

#[derive(Debug, Error, Clone, Copy)]
#[error("Listeners shutdown")]
pub struct ListenersShutdown;

impl QuicListeners {
    /// Accept an incoming QUIC connection from the queue.
    ///
    /// Returns the connection, connected server name, and network path information.
    /// Connections are automatically routed based on SNI (Server Name Indication).
    ///
    /// The connection queue size is limited by the `backlog` parameter in [`QuicListenersBuilder::listen`].
    /// When the queue is full, new incoming packets may be dropped at the network level.
    pub async fn accept(&self) -> Result<(Connection, String, Pathway, Link), ListenersShutdown> {
        self.incomings
            .recv()
            .await
            .ok_or(ListenersShutdown)
            .map(|(i, ..)| i)
    }

    /// Close the QuicListeners, stops accepting new connections.
    ///
    /// Unaccepted connections will be closed
    pub fn shutdown(&self) {
        self.incomings.close();
        self.backlog.close();
    }
}

impl Drop for QuicListeners {
    fn drop(&mut self) {
        self.shutdown();
    }
}

struct ServerAuther {
    anti_port_scan: bool,
    iface: BindUri,
    servers: Arc<DashMap<String, Server>>,
}

impl AuthClient for ServerAuther {
    fn verify_client_name(
        &self,
        server_agent: &LocalAgent,
        _: Option<&str>,
    ) -> ClientNameVerifyResult {
        match self
            .servers
            .get(server_agent.name())
            .is_some_and(|server| server.bind_ifaces.contains_key(&self.iface))
        {
            true => ClientNameVerifyResult::Accept,
            false if self.anti_port_scan => ClientNameVerifyResult::SilentRefuse("".to_owned()),
            false => ClientNameVerifyResult::Refuse("".to_owned()),
        }
    }

    fn verify_client_agent(&self, _: &LocalAgent, _: &RemoteAgent) -> ClientAgentVerifyResult {
        ClientAgentVerifyResult::Accept
    }
}

// internal methods
impl QuicListeners {
    #[tracing::instrument(
        target = "quic_listeners", level = "debug", skip_all, 
        fields(%bind_uri, %pathway, %link, odcid=tracing::field::Empty, server_name=tracing::field::Empty)
    )]
    pub(crate) fn try_accept_connection(&self, packet: Packet, (bind_uri, pathway, link): Way) {
        let origin_dcid = match &packet {
            Packet::Data(data_packet) => match &data_packet.header {
                DataHeader::Long(LongHeader::Initial(hdr)) => *hdr.dcid(),
                DataHeader::Long(LongHeader::ZeroRtt(hdr)) => *hdr.dcid(),
                _ => return,
            },
            _ => return,
        };
        tracing::Span::current().record("odcid", origin_dcid.to_string());

        if origin_dcid.is_empty() {
            tracing::debug!(target: "quic_listeners", "Received an initial/0rtt packet with empty destination CID, ignoring it");
            return;
        }

        // Acquire a permit from the backlog semaphore to limit the number of concurrent connections.
        let Ok(premit) = self.backlog.clone().try_acquire_owned() else {
            tracing::debug!(target: "quic_listeners", "Backlog full, dropping incoming packet");
            return;
        };

        let server_auther = ServerAuther {
            anti_port_scan: self.anti_port_scan,
            iface: bind_uri.clone(),
            servers: self.servers.clone(),
        };

        let connection = Connection::new_server(self.token_provider.clone())
            .with_parameters(self.parameters.clone())
            .with_client_auther(Box::new((server_auther, self.client_auther.clone())))
            .with_tls_config(self.tls_config.clone())
            .with_streams_concurrency_strategy(self.stream_strategy_factory.as_ref())
            .with_zero_rtt(self.tls_config.max_early_data_size == 0xffffffff)
            .with_defer_idle_timeout(self.defer_idle_timeout)
            .with_iface_factory(self.network.iface_factory.clone())
            .with_iface_manager(self.network.iface_manager.clone())
            .with_quic_router(self.network.quic_router.clone())
            .with_locations(self.network.locations.clone())
            // todo
            // .with_stun_servers()
            .with_cids(origin_dcid)
            .with_qlog(self.qlogger.clone())
            .run();

        let incomings = self.incomings.clone();
        let quic_router = self.network.quic_router.clone();

        let try_accept_connection = async move {
            quic_router.deliver(packet, (bind_uri, pathway, link)).await;

            match connection.server_name().await {
                Ok(server_name) => {
                    tracing::Span::current().record("server_name", &server_name);
                    _ = connection.subscribe_local_address();
                    let incoming = (connection, server_name, pathway, link);
                    match incomings.send((incoming, premit)).await {
                        Ok(..) => {
                            tracing::debug!(target: "quic_listeners", "Accepted incoming connection")
                        }
                        Err(..) => {
                            tracing::debug!(target: "quic_listeners", "Listeners is shutdown, closing incoming connection")
                        }
                    }
                }
                Err(error) => {
                    tracing::debug!(
                        target: "quic_listeners",
                        "Failed to accept connection: {error}",
                    );
                }
            }
        };
        // Task completes after a single accept-notify cycle; no explicit join needed.
        tokio::spawn(try_accept_connection.in_current_span());
    }
}

/// The builder for the quic listeners.
#[derive(Clone)]
pub struct QuicListenersBuilder<T> {
    // network
    network: common::Network,

    // server
    servers: Arc<DashMap<String, Server>>, // must be empty while building
    incomings: Arc<Incomings>,             // identify the building QuicListeners
    // server: quic config(in initialize order)
    supported_versions: Vec<u32>,
    token_provider: Arc<dyn TokenProvider>,
    parameters: ServerParameters,
    anti_port_scan: bool,
    client_auther: Arc<dyn AuthClient>,
    tls_config: T,
    stream_strategy_factory: Arc<dyn ProductStreamsConcurrencyController>,
    defer_idle_timeout: Duration,
    qlogger: Arc<dyn QLog + Send + Sync>,
}

impl QuicListeners {
    /// Start to build a [`QuicListeners`].
    pub fn builder() -> QuicListenersBuilder<TlsServerConfigBuilder<WantsVerifier>> {
        Self::builder_with_tls(TlsServerConfig::builder_with_protocol_versions(&[
            &rustls::version::TLS13,
        ]))
    }

    /// Start to build a QuicServer with the given tls crypto provider.
    pub fn builder_with_crypto_provider(
        provider: Arc<rustls::crypto::CryptoProvider>,
    ) -> Result<QuicListenersBuilder<TlsServerConfigBuilder<WantsVerifier>>, rustls::Error> {
        Ok(Self::builder_with_tls(
            TlsServerConfig::builder_with_provider(provider)
                .with_protocol_versions(&[&rustls::version::TLS13])?,
        ))
    }

    /// Start to build a [`QuicListeners`] with the given TLS configuration.
    ///
    /// This is useful when you want to customize the TLS configuration, or integrate qm-quic with other crates.
    pub fn builder_with_tls<T>(tls_config: T) -> QuicListenersBuilder<T> {
        QuicListenersBuilder {
            // network
            network: common::Network::default(),

            // server
            servers: Arc::new(DashMap::new()), // must be empty while building
            incomings: Arc::new(BoundQueue::new(8)), // identify the building QuicListeners
            // server: quic config(in initialize order)
            supported_versions: vec![1],
            token_provider: Arc::new(handy::NoopTokenRegistry),
            parameters: handy::server_parameters(),
            anti_port_scan: false,
            client_auther: Arc::new(AcceptAllClientAuther),
            tls_config,
            stream_strategy_factory: Arc::new(handy::ConsistentConcurrency::new),
            defer_idle_timeout: Duration::ZERO,
            qlogger: Arc::new(handy::NoopLogger),
        }
    }
}

impl<T> QuicListenersBuilder<T> {
    pub fn with_resolver(mut self, resolver: Arc<dyn Resolve + Send + Sync>) -> Self {
        self.network.resolver = resolver;
        self
    }

    pub fn with_physical_ifaces(mut self, physical_ifaces: &'static Devices) -> Self {
        self.network.devices = physical_ifaces;
        self
    }

    /// Specify how hosts bind to the interface.
    ///
    /// If you call this multiple times, only the last `factory` will be used.
    ///
    /// The default quic interface is provided by [`handy::DEFAULT_IO_FACTORY`].
    /// For Unix and Windows targets, this is a high performance UDP library supporting GSO and GRO
    /// provided by `qudp` crate. For other platforms, please specify you own factory.
    pub fn with_iface_factory(mut self, iface_factory: Arc<dyn ProductIO + 'static>) -> Self {
        self.network.iface_factory = iface_factory;
        self
    }

    pub fn with_iface_manager(mut self, iface_manager: Arc<InterfaceManager>) -> Self {
        self.network.iface_manager = iface_manager;
        self
    }

    /// Specify the router to use for the listeners.
    ///
    /// Packets received from the interface bound to the server will be deliver this router,
    /// connectless packets (maybe incoming client connection) will be delivered to QuicListeners.
    ///
    /// A router can only be listened to by one QuicListener,
    /// or the [`QuicListenersBuilder::listen`] will fail.
    pub fn with_router(mut self, router: Arc<QuicRouter>) -> Self {
        self.network.quic_router = router;
        self
    }

    pub fn with_stun(mut self, stun_server: impl Into<Arc<str>>) -> Self {
        self.network.stun_server = Some(stun_server.into());
        self
    }

    /// Specify the locations for interface sharing.
    ///
    /// The given locations is shared by all connections created by this listeners.
    pub fn with_locations(mut self, locations: Arc<Locations>) -> Self {
        self.network.locations = locations;
        self
    }

    /// (WIP)Specify the supported quic versions.
    ///
    /// If you call this multiple times, only the last call will take effect.
    pub fn with_supported_versions(mut self, versions: impl IntoIterator<Item = u32>) -> Self {
        self.supported_versions.clear();
        self.supported_versions.extend(versions);
        self
    }

    /// Specify how server to create and verify the client's Token in [address verification].
    ///
    /// If you call this multiple times, only the last `token_provider` will be used.
    ///
    /// [address verification](https://www.rfc-editor.org/rfc/rfc9000.html#name-address-validation)
    pub fn with_token_provider(self, token_provider: Arc<dyn TokenProvider>) -> Self {
        Self {
            token_provider,
            ..self
        }
    }

    /// Specify the [transport parameters] for the server connections.
    ///
    /// If you call this multiple times, only the last `parameters` will be used.
    ///
    /// Usually, you don't need to call this method, because the server will use a set of default parameters.
    ///
    /// [transport parameters](https://www.rfc-editor.org/rfc/rfc9000.html#name-transport-parameter-definit)
    pub fn with_parameters(mut self, parameters: ServerParameters) -> Self {
        self.parameters = parameters;
        self
    }

    /// Enable anti-port scanning protection.
    ///
    /// When anti-port scanning protection is enabled, the server will silently drop connections
    /// that fail validation (e.g., invalid ClientHello, authentication failures)
    /// without sending any response packets.
    ///
    /// This security feature provides the following benefits:
    /// - Prevents attackers from detecting server presence through port scanning
    /// - Reduces the attack surface by not revealing server configuration details
    /// - Protects against network reconnaissance and probing attacks
    /// - Makes the server appear "offline" to unauthorized connection attempts
    ///
    /// **Security Note:** This feature should be used carefully as it may make
    /// debugging connection issues more difficult. Consider using it in production
    /// environments where security is prioritized over observability.
    ///
    /// **Tip:** For enhanced security, combine this with [`with_client_auther`] to implement
    /// custom authentication logic while maintaining stealth behavior for failed connections.
    ///
    /// Default: disabled
    ///
    /// [`with_client_auther`]: QuicListenersBuilder::with_client_auther
    pub fn enable_anti_port_scan(mut self) -> Self {
        self.anti_port_scan = true;
        self
    }

    /// Specify custom client authentication handlers for the server.
    ///
    /// Client authers are used to perform additional validation beyond standard TLS
    /// certificate verification. They can verify server names, client parameters,
    /// and client certificates according to custom business logic.
    ///
    /// Each [`AuthClient`] implementation provides three verification methods:
    /// - `verify_server_name()`: Validates the requested server name (SNI)
    /// - `verify_client_params()`: Validates client QUIC transport parameters
    /// - `verify_client_certs()`: Validates client certificate chains
    ///
    /// All provided authers must approve the connection for it to be accepted.
    /// If any auther rejects the connection, it will be dropped.
    ///
    /// If you call this multiple times, only the last `client_auther` will be used.
    ///
    /// **Security Enhancement:** When combined with [`enable_anti_port_scan`],
    /// failed authentication attempts will be silently dropped without any response,
    /// providing enhanced security against reconnaissance attacks.
    ///
    /// **TLS Protocol Note:** Certificate verification failures during the TLS handshake
    /// will still send error responses to clients, as the server has already sent
    /// its `ServerHello` message at that point. The stealth behavior only applies to
    /// earlier validation failures that occur before the TLS handshake begins.
    ///
    /// **Built-in Validation:** The server automatically verifies that the interface
    /// receiving the client connection is configured to listen for the requested
    /// server name (SNI). This built-in validation ensures proper routing of
    /// connections to their intended hosts.
    ///
    /// Default: empty (only built-in host and interface validation)
    ///
    /// [`AuthClient`]: qconnection::tls::AuthClient
    /// [`enable_anti_port_scan`]: QuicListenersBuilder::enable_anti_port_scan
    pub fn with_client_auther(mut self, client_auther: impl AuthClient + 'static) -> Self {
        self.client_auther = Arc::new(client_auther);
        self
    }

    fn map_tls<T1>(self, f: impl FnOnce(T) -> T1) -> QuicListenersBuilder<T1> {
        QuicListenersBuilder {
            network: self.network,
            servers: self.servers,
            incomings: self.incomings,
            supported_versions: self.supported_versions,
            token_provider: self.token_provider,
            parameters: self.parameters,
            anti_port_scan: self.anti_port_scan,
            client_auther: self.client_auther,
            tls_config: f(self.tls_config),
            stream_strategy_factory: self.stream_strategy_factory,
            defer_idle_timeout: self.defer_idle_timeout,
            qlogger: self.qlogger,
        }
    }

    /// Specify the factory which product the streams concurrency strategy controller for the server.
    ///
    /// The streams controller is used to control the concurrency of data streams.
    /// Take a look of [`ControlStreamsConcurrency`] for more information.
    ///
    /// If you call this multiple times, only the last `controller` will be used.
    pub fn with_streams_concurrency_strategy(
        self,
        stream_strategy_factory: Arc<dyn ProductStreamsConcurrencyController>,
    ) -> Self {
        Self {
            stream_strategy_factory,
            ..self
        }
    }

    /// Provide an option to defer an idle timeout.
    ///
    /// This facility could be used when the application wishes to avoid losing
    /// state that has been associated with an open connection but does not expect
    /// to exchange application data for some time.
    ///
    /// See [Deferring Idle Timeout](https://datatracker.ietf.org/doc/html/rfc9000#name-deferring-idle-timeout)
    /// of [RFC 9000](https://datatracker.ietf.org/doc/html/rfc9000)
    /// for more information.
    pub fn defer_idle_timeout(mut self, duration: Duration) -> Self {
        self.defer_idle_timeout = duration;
        self
    }

    /// Specify qlog collector for server connections.
    ///
    /// If you call this multiple times, only the last `logger` will be used.
    ///
    /// Pre-implemented loggers:
    /// - [`LegacySeqLogger`]: Generates qlog files compatible with [qvis] visualization.
    ///   - `LegacySeqLogger::new(PathBuf::from("/dir"))`: Write to files `{connection_id}_{role}.sqlog` in `dir`
    ///   - `LegacySeqLogger::new(tokio::io::stdout())`: Stream to stdout
    ///   - `LegacySeqLogger::new(tokio::io::stderr())`: Stream to stderr
    ///
    ///   Output format: JSON-SEQ ([RFC7464]), one JSON event per line.
    ///
    /// - [`handy::NoopLogger`] (default): Ignores all qlog events (default, recommended for production).
    ///
    /// [qvis]: https://qvis.quictools.info/
    /// [RFC7464]: https://www.rfc-editor.org/rfc/rfc7464
    /// [`LegacySeqLogger`]: qevent::telemetry::handy::LegacySeqLogger
    pub fn with_qlog(self, qlogger: Arc<dyn QLog + Send + Sync>) -> Self {
        Self { qlogger, ..self }
    }
}

impl QuicListenersBuilder<TlsServerConfigBuilder<WantsVerifier>> {
    /// Choose how to verify client certificates.
    pub fn with_client_cert_verifier(
        self,
        client_cert_verifier: Arc<dyn ClientCertVerifier>,
    ) -> QuicListenersBuilder<TlsServerConfig> {
        let virtual_servers = Arc::new(VirtualHosts(self.servers.clone()));
        self.map_tls(|tls_config_builder| {
            tls_config_builder
                .with_client_cert_verifier(client_cert_verifier)
                .with_cert_resolver(virtual_servers)
        })
    }

    /// Disable client authentication.
    pub fn without_client_cert_verifier(self) -> QuicListenersBuilder<TlsServerConfig> {
        let virtual_servers = Arc::new(VirtualHosts(self.servers.clone()));
        self.map_tls(|tls_config_builder| {
            tls_config_builder
                .with_client_cert_verifier(Arc::new(NoClientAuth))
                .with_cert_resolver(virtual_servers)
        })
    }
}

impl QuicListenersBuilder<TlsServerConfig> {
    /// Specify the [alpn-protocol-ids] that the server supports.
    ///
    /// If you call this multiple times, all the `alpn_protocol` will be used.
    ///
    /// If you never call this method, we will not do ALPN with the client.
    ///
    /// [alpn-protocol-ids](https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids)
    pub fn with_alpns(mut self, alpn: impl IntoIterator<Item = impl Into<Vec<u8>>>) -> Self {
        self.tls_config
            .alpn_protocols
            .extend(alpn.into_iter().map(Into::into));
        self
    }

    pub fn enable_0rtt(mut self) -> Self {
        // The TLS early_data extension in the NewSessionTicket message is defined to convey (in the
        // max_early_data_size parameter) the amount of TLS 0-RTT data the server is willing to accept. QUIC does not
        // use TLS early data. QUIC uses 0-RTT packets to carry early data. Accordingly, the max_early_data_size
        // parameter is repurposed to hold a sentinel value 0xffffffff to indicate that the server is willing to accept QUIC
        // 0-RTT data. To indicate that the server does not accept 0-RTT data, the early_data extension is omitted from
        // the NewSessionTicket. The amount of data that the client can send in QUIC 0-RTT is controlled by the
        // initial_max_data transport parameter supplied by the server.
        self.tls_config.max_early_data_size = 0xffffffff;
        self
    }

    /// Start listening for incoming connections.
    ///
    /// The `backlog` parameter has the same meaning as the backlog parameter of the UNIX listen function,
    /// which is the maximum number of pending connections that can be queued.
    /// If the queue is full, new initial packets may be dropped.
    ///
    /// Panic if `backlog` is 0.
    pub fn listen(self, backlog: usize) -> Result<Arc<QuicListeners>, ListenError> {
        assert!(backlog > 0, "backlog must be greater than 0");
        debug_assert!(self.servers.is_empty());

        let quic_router = self.network.quic_router.clone();

        let quic_listeners = Arc::new(QuicListeners {
            network: self.network,
            servers: self.servers,
            incomings: self.incomings,
            backlog: Arc::new(Semaphore::new(backlog)),
            _supported_versions: self.supported_versions,
            token_provider: self.token_provider,
            parameters: self.parameters,
            anti_port_scan: self.anti_port_scan,
            client_auther: self.client_auther,
            tls_config: self.tls_config,
            stream_strategy_factory: self.stream_strategy_factory,
            defer_idle_timeout: self.defer_idle_timeout,
            qlogger: self.qlogger,
        });

        // TODO: optimize init order
        let listeners = quic_listeners.clone();
        if !quic_router.on_connectless_packets(move |packet, way| {
            listeners.try_accept_connection(packet, way);
        }) {
            return Err(ListenError::AlreadyRunning);
        }

        Ok(quic_listeners)
    }
}


================================================
FILE: dquic/tests/auth.rs
================================================
use std::{future::Future, sync::Arc, time::Duration};

use dquic::{
    prelude::{handy::*, *},
    qbase,
    qresolve::Source,
};
use qbase::param::ServerParameters;
use qconnection::qinterface::{bind_uri::BindUri, component::route::QuicRouter};
use rustls::{
    pki_types::{CertificateDer, pem::PemObject},
    server::WebPkiClientVerifier,
};
use tokio::{
    io::{AsyncReadExt, AsyncWriteExt},
    time,
};
use tokio_util::task::AbortOnDropHandle;

mod common;
use common::*;
mod echo_common;
use echo_common::*;

#[test]
fn client_without_verify() -> Result<(), BoxError> {
    run(async {
        let router = Arc::new(QuicRouter::default());
        let (listeners, server_task) =
            launch_echo_server(router.clone(), server_parameters()).await?;
        let _server_task = AbortOnDropHandle::new(tokio::spawn(server_task));

        let server_addr = get_server_addr(&listeners);

        let client = {
            let parameters = client_parameters();
            let client = QuicClient::builder()
                .with_router(router)
                .without_verifier()
                .with_parameters(parameters)
                .without_cert()
                .with_qlog(qlogger())
                .enable_sslkeylog()
                .build();
            Arc::new(client)
        };

        let connection = client
            .connected_to_with_source("localhost", [(Source::System, server_addr.into())])
            .await?;
        send_and_verify_echo(&connection, TEST_DATA).await?;

        listeners.shutdown();
        Ok(())
    })
}

struct ClientNameAuther<const SILENT_REFUSE: bool>;

impl<const SILENT: bool> AuthClient for ClientNameAuther<SILENT> {
    fn verify_client_name(
        &self,
        _: &LocalAgent,
        client_name: Option<&str>,
    ) -> ClientNameVerifyResult {
        match matches!(client_name, Some("client")) {
            true => ClientNameVerifyResult::Accept,
            false if !SILENT => ClientNameVerifyResult::Refuse("".to_owned()),
            false => ClientNameVerifyResult::SilentRefuse("Client name ".to_owned()),
        }
    }

    fn verify_client_agent(&self, _: &LocalAgent, _: &RemoteAgent) -> ClientAgentVerifyResult {
        ClientAgentVerifyResult::Accept
    }
}

async fn launch_client_auth_test_server<const SILENT_REFUSE: bool>(
    quic_router: Arc<QuicRouter>,
    server_parameters: ServerParameters,
) -> Result<(Arc<QuicListeners>, impl Future<Output: Send>), BoxError> {
    let mut roots = rustls::RootCertStore::empty();
    roots.add_parsable_certificates(CertificateDer::pem_slice_iter(CA_CERT).map(Result::unwrap));
    let listeners = QuicListeners::builder()
        .with_router(quic_router)
        .with_client_cert_verifier(
            WebPkiClientVerifier::builder(Arc::new(roots))
                .build()
                .unwrap(),
        )
        .with_client_auther(ClientNameAuther::<SILENT_REFUSE>)
        .with_parameters(server_parameters)
        .with_qlog(qlogger())
        .listen(128)?;
    listeners
        .add_server(
            "localhost",
            SERVER_CERT,
            SERVER_KEY,
            [BindUri::from("inet://127.0.0.1:0").alloc_port()],
            None,
        )
        .await?;
    Ok((listeners.clone(), serve_echo(listeners)))
}

#[test]
fn auth_client_name() -> Result<(), BoxError> {
    run(async {
        const SILENT_REFUSE: bool = false;

        let router = Arc::new(QuicRouter::default());
        let (listeners, server_task) =
            launch_client_auth_test_server::<SILENT_REFUSE>(router.clone(), server_parameters())
                .await?;
        let _server_task = AbortOnDropHandle::new(tokio::spawn(server_task));
        let server_addr = get_server_addr(&listeners);

        let client = {
            let mut roots = rustls::RootCertStore::empty();
            roots.add_parsable_certificates(
                CertificateDer::pem_slice_iter(CA_CERT).map(Result::unwrap),
            );
            let client = QuicClient::builder()
                .with_router(router)
                .with_root_certificates(roots)
                .with_parameters(client_parameters())
                .with_cert(CLIENT_CERT, CLIENT_KEY)
                .with_name("client")
                .with_qlog(qlogger())
                .enable_sslkeylog()
                .build();

            Arc::new(client)
        };
        let connection = client
            .connected_to_with_source("localhost", [(Source::System, server_addr.into())])
            .await?;
        send_and_verify_echo(&connection, TEST_DATA).await?;

        listeners.shutdown();
        Ok(())
    })
}

#[test]
fn auth_client_name_incorrect_name() -> Result<(), BoxError> {
    run(async {
        const SILENT_REFUSE: bool = false;

        let router = Arc::new(QuicRouter::default());
        let (listeners, server_task) =
            launch_client_auth_test_server::<SILENT_REFUSE>(router.clone(), server_parameters())
                .await?;
        let _server_task = AbortOnDropHandle::new(tokio::spawn(server_task));
        let server_addr = get_server_addr(&listeners);

        let client = {
            let mut roots = rustls::RootCertStore::empty();
            roots.add_parsable_certificates(
                CertificateDer::pem_slice_iter(CA_CERT).map(Result::unwrap),
            );
            let client = QuicClient::builder()
                .with_router(router)
                .with_root_certificates(roots)
                .with_parameters(client_parameters())
                .with_cert(CLIENT_CERT, CLIENT_KEY)
                .with_name("wrong_name")
                .with_qlog(qlogger())
                .enable_sslkeylog()
                .build();

            Arc::new(client)
        };
        let connection = client
            .connected_to_with_source("localhost", [(Source::System, server_addr.into())])
            .await?;
        let error = connection.terminated().await;
        // TODO: 偶尔以NoViablePath结束,需要调查原因
        assert_eq!(error.kind(), ErrorKind::ConnectionRefused);

        listeners.shutdown();
        Ok(())
    })
}

#[test]
fn auth_client_refuse() -> Result<(), BoxError> {
    run(async {
        const SILENT_REFUSE: bool = false;

        let router = Arc::new(QuicRouter::default());
        let (listeners, server_task) =
            launch_client_auth_test_server::<SILENT_REFUSE>(router.clone(), server_parameters())
                .await?;
        let _server_task = AbortOnDropHandle::new(tokio::spawn(server_task));
        let server_addr = get_server_addr(&listeners);

        let client = {
            let parameters = client_parameters();
            // no CLIENT_NAME

            let mut roots = rustls::RootCertStore::empty();
            roots.add_parsable_certificates(
                CertificateDer::pem_slice_iter(CA_CERT).map(Result::unwrap),
            );
            let client = QuicClient::builder()
                .with_router(router)
                .with_root_certificates(roots)
                .with_parameters(parameters)
                .with_cert(CLIENT_CERT, CLIENT_KEY)
                .with_qlog(qlogger())
                .enable_sslkeylog()
                .build();

            Arc::new(client)
        };
        let connection = c
Download .txt
gitextract_c16ycxax/

├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── feature_request.md
│   │   └── r2cn.md
│   ├── dependabot.yml
│   └── workflows/
│       ├── benchmark.yml
│       ├── codecov.yml
│       ├── commitlint.yml
│       ├── feishu-bot.yml
│       ├── rust.yml
│       └── traversal.yml
├── .gitignore
├── .pre-commit-config.yaml
├── .rustfmt.toml
├── .rusty-hook.toml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Cargo.toml
├── LICENSE
├── README.md
├── README_CN.md
├── SECURITY.md
├── benchmark/
│   └── launch.py
├── codecov.yml
├── commitlint.config.js
├── dquic/
│   ├── Cargo.toml
│   ├── examples/
│   │   ├── echo-client.rs
│   │   ├── echo-server.rs
│   │   ├── http-client.rs
│   │   ├── http-server.rs
│   │   ├── traversal-client.rs
│   │   └── traversal-server.rs
│   ├── src/
│   │   ├── cert.rs
│   │   ├── client.rs
│   │   ├── common.rs
│   │   ├── lib.rs
│   │   └── server.rs
│   └── tests/
│       ├── auth.rs
│       ├── common/
│       │   └── mod.rs
│       ├── echo.rs
│       ├── echo_common/
│       │   └── mod.rs
│       └── traversal.rs
├── h3-shim/
│   ├── Cargo.toml
│   ├── examples/
│   │   ├── README.md
│   │   ├── h3-client.rs
│   │   └── h3-server.rs
│   └── src/
│       ├── conn.rs
│       ├── error.rs
│       ├── ext.rs
│       ├── lib.rs
│       ├── pool.rs
│       └── streams.rs
├── interop/
│   ├── Dockerfile
│   └── run_endpoint.sh
├── qbase/
│   ├── Cargo.toml
│   └── src/
│       ├── cid/
│       │   ├── connection_id.rs
│       │   ├── local_cid.rs
│       │   └── remote_cid.rs
│       ├── cid.rs
│       ├── error.rs
│       ├── flow.rs
│       ├── frame/
│       │   ├── ack.rs
│       │   ├── add_address.rs
│       │   ├── connection_close.rs
│       │   ├── crypto.rs
│       │   ├── data_blocked.rs
│       │   ├── datagram.rs
│       │   ├── error.rs
│       │   ├── handshake_done.rs
│       │   ├── io.rs
│       │   ├── max_data.rs
│       │   ├── max_stream_data.rs
│       │   ├── max_streams.rs
│       │   ├── new_connection_id.rs
│       │   ├── new_token.rs
│       │   ├── padding.rs
│       │   ├── path_challenge.rs
│       │   ├── path_response.rs
│       │   ├── ping.rs
│       │   ├── punch_done.rs
│       │   ├── punch_hello.rs
│       │   ├── punch_me_now.rs
│       │   ├── remove_address.rs
│       │   ├── reset_stream.rs
│       │   ├── retire_connection_id.rs
│       │   ├── stop_sending.rs
│       │   ├── stream.rs
│       │   ├── stream_data_blocked.rs
│       │   └── streams_blocked.rs
│       ├── frame.rs
│       ├── handshake.rs
│       ├── lib.rs
│       ├── metric.rs
│       ├── net/
│       │   ├── addr.rs
│       │   ├── nat.rs
│       │   ├── route.rs
│       │   └── tx.rs
│       ├── net.rs
│       ├── packet/
│       │   ├── decrypt.rs
│       │   ├── encrypt.rs
│       │   ├── error.rs
│       │   ├── header/
│       │   │   ├── long.rs
│       │   │   └── short.rs
│       │   ├── header.rs
│       │   ├── io.rs
│       │   ├── keys.rs
│       │   ├── number.rs
│       │   ├── signal.rs
│       │   ├── type/
│       │   │   ├── long/
│       │   │   │   └── v1.rs
│       │   │   ├── long.rs
│       │   │   └── short.rs
│       │   └── type.rs
│       ├── packet.rs
│       ├── param/
│       │   ├── core.rs
│       │   ├── error.rs
│       │   ├── handy.rs
│       │   ├── io.rs
│       │   └── preferred_address.rs
│       ├── param.rs
│       ├── role.rs
│       ├── sid/
│       │   ├── handy.rs
│       │   ├── local_sid.rs
│       │   └── remote_sid.rs
│       ├── sid.rs
│       ├── time.rs
│       ├── token.rs
│       ├── util/
│       │   ├── async_deque.rs
│       │   ├── bound_queue.rs
│       │   ├── data.rs
│       │   ├── index_deque.rs
│       │   ├── unique_id.rs
│       │   └── wakers.rs
│       ├── util.rs
│       └── varint.rs
├── qcongestion/
│   ├── Cargo.toml
│   └── src/
│       ├── algorithm/
│       │   ├── bbr/
│       │   │   ├── delivery_rate.rs
│       │   │   ├── min_max.rs
│       │   │   ├── model.rs
│       │   │   ├── parameters.rs
│       │   │   └── state.rs
│       │   ├── bbr.rs
│       │   └── new_reno.rs
│       ├── algorithm.rs
│       ├── congestion.rs
│       ├── lib.rs
│       ├── pacing.rs
│       ├── packets.rs
│       ├── rtt.rs
│       └── status.rs
├── qconnection/
│   ├── Cargo.toml
│   └── src/
│       ├── builder.rs
│       ├── events.rs
│       ├── handshake.rs
│       ├── lib.rs
│       ├── path/
│       │   ├── aa.rs
│       │   ├── burst.rs
│       │   ├── drive.rs
│       │   ├── error.rs
│       │   ├── paths.rs
│       │   ├── util.rs
│       │   └── validate.rs
│       ├── path.rs
│       ├── space/
│       │   ├── data.rs
│       │   ├── handshake.rs
│       │   └── initial.rs
│       ├── space.rs
│       ├── state.rs
│       ├── termination.rs
│       ├── tls/
│       │   ├── agent.rs
│       │   └── client_auth.rs
│       ├── tls.rs
│       ├── traversal.rs
│       └── tx.rs
├── qdatagram/
│   ├── Cargo.toml
│   └── src/
│       ├── lib.rs
│       ├── reader.rs
│       └── writer.rs
├── qevent/
│   ├── Cargo.toml
│   └── src/
│       ├── legacy/
│       │   ├── exporter.rs
│       │   └── quic.rs
│       ├── legacy.rs
│       ├── lib.rs
│       ├── loglevel.rs
│       ├── macro_support.rs
│       ├── macros.rs
│       ├── packet.rs
│       ├── quic/
│       │   ├── connectivity.rs
│       │   ├── recovery.rs
│       │   ├── security.rs
│       │   └── transport.rs
│       ├── quic.rs
│       ├── telemetry/
│       │   ├── filter.rs
│       │   ├── handy.rs
│       │   ├── macro_support.rs
│       │   └── macros.rs
│       └── telemetry.rs
├── qinterface/
│   ├── Cargo.toml
│   ├── examples/
│   │   └── interface-monitor.rs
│   ├── src/
│   │   ├── bind_uri.rs
│   │   ├── component/
│   │   │   ├── alive.rs
│   │   │   ├── location.rs
│   │   │   ├── route/
│   │   │   │   ├── handler.rs
│   │   │   │   ├── packet.rs
│   │   │   │   └── queue.rs
│   │   │   └── route.rs
│   │   ├── component.rs
│   │   ├── device.rs
│   │   ├── iface.rs
│   │   ├── io/
│   │   │   ├── factory.rs
│   │   │   └── handy.rs
│   │   ├── io.rs
│   │   ├── lib.rs
│   │   └── manager.rs
│   └── tests/
│       ├── auto_rebind.rs
│       ├── common/
│       │   └── mod.rs
│       ├── components.rs
│       ├── lifecycle.rs
│       ├── locations.rs
│       └── rebind.rs
├── qmacro/
│   ├── Cargo.toml
│   └── src/
│       ├── derive.rs
│       └── lib.rs
├── qprotocol/
│   ├── Cargo.toml
│   └── src/
│       ├── dns.rs
│       ├── forward.rs
│       ├── io.rs
│       ├── lib.rs
│       ├── quic.rs
│       ├── stun/
│       │   └── msg.rs
│       └── stun.rs
├── qrecovery/
│   ├── Cargo.toml
│   └── src/
│       ├── crypto.rs
│       ├── journal/
│       │   ├── rcvd.rs
│       │   └── sent.rs
│       ├── journal.rs
│       ├── lib.rs
│       ├── recv/
│       │   ├── incoming.rs
│       │   ├── rcvbuf.rs
│       │   ├── reader.rs
│       │   └── recver.rs
│       ├── recv.rs
│       ├── reliable.rs
│       ├── send/
│       │   ├── outgoing.rs
│       │   ├── sender.rs
│       │   ├── sndbuf.rs
│       │   └── writer.rs
│       ├── send.rs
│       ├── streams/
│       │   ├── error.rs
│       │   ├── io.rs
│       │   ├── listener.rs
│       │   └── raw.rs
│       └── streams.rs
├── qresolve/
│   ├── Cargo.toml
│   └── src/
│       └── lib.rs
├── qtraversal/
│   ├── Cargo.toml
│   ├── README.md
│   ├── examples/
│   │   ├── stun_client.rs
│   │   └── stun_server.rs
│   ├── src/
│   │   ├── addr.rs
│   │   ├── future.rs
│   │   ├── lib.rs
│   │   ├── nat/
│   │   │   ├── client.rs
│   │   │   ├── iface.rs
│   │   │   ├── msg.rs
│   │   │   ├── router.rs
│   │   │   ├── server.rs
│   │   │   └── tx.rs
│   │   ├── nat.rs
│   │   ├── packet.rs
│   │   ├── punch/
│   │   │   ├── predictor.rs
│   │   │   ├── puncher.rs
│   │   │   ├── scheduler.rs
│   │   │   └── tx.rs
│   │   ├── punch.rs
│   │   └── route.rs
│   ├── tests/
│   │   └── detect.rs
│   └── tools/
│       ├── build_nat.sh
│       ├── clear_nat.sh
│       ├── dockerfile
│       └── run_stun.sh
├── qudp/
│   ├── Cargo.toml
│   ├── examples/
│   │   ├── receive.rs
│   │   └── send.rs
│   └── src/
│       ├── lib.rs
│       ├── unix.rs
│       └── windows.rs
└── tests/
    └── keychain/
        ├── gen_key.sh
        ├── localhost/
        │   ├── ca.cert
        │   ├── ca.key
        │   ├── ca.srl
        │   ├── client.cert
        │   ├── client.key
        │   ├── server.cert
        │   └── server.key
        ├── quic.test.net/
        │   ├── quic-test-net-ECC.crt
        │   ├── quic-test-net-ECC.key
        │   └── quic-test-net.csr
        ├── root/
        │   ├── rootCA-ECC.crt
        │   ├── rootCA-ECC.key
        │   └── rootCA-ECC.srl
        └── start-quic-server.sh
Download .txt
Showing preview only (350K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (4373 symbols across 220 files)

FILE: benchmark/launch.py
  class ServerRunner (line 13) | class ServerRunner:
    method __init__ (line 18) | def __init__(self, impl_name: str, launch_server: list[str], listen_po...
    method run (line 23) | def run(self, log) -> subprocess.Popen:
  class Result (line 34) | class Result:
    method __init__ (line 39) | def __init__(self, success: int, duration: float):
    method __str__ (line 43) | def __str__(self):
    method __repr__ (line 46) | def __repr__(self):
    method average (line 50) | def average(results: list['Result']) -> 'Result':
  class RandomFiles (line 60) | class RandomFiles:
    method __init__ (line 63) | def __init__(self):
    method gen (line 67) | def gen(self, file_size: int) -> str:
  class Certs (line 77) | class Certs:
    method __init__ (line 89) | def __init__(self):
    method gen (line 92) | def gen(self):
  function git_clone (line 138) | def git_clone(owner: str, repo: str, branch: str) -> None:
  function go_quic_runner (line 148) | def go_quic_runner() -> ServerRunner:
  function dquic_runner (line 176) | def dquic_runner() -> ServerRunner:
  function dquic_multi_path_runner (line 201) | def dquic_multi_path_runner() -> ServerRunner:
  function tquic_runner (line 227) | def tquic_runner() -> ServerRunner:
  function quinn_runner (line 250) | def quinn_runner() -> ServerRunner:
  function cf_quiche_runner (line 273) | def cf_quiche_runner() -> ServerRunner:
  class H3Client (line 297) | class H3Client:
    method __init__ (line 302) | def __init__(self, stress: int = 1024*30, requests: int = 8, progress:...
    method run_once (line 315) | def run_once(self, server_runner: ServerRunner, file_size: int, seq: i...
    method run_many (line 375) | def run_many(self, server_runner: ServerRunner, file_size: int, times:...
  function run (line 385) | def run(*runners: ServerRunner) -> dict[dict[str, list[Result]]]:
  function plot_results (line 401) | def plot_results(results: dict[str, dict[str, list[Result]]]):
  function save_results (line 456) | def save_results(results: dict[str, dict[str, list[Result]]]):
  function load_results (line 471) | def load_results(*paths: str) -> dict[str, dict[str, list[Result]]]:

FILE: dquic/examples/echo-client.rs
  type Options (line 23) | struct Options {
  function main (line 62) | async fn main() {
  type Error (line 92) | type Error = Box<dyn std::error::Error + Send + Sync>;
  function run (line 94) | async fn run(options: Options) -> Result<(), Error> {
  function send_and_verify_files (line 125) | async fn send_and_verify_files(
  function process (line 173) | async fn process(client: &Arc<QuicClient>, auth: &Authority, progress: b...
  function new_pb (line 203) | fn new_pb(prefix: impl Into<Cow<'static, str>>, len: u64) -> ProgressBar {
  function send_and_verify_echo (line 210) | async fn send_and_verify_echo(

FILE: dquic/examples/echo-server.rs
  type Options (line 12) | struct Options {
  type Certs (line 43) | struct Certs {
  function main (line 63) | async fn main() {
  function run (line 86) | async fn run(options: Options) -> Result<(), Box<dyn std::error::Error +...
  function serve_echo (line 127) | async fn serve_echo(listeners: Arc<QuicListeners>) -> Result<(), Listene...

FILE: dquic/examples/http-client.rs
  type Options (line 15) | struct Options {
  function main (line 54) | async fn main() {
  type Error (line 81) | type Error = Box<dyn std::error::Error + Send + Sync>;
  function run (line 83) | async fn run(options: Options) -> Result<(), Error> {
  function process (line 126) | async fn process(
  function download (line 156) | async fn download(client: &Arc<QuicClient>, uri: Uri, save: Option<&Path...

FILE: dquic/examples/http-server.rs
  type Options (line 13) | struct Options {
  type Certs (line 61) | struct Certs {
  type Error (line 80) | type Error = Box<dyn std::error::Error + Send + Sync>;
  function main (line 82) | fn main() {
  function run (line 112) | async fn run(options: Options) -> Result<(), Error> {
  function serve_files (line 154) | async fn serve_files(connection: Connection) -> Result<(), Error> {

FILE: dquic/examples/traversal-client.rs
  function main (line 147) | fn main() {}

FILE: dquic/examples/traversal-server.rs
  function main (line 124) | fn main() {}

FILE: dquic/src/cert.rs
  type ToCertificate (line 5) | pub trait ToCertificate {
    method to_certificate (line 6) | fn to_certificate(self) -> Vec<CertificateDer<'static>>;
    method to_certificate (line 10) | fn to_certificate(self) -> Vec<CertificateDer<'static>> {
    method to_certificate (line 16) | fn to_certificate(self) -> Vec<CertificateDer<'static>> {
    method to_certificate (line 22) | fn to_certificate(self) -> Vec<CertificateDer<'static>> {
    method to_certificate (line 28) | fn to_certificate(self) -> Vec<CertificateDer<'static>> {
    method to_certificate (line 34) | fn to_certificate(self) -> Vec<CertificateDer<'static>> {
    method to_certificate (line 47) | fn to_certificate(self) -> Vec<CertificateDer<'static>> {
    method to_certificate (line 59) | fn to_certificate(self) -> Vec<CertificateDer<'static>> {
  type ToPrivateKey (line 64) | pub trait ToPrivateKey {
    method to_private_key (line 65) | fn to_private_key(self) -> PrivateKeyDer<'static>;
    method to_private_key (line 69) | fn to_private_key(self) -> PrivateKeyDer<'static> {
    method to_private_key (line 75) | fn to_private_key(self) -> PrivateKeyDer<'static> {
    method to_private_key (line 81) | fn to_private_key(self) -> PrivateKeyDer<'static> {
    method to_private_key (line 93) | fn to_private_key(self) -> PrivateKeyDer<'static> {
    method to_private_key (line 104) | fn to_private_key(self) -> PrivateKeyDer<'static> {

FILE: dquic/src/client.rs
  type TlsClientConfig (line 35) | type TlsClientConfig = rustls::ClientConfig;
  type TlsClientConfigBuilder (line 36) | type TlsClientConfigBuilder<T> = ConfigBuilder<TlsClientConfig, T>;
  type QuicClient (line 55) | pub struct QuicClient {
    method bind_ifaces (line 97) | pub fn bind_ifaces(&self) -> HashMap<BindUri, BindInterface> {
    method bind (line 104) | pub async fn bind(&self, bind_uri: impl Into<BindUri>) -> BindInterface {
    method unbind (line 113) | pub fn unbind(&self, bind_uri: &BindUri) -> Option<BindInterface> {
    method new_connection (line 125) | pub fn new_connection(&self, server_name: impl Into<String>) -> Connec...
    method bind_uri_for (line 147) | fn bind_uri_for(source: &Source, ep: &EndpointAddr) -> BindUri {
    method ensure_iface_for (line 170) | async fn ensure_iface_for(&self, source: &Source, ep: &EndpointAddr) {
    method select_or_bind_ifaces (line 182) | async fn select_or_bind_ifaces(
    method probe (line 259) | pub async fn probe(
    method setup_server_endpoint (line 291) | async fn setup_server_endpoint(
    method connected_to_with_source (line 328) | pub async fn connected_to_with_source(
    method connect (line 353) | pub async fn connect(self: &Arc<Self>, server: &str) -> Result<Connect...
    method builder (line 436) | pub fn builder() -> QuicClientBuilder<TlsClientConfigBuilder<WantsVeri...
    method builder_with_crypto_provider (line 443) | pub fn builder_with_crypto_provider(
    method builder_with_tls (line 456) | pub fn builder_with_tls<T>(tls_config: T) -> QuicClientBuilder<T> {
  type ConnectServerError (line 71) | pub enum ConnectServerError {
  type BindInterfaceError (line 89) | pub struct BindInterfaceError {
  type QuicClientBuilder (line 418) | pub struct QuicClientBuilder<T> {
  function with_resolver (line 477) | pub fn with_resolver(mut self, resolver: Arc<dyn Resolve + Send + Sync>)...
  function physical_ifaces (line 482) | pub fn physical_ifaces(mut self, physical_ifaces: &'static Devices) -> S...
  function with_iface_factory (line 495) | pub fn with_iface_factory(mut self, iface_factory: Arc<dyn ProductIO>) -...
  function with_iface_manager (line 501) | pub fn with_iface_manager(mut self, iface_manager: Arc<InterfaceManager>...
  function with_router (line 506) | pub fn with_router(mut self, router: Arc<QuicRouter>) -> Self {
  function with_stun (line 511) | pub fn with_stun(mut self, server: impl Into<Arc<str>>) -> Self {
  function with_locations (line 519) | pub fn with_locations(mut self, locations: Arc<Locations>) -> Self {
  function bind (line 543) | pub async fn bind(mut self, bind_uris: impl IntoIterator<Item = impl Int...
  function prefer_versions (line 558) | pub fn prefer_versions(mut self, versions: impl IntoIterator<Item = u32>...
  function with_token_sink (line 571) | pub fn with_token_sink(self, token_sink: Arc<dyn TokenSink>) -> Self {
  function with_parameters (line 582) | pub fn with_parameters(self, parameters: ClientParameters) -> Self {
  function map_tls (line 586) | fn map_tls<T1>(self, f: impl FnOnce(T) -> T1) -> QuicClientBuilder<T1> {
  function with_name (line 601) | pub fn with_name(mut self, name: impl Into<String>) -> Self {
  function defer_idle_timeout (line 617) | pub fn defer_idle_timeout(mut self, duration: Duration) -> Self {
  function with_streams_concurrency_strategy (line 631) | pub fn with_streams_concurrency_strategy(
  function with_qlog (line 658) | pub fn with_qlog(self, qlogger: Arc<dyn QLog + Send + Sync>) -> Self {
  function with_root_certificates (line 667) | pub fn with_root_certificates(
  function with_webpki_verifier (line 677) | pub fn with_webpki_verifier(
  function with_custom_server_cert_verifier (line 689) | pub fn with_custom_server_cert_verifier(
  function without_verifier (line 701) | pub fn without_verifier(self) -> QuicClientBuilder<TlsClientConfigBuilde...
  function with_cert (line 769) | pub fn with_cert(
  function without_cert (line 782) | pub fn without_cert(self) -> QuicClientBuilder<TlsClientConfig> {
  function with_cert_resolver (line 786) | pub fn with_cert_resolver(
  function with_alpns (line 804) | pub fn with_alpns(mut self, alpns: impl IntoIterator<Item = impl Into<Ve...
  function enable_sslkeylog (line 818) | pub fn enable_sslkeylog(mut self) -> Self {
  function enable_0rtt (line 823) | pub fn enable_0rtt(mut self) -> Self {
  function build (line 829) | pub fn build(self) -> QuicClient {

FILE: dquic/src/common.rs
  type Network (line 27) | pub struct Network {
    method lookup_first_agent (line 53) | async fn lookup_first_agent(
    method init_iface_components (line 75) | fn init_iface_components(
    method bind (line 149) | pub async fn bind(&self, bind_uri: BindUri) -> BindInterface {
    method bind_many (line 174) | pub async fn bind_many(
  method default (line 38) | fn default() -> Self {

FILE: dquic/src/server.rs
  type ServerError (line 45) | pub enum ServerError {
  function from (line 64) | fn from(error: ServerError) -> Self {
  type ListenError (line 76) | pub enum ListenError {
  function from (line 83) | fn from(error: ListenError) -> Self {
  type TlsServerConfigBuilder (line 90) | type TlsServerConfigBuilder<T> = ConfigBuilder<TlsServerConfig, T>;
  type VirtualHosts (line 93) | pub struct VirtualHosts(Arc<DashMap<String, Server>>);
  method resolve (line 96) | fn resolve(&self, client_hello: rustls::server::ClientHello) -> Option<A...
  type Server (line 103) | pub struct Server {
    method fmt (line 111) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    method bind_interfaces (line 120) | pub fn bind_interfaces(&self) -> HashMap<BindUri, BindInterface> {
    method bind (line 127) | pub async fn bind(&self, bind_uris: impl IntoIterator<Item = impl Into...
    method get_iface (line 134) | pub fn get_iface(&self, bind_uri: &BindUri) -> Option<BindInterface> {
    method remove_iface (line 140) | pub fn remove_iface(&self, bind_uri: &BindUri) -> Option<BindInterface> {
    method certified_key (line 144) | pub fn certified_key(&self) -> Arc<CertifiedKey> {
    method update_ocsp (line 148) | pub fn update_ocsp(&self, ocsp: Option<Vec<u8>>) {
  type Incomings (line 157) | type Incomings = BoundQueue<((Connection, String, Pathway, Link), OwnedS...
  type QuicListeners (line 184) | pub struct QuicListeners {
    method add_server (line 215) | pub async fn add_server(
    method remove_server (line 278) | pub fn remove_server(&self, server_name: &str) -> bool {
    method get_server (line 283) | pub fn get_server<'l>(&'l self, server_name: &str) -> Option<impl Dere...
    method get_server_mut (line 288) | pub fn get_server_mut<'l>(
    method servers (line 295) | pub fn servers(&self) -> Vec<String> {
    method accept (line 315) | pub async fn accept(&self) -> Result<(Connection, String, Pathway, Lin...
    method shutdown (line 326) | pub fn shutdown(&self) {
    method try_accept_connection (line 372) | pub(crate) fn try_accept_connection(&self, packet: Packet, (bind_uri, ...
    method builder (line 473) | pub fn builder() -> QuicListenersBuilder<TlsServerConfigBuilder<WantsV...
    method builder_with_crypto_provider (line 480) | pub fn builder_with_crypto_provider(
    method builder_with_tls (line 492) | pub fn builder_with_tls<T>(tls_config: T) -> QuicListenersBuilder<T> {
  type ListenersShutdown (line 305) | pub struct ListenersShutdown;
  method drop (line 333) | fn drop(&mut self) {
  type ServerAuther (line 338) | struct ServerAuther {
  method verify_client_name (line 345) | fn verify_client_name(
  method verify_client_agent (line 361) | fn verify_client_agent(&self, _: &LocalAgent, _: &RemoteAgent) -> Client...
  type QuicListenersBuilder (line 452) | pub struct QuicListenersBuilder<T> {
  function with_resolver (line 515) | pub fn with_resolver(mut self, resolver: Arc<dyn Resolve + Send + Sync>)...
  function with_physical_ifaces (line 520) | pub fn with_physical_ifaces(mut self, physical_ifaces: &'static Devices)...
  function with_iface_factory (line 532) | pub fn with_iface_factory(mut self, iface_factory: Arc<dyn ProductIO + '...
  function with_iface_manager (line 537) | pub fn with_iface_manager(mut self, iface_manager: Arc<InterfaceManager>...
  function with_router (line 549) | pub fn with_router(mut self, router: Arc<QuicRouter>) -> Self {
  function with_stun (line 554) | pub fn with_stun(mut self, stun_server: impl Into<Arc<str>>) -> Self {
  function with_locations (line 562) | pub fn with_locations(mut self, locations: Arc<Locations>) -> Self {
  function with_supported_versions (line 570) | pub fn with_supported_versions(mut self, versions: impl IntoIterator<Ite...
  function with_token_provider (line 581) | pub fn with_token_provider(self, token_provider: Arc<dyn TokenProvider>)...
  function with_parameters (line 595) | pub fn with_parameters(mut self, parameters: ServerParameters) -> Self {
  function enable_anti_port_scan (line 622) | pub fn enable_anti_port_scan(mut self) -> Self {
  function with_client_auther (line 661) | pub fn with_client_auther(mut self, client_auther: impl AuthClient + 'st...
  function map_tls (line 666) | fn map_tls<T1>(self, f: impl FnOnce(T) -> T1) -> QuicListenersBuilder<T1> {
  function with_streams_concurrency_strategy (line 689) | pub fn with_streams_concurrency_strategy(
  function defer_idle_timeout (line 708) | pub fn defer_idle_timeout(mut self, duration: Duration) -> Self {
  function with_qlog (line 730) | pub fn with_qlog(self, qlogger: Arc<dyn QLog + Send + Sync>) -> Self {
  function with_client_cert_verifier (line 737) | pub fn with_client_cert_verifier(
  function without_client_cert_verifier (line 750) | pub fn without_client_cert_verifier(self) -> QuicListenersBuilder<TlsSer...
  function with_alpns (line 768) | pub fn with_alpns(mut self, alpn: impl IntoIterator<Item = impl Into<Vec...
  function enable_0rtt (line 775) | pub fn enable_0rtt(mut self) -> Self {
  function listen (line 794) | pub fn listen(self, backlog: usize) -> Result<Arc<QuicListeners>, Listen...

FILE: dquic/tests/auth.rs
  function client_without_verify (line 26) | fn client_without_verify() -> Result<(), BoxError> {
  type ClientNameAuther (line 58) | struct ClientNameAuther<const SILENT_REFUSE: bool>;
  method verify_client_name (line 61) | fn verify_client_name(
  method verify_client_agent (line 73) | fn verify_client_agent(&self, _: &LocalAgent, _: &RemoteAgent) -> Client...
  function launch_client_auth_test_server (line 78) | async fn launch_client_auth_test_server<const SILENT_REFUSE: bool>(
  function auth_client_name (line 108) | fn auth_client_name() -> Result<(), BoxError> {
  function auth_client_name_incorrect_name (line 147) | fn auth_client_name_incorrect_name() -> Result<(), BoxError> {
  function auth_client_refuse (line 188) | fn auth_client_refuse() -> Result<(), BoxError> {
  function auth_client_refuse_silently (line 232) | fn auth_client_refuse_silently() -> Result<(), BoxError> {
  type Message (line 282) | struct Message {
  constant SIGNATURE_SCHEME (line 287) | const SIGNATURE_SCHEME: rustls::SignatureScheme = rustls::SignatureSchem...
  function send_and_verify_echo_with_sign_verify (line 289) | async fn send_and_verify_echo_with_sign_verify(
  function echo_stream_with_sign_verify (line 322) | async fn echo_stream_with_sign_verify(
  function serve_echo_with_sign_verify (line 341) | pub async fn serve_echo_with_sign_verify(listeners: Arc<QuicListeners>) {
  function launch_echo_with_sign_verify_server (line 360) | async fn launch_echo_with_sign_verify_server(
  function sign_and_verify (line 389) | fn sign_and_verify() -> Result<(), BoxError> {

FILE: dquic/tests/common/mod.rs
  function qlogger (line 25) | pub fn qlogger() -> Arc<dyn QLog + Send + Sync> {
  type BoxError (line 30) | pub type BoxError = Box<dyn std::error::Error + Send + Sync>;
  function run (line 32) | pub fn run<F: Future>(future: F) -> F::Output {
  function launch_test_client (line 68) | pub fn launch_test_client(
  function get_server_addr (line 86) | pub fn get_server_addr(listeners: &QuicListeners) -> SocketAddr {
  constant CA_CERT (line 102) | pub const CA_CERT: &[u8] = include_bytes!("../../../tests/keychain/local...
  constant SERVER_CERT (line 103) | pub const SERVER_CERT: &[u8] = include_bytes!("../../../tests/keychain/l...
  constant SERVER_KEY (line 104) | pub const SERVER_KEY: &[u8] = include_bytes!("../../../tests/keychain/lo...
  constant CLIENT_CERT (line 105) | pub const CLIENT_CERT: &[u8] = include_bytes!("../../../tests/keychain/l...
  constant CLIENT_KEY (line 106) | pub const CLIENT_KEY: &[u8] = include_bytes!("../../../tests/keychain/lo...
  constant TEST_DATA (line 107) | pub const TEST_DATA: &[u8] = include_bytes!("mod.rs");

FILE: dquic/tests/echo.rs
  function single_stream (line 19) | fn single_stream() -> Result<(), BoxError> {
  function signal_big_stream (line 39) | fn signal_big_stream() -> Result<(), BoxError> {
  function empty_stream (line 60) | fn empty_stream() -> Result<(), BoxError> {
  function shutdown (line 80) | fn shutdown() -> Result<(), BoxError> {
  function idle_timeout (line 134) | fn idle_timeout() -> Result<(), BoxError> {
  function double_connections (line 164) | fn double_connections() -> Result<(), BoxError> {
  constant PARALLEL_ECHO_CONNS (line 214) | const PARALLEL_ECHO_CONNS: usize = 3;
  constant PARALLEL_ECHO_STREAMS (line 215) | const PARALLEL_ECHO_STREAMS: usize = 2;
  function parallel_stream (line 218) | fn parallel_stream() -> Result<(), BoxError> {
  function parallel_big_stream (line 275) | fn parallel_big_stream() -> Result<(), BoxError> {
  function limited_streams (line 329) | fn limited_streams() -> Result<(), BoxError> {

FILE: dquic/tests/echo_common/mod.rs
  function echo_stream (line 11) | pub async fn echo_stream(mut reader: StreamReader, mut writer: StreamWri...
  function serve_echo (line 17) | pub async fn serve_echo(listeners: Arc<QuicListeners>) {
  function send_and_verify_echo (line 29) | pub async fn send_and_verify_echo(connection: &Connection, data: &[u8]) ...
  function launch_echo_server (line 51) | pub async fn launch_echo_server(

FILE: dquic/tests/traversal.rs
  type TestCase (line 29) | pub struct TestCase {
  constant STUN_SERVERS (line 35) | pub const STUN_SERVERS: &str = "10.10.0.64:20002";
  constant CASES (line 37) | pub const CASES: [TestCase; 10] = [
  function launch_stun_test_server (line 165) | async fn launch_stun_test_server(server_case: TestCase) -> Arc<QuicListe...
  function launch_stun_test_client (line 201) | async fn launch_stun_test_client(client_case: TestCase) -> Arc<QuicClien...
  function test_punch_case (line 236) | async fn test_punch_case(client_nat: NatType, server_nat: NatType) {
  function get_stun_data (line 262) | async fn get_stun_data(server_iface: dquic::qinterface::Interface) -> Ve...
  function launch_client (line 293) | async fn launch_client(client_case: TestCase, server_ep: EndpointAddr) {
  type Error (line 345) | pub type Error = Box<dyn std::error::Error + Send + Sync>;
  function test_knock_ttl_is_1_in_tests (line 348) | fn test_knock_ttl_is_1_in_tests() {

FILE: h3-shim/examples/h3-client.rs
  type Options (line 22) | struct Options {
  function main (line 88) | async fn main() {
  type Error (line 117) | type Error = Box<dyn std::error::Error + Send + Sync>;
  function run (line 119) | async fn run(options: Options) -> Result<(), Error> {
  function download_files_with_progress (line 222) | async fn download_files_with_progress(

FILE: h3-shim/examples/h3-server.rs
  type Options (line 17) | struct Options {
  type Certs (line 65) | struct Certs {
  function main (line 84) | fn main() {
  function run (line 117) | async fn run(options: Options) -> Result<(), Box<dyn std::error::Error +...
  function handle_connection (line 186) | async fn handle_connection<T>(
  function handle_request (line 214) | async fn handle_request<T>(
  function test_name (line 258) | fn test_name() {}

FILE: h3-shim/src/conn.rs
  type QuicConnection (line 17) | pub struct QuicConnection {
    method new (line 34) | pub fn new(conn: Arc<Connection>) -> Self {
    type BidiStream (line 47) | type BidiStream = BidiStream<B>;
    type SendStream (line 49) | type SendStream = SendStream<B>;
    method poll_open_bidi (line 52) | fn poll_open_bidi(
    method poll_open_send (line 75) | fn poll_open_send(
    method close (line 83) | fn close(&mut self, code: h3::error::Code, reason: &[u8]) {
    type RecvStream (line 92) | type RecvStream = RecvStream;
    type OpenStreams (line 94) | type OpenStreams = OpenStreams;
    method poll_accept_recv (line 97) | fn poll_accept_recv(
    method poll_accept_bidi (line 105) | fn poll_accept_bidi(
    method opener (line 116) | fn opener(&self) -> Self::OpenStreams {
  type Target (line 26) | type Target = Arc<Connection>;
  method deref (line 28) | fn deref(&self) -> &Self::Target {
  type OpenStreams (line 122) | pub struct OpenStreams {
    method new (line 129) | fn new(conn: Arc<Connection>) -> Self {
    type BidiStream (line 150) | type BidiStream = BidiStream<B>;
    type SendStream (line 152) | type SendStream = SendStream<B>;
    method poll_open_bidi (line 155) | fn poll_open_bidi(
    method poll_open_send (line 163) | fn poll_open_send(
    method close (line 171) | fn close(&mut self, code: h3::error::Code, reason: &[u8]) {
  method clone (line 139) | fn clone(&self) -> Self {
  type BoxStream (line 177) | type BoxStream<T> = Pin<Box<dyn Stream<Item = T> + Send + Sync>>;
  function sid_exceed_limit_error (line 179) | fn sid_exceed_limit_error() -> ConnectionErrorIncoming {
  type OpenBiStreams (line 186) | struct OpenBiStreams(
    method new (line 191) | fn new(conn: Arc<Connection>) -> Self {
    method poll_open (line 206) | fn poll_open<B>(
  type OpenUniStreams (line 221) | struct OpenUniStreams(BoxStream<Result<(StreamId, StreamWriter), Connect...
    method new (line 224) | fn new(conn: Arc<Connection>) -> Self {
    method poll_open (line 236) | fn poll_open<B>(
  type AcceptBiStreams (line 252) | struct AcceptBiStreams(
    method new (line 257) | fn new(conn: Arc<Connection>) -> Self {
    method poll_accept (line 269) | fn poll_accept<B>(
  type AcceptUniStreams (line 281) | struct AcceptUniStreams(BoxStream<Result<(StreamId, StreamReader), Conne...
    method new (line 284) | fn new(conn: Arc<Connection>) -> Self {
    method poll_accept (line 295) | fn poll_accept(

FILE: h3-shim/src/error.rs
  function convert_quic_error (line 7) | pub fn convert_quic_error(e: qbase::error::Error) -> ConnectionErrorInco...
  function convert_stream_io_error (line 18) | pub fn convert_stream_io_error(e: std::io::Error) -> StreamErrorIncoming {

FILE: h3-shim/src/streams.rs
  type SendStream (line 17) | pub struct SendStream<B> {
  function new (line 24) | pub fn new(sid: qbase::sid::StreamId, writer: StreamWriter) -> Self {
  function poll_ready (line 36) | fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Stream...
  function send_data (line 58) | fn send_data<T: Into<h3::quic::WriteBuf<B>>>(
  function poll_finish (line 68) | fn poll_finish(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Strea...
  function reset (line 77) | fn reset(&mut self, reset_code: u64) {
  function send_id (line 83) | fn send_id(&self) -> h3::quic::StreamId {
  function poll_send (line 90) | fn poll_send<D: Buf>(
  type RecvStream (line 103) | pub struct RecvStream {
    method new (line 109) | pub(crate) fn new(sid: qbase::sid::StreamId, reader: StreamReader) -> ...
    type Buf (line 119) | type Buf = bytes::Bytes;
    method poll_data (line 122) | fn poll_data(
    method stop_sending (line 141) | fn stop_sending(&mut self, error_code: u64) {
    method recv_id (line 146) | fn recv_id(&self) -> h3::quic::StreamId {
  type BidiStream (line 151) | pub struct BidiStream<B> {
  function new (line 157) | pub(crate) fn new(
  type Buf (line 169) | type Buf = bytes::Bytes;
  function poll_data (line 172) | fn poll_data(
  function stop_sending (line 180) | fn stop_sending(&mut self, error_code: u64) {
  function recv_id (line 185) | fn recv_id(&self) -> h3::quic::StreamId {
  function poll_ready (line 192) | fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Stream...
  function send_data (line 197) | fn send_data<T: Into<h3::quic::WriteBuf<B>>>(
  function poll_finish (line 205) | fn poll_finish(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Strea...
  function reset (line 210) | fn reset(&mut self, reset_code: u64) {
  function send_id (line 215) | fn send_id(&self) -> h3::quic::StreamId {
  function poll_send (line 222) | fn poll_send<D: Buf>(
  type SendStream (line 232) | type SendStream = SendStream<B>;
  type RecvStream (line 234) | type RecvStream = RecvStream;
    method new (line 109) | pub(crate) fn new(sid: qbase::sid::StreamId, reader: StreamReader) -> ...
    type Buf (line 119) | type Buf = bytes::Bytes;
    method poll_data (line 122) | fn poll_data(
    method stop_sending (line 141) | fn stop_sending(&mut self, error_code: u64) {
    method recv_id (line 146) | fn recv_id(&self) -> h3::quic::StreamId {
  function split (line 237) | fn split(self) -> (Self::SendStream, Self::RecvStream) {

FILE: qbase/src/cid.rs
  type GenUniqueCid (line 14) | pub trait GenUniqueCid {
    method gen_unique_cid (line 17) | fn gen_unique_cid(&self) -> ConnectionId;
  type RetireCid (line 20) | pub trait RetireCid {
    method retire_cid (line 22) | fn retire_cid(&self, cid: ConnectionId);
  type Registry (line 31) | pub struct Registry<LOCAL, REMOTE> {
  function new (line 40) | pub fn new(role: Role, origin_dcid: ConnectionId, local: LOCAL, remote: ...
  function role (line 49) | pub fn role(&self) -> Role {
  function origin_dcid (line 53) | pub fn origin_dcid(&self) -> ConnectionId {

FILE: qbase/src/cid/connection_id.rs
  constant MAX_CID_SIZE (line 10) | pub const MAX_CID_SIZE: usize = 20;
  type ConnectionId (line 23) | pub struct ConnectionId {
    method fmt (line 29) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    method fmt (line 38) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    method fmt (line 44) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    method from_slice (line 93) | pub fn from_slice(bytes: &[u8]) -> Self {
    method random_gen (line 105) | pub fn random_gen(len: usize) -> Self {
    method random_gen_with_mark (line 117) | pub fn random_gen_with_mark(len: usize, mark: u8, mask: u8) -> Self {
    method encoding_size (line 131) | pub fn encoding_size(&self) -> usize {
    method eq (line 145) | fn eq(&self, other: &ConnectionId) -> bool {
  function be_connection_id (line 56) | pub fn be_connection_id(input: &[u8]) -> IResult<&[u8], ConnectionId> {
  function be_connection_id_with_len (line 67) | pub fn be_connection_id_with_len(input: &[u8], len: usize) -> IResult<&[...
  type WriteConnectionId (line 79) | pub trait WriteConnectionId: bytes::BufMut {
    method put_connection_id (line 81) | fn put_connection_id(&mut self, cid: &ConnectionId);
    method put_connection_id (line 85) | fn put_connection_id(&mut self, cid: &ConnectionId) {
  type Target (line 137) | type Target = [u8];
  method deref (line 139) | fn deref(&self) -> &Self::Target {
  method hash (line 151) | fn hash<H: Hasher>(&self, state: &mut H) {
  function test_read_connection_id (line 162) | fn test_read_connection_id() {
  function test_cid_from_large_slice (line 180) | fn test_cid_from_large_slice() {
  function test_write_connection_id (line 185) | fn test_write_connection_id() {

FILE: qbase/src/cid/local_cid.rs
  type LocalCids (line 17) | struct LocalCids<ISSUED>
  function new (line 40) | fn new(scid: ConnectionId, issued_cids: ISSUED) -> Self {
  function initial_scid (line 63) | fn initial_scid(&self) -> Option<ConnectionId> {
  function set_limit (line 72) | fn set_limit(&mut self, active_cid_limit: u64) -> Result<(), Error> {
  function issue_new_cid (line 90) | fn issue_new_cid(&mut self) {
  function recv_retire_cid_frame (line 102) | fn recv_retire_cid_frame(&mut self, frame: RetireConnectionIdFrame) -> R...
  function clear (line 128) | fn clear(&mut self) {
  method drop (line 139) | fn drop(&mut self) {
  type ArcLocalCids (line 163) | pub struct ArcLocalCids<ISSUED>(Arc<Mutex<LocalCids<ISSUED>>>)
  function new (line 178) | pub fn new(scid: ConnectionId, issued_cids: ISSUED) -> Self {
  function initial_scid (line 220) | pub fn initial_scid(&self) -> Option<ConnectionId> {
  function clear (line 235) | pub fn clear(&self) {
  function set_limit (line 243) | pub fn set_limit(&self, active_cid_limit: u64) -> Result<(), Error> {
  type Output (line 252) | type Output = ();
  function recv_frame (line 256) | fn recv_frame(
  type IssuedCids (line 271) | struct IssuedCids {
    method frames (line 277) | fn frames(&self) -> MutexGuard<'_, Vec<NewConnectionIdFrame>> {
    method active_cids (line 281) | fn active_cids(&self) -> MutexGuard<'_, HashMap<ConnectionId, ResetTok...
    method send_frame (line 306) | fn send_frame<I: IntoIterator<Item = NewConnectionIdFrame>>(&self, ite...
  method gen_unique_cid (line 287) | fn gen_unique_cid(&self) -> ConnectionId {
  method retire_cid (line 300) | fn retire_cid(&self, cid: ConnectionId) {
  function test_issue_cid (line 312) | fn test_issue_cid() {
  function test_recv_retire_cid_frame (line 324) | fn test_recv_retire_cid_frame() {

FILE: qbase/src/cid/remote_cid.rs
  type RemoteCids (line 24) | struct RemoteCids<RETIRED>
  function new (line 56) | fn new(active_cid_limit: u64, retired_cids: RETIRED) -> Self {
  function apply_initial_dcid (line 69) | fn apply_initial_dcid(&mut self, initial_dcid: ConnectionId, dcid_cell: ...
  function recv_new_cid_frame (line 99) | fn recv_new_cid_frame(
  function arrange_idle_cid (line 134) | fn arrange_idle_cid(&mut self) {
  function retire_prior_to (line 169) | fn retire_prior_to(&mut self, tomb_seq: u64) {
  function apply_dcid (line 218) | fn apply_dcid(&mut self) -> ArcCidCell<RETIRED> {
  type ArcRemoteCids (line 236) | pub struct ArcRemoteCids<RETIRED>(Arc<Mutex<RemoteCids<RETIRED>>>)
  function new (line 249) | pub fn new(active_cid_limit: u64, retired_cids: RETIRED) -> Self {
  function apply_initial_dcid (line 269) | pub fn apply_initial_dcid(&self, initial_dcid: ConnectionId, dcid_cell: ...
  function apply_dcid (line 279) | pub fn apply_dcid(&self) -> ArcCidCell<RETIRED> {
  function latest_dcid (line 287) | pub fn latest_dcid(&self) -> Option<ConnectionId> {
  type Output (line 304) | type Output = Option<ResetToken>;
  function recv_frame (line 306) | fn recv_frame(&self, frame: NewConnectionIdFrame) -> Result<Self::Output...
  type CidCell (line 312) | struct CidCell<RETIRED>
  function assign (line 327) | fn assign(&mut self, seq: u64, cid: ConnectionId) {
  function borrow_cid (line 345) | fn borrow_cid(&mut self, tx_waker: ArcSendWaker) -> Result<Option<Connec...
  function renew (line 360) | fn renew(&mut self) {
  function retire (line 372) | fn retire(&mut self) {
  type ArcCidCell (line 392) | pub struct ArcCidCell<RETIRED>(Arc<Mutex<CidCell<RETIRED>>>)
  function new (line 405) | fn new(retired_cids: RETIRED) -> Self {
  function is_retired (line 415) | fn is_retired(&self) -> bool {
  function borrow_cid (line 424) | pub fn borrow_cid(
  function retire (line 438) | pub fn retire(&self) {
  type BorrowedCid (line 447) | pub struct BorrowedCid<'a, RETIRED>
  type Target (line 459) | type Target = ConnectionId;
  method deref (line 461) | fn deref(&self) -> &Self::Target {
  method drop (line 470) | fn drop(&mut self) {
  type RetiredCids (line 482) | struct RetiredCids(Arc<Mutex<Vec<RetireConnectionIdFrame>>>);
    method send_frame (line 485) | fn send_frame<I: IntoIterator<Item = RetireConnectionIdFrame>>(&self, ...
  function test_remote_cids (line 491) | fn test_remote_cids() {
  function test_retire_in_remote_cids (line 538) | fn test_retire_in_remote_cids() {
  function test_retire_without_apply (line 618) | fn test_retire_without_apply() {

FILE: qbase/src/error.rs
  type ErrorKind (line 17) | pub enum ErrorKind {
    type Error (line 114) | type Error = InvalidErrorKind;
    method try_from (line 116) | fn try_from(value: VarInt) -> Result<Self, Self::Error> {
  method fmt (line 79) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  type InvalidErrorKind (line 111) | pub struct InvalidErrorKind(u64);
  method from (line 142) | fn from(value: ErrorKind) -> Self {
  type ErrorFrameType (line 167) | pub enum ErrorFrameType {
    method from (line 226) | fn from(value: FrameType) -> Self {
  type QuicError (line 178) | pub struct QuicError {
    method new (line 187) | pub fn new<T: Into<Cow<'static, str>>>(
    method with_default_fty (line 201) | pub fn with_default_fty<T: Into<Cow<'static, str>>>(kind: ErrorKind, r...
    method kind (line 210) | pub fn kind(&self) -> ErrorKind {
    method frame_type (line 215) | pub fn frame_type(&self) -> ErrorFrameType {
    method reason (line 220) | pub fn reason(&self) -> &str {
  method from (line 232) | fn from(val: ErrorFrameType) -> Self {
  type AppError (line 243) | pub struct AppError {
    method new (line 250) | pub fn new(error_code: VarInt, reason: impl Into<Cow<'static, str>>) -...
    method error_code (line 260) | pub fn error_code(&self) -> u64 {
    method reason (line 265) | pub fn reason(&self) -> &str {
  type Error (line 271) | pub enum Error {
    method kind (line 279) | pub fn kind(&self) -> ErrorKind {
    method frame_type (line 286) | pub fn frame_type(&self) -> ErrorFrameType {
    method from (line 316) | fn from(frame: ConnectionCloseFrame) -> Self {
  function from (line 295) | fn from(e: Error) -> Self {
  method from (line 301) | fn from(e: Error) -> Self {
  method from (line 310) | fn from(e: AppError) -> Self {
  function test_error_kind_display (line 337) | fn test_error_kind_display() {
  function test_error_kind_conversion (line 344) | fn test_error_kind_conversion() {
  function test_error_creation (line 372) | fn test_error_creation() {
  function test_error_conversion (line 382) | fn test_error_conversion() {

FILE: qbase/src/flow.rs
  type SendControler (line 22) | struct SendControler<TX> {
  function new (line 31) | fn new(initial_max_data: u64, broker: TX, tx_wakers: ArcSendWakers) -> S...
  function increase_limit (line 41) | fn increase_limit(&mut self, max_data: u64) {
  function avaliable (line 49) | fn avaliable(&self) -> u64 {
  function commit (line 53) | fn commit(&mut self, flow: u64)
  function return_back (line 68) | fn return_back(&mut self, flow: u64) {
  function revise_max_data (line 75) | fn revise_max_data(&mut self, zero_rtt_rejected: bool, max_data: u64) {
  type ArcSendControler (line 107) | pub struct ArcSendControler<TX>(Arc<Mutex<Result<SendControler<TX>, Erro...
  function new (line 118) | pub fn new(initial_max_data: u64, broker: TX, tx_wakers: ArcSendWakers) ...
  function increase_limit (line 126) | fn increase_limit(&self, max_data: u64) {
  function credit (line 143) | pub fn credit(&self, quota: usize) -> Result<Credit<'_, TX>, Error>
  function revise_max_data (line 160) | pub fn revise_max_data(&self, zero_rtt_rejected: bool, max_data: u64) {
  function on_error (line 168) | pub fn on_error(&self, error: &Error) {
  type Output (line 180) | type Output = ();
  function recv_frame (line 182) | fn recv_frame(&self, frame: MaxDataFrame) -> Result<Self::Output, Error> {
  type Credit (line 193) | pub struct Credit<'a, TX> {
  function available (line 200) | pub fn available(&self) -> usize {
  function post_sent (line 210) | pub fn post_sent(&mut self, amount: usize) {
  method drop (line 216) | fn drop(&mut self) {
  type RecvController (line 225) | struct RecvController<TX> {
  function new (line 234) | fn new(initial_max_data: u64, broker: TX) -> Self {
  function on_new_rcvd (line 253) | fn on_new_rcvd(&mut self, frame_type: FrameType, amount: usize) -> Resul...
  type ArcRecvController (line 293) | pub struct ArcRecvController<TX>(Arc<Mutex<RecvController<TX>>>);
  function new (line 297) | pub fn new(initial_max_data: u64, broker: TX) -> Self {
  function on_new_rcvd (line 314) | pub fn on_new_rcvd(&self, frame_type: FrameType, amount: usize) -> Resul...
  type Output (line 325) | type Output = ();
  function recv_frame (line 327) | fn recv_frame(&self, _frame: DataBlockedFrame) -> Result<Self::Output, E...
  type FlowController (line 336) | pub struct FlowController<TX> {
  function new (line 347) | pub fn new(
  function reset_send_window (line 363) | pub fn reset_send_window(&self, snd_wnd: u64) {
  function send_limit (line 370) | pub fn send_limit(&self, quota: usize) -> Result<Credit<'_, TX>, Error>
  function on_conn_error (line 382) | pub fn on_conn_error(&self, error: &Error) {
  function on_new_rcvd (line 394) | pub fn on_new_rcvd(&self, frame_type: FrameType, amount: usize) -> Resul...
  type SendControllerBroker (line 406) | struct SendControllerBroker(Arc<Mutex<Vec<DataBlockedFrame>>>);
    method send_frame (line 409) | fn send_frame<I: IntoIterator<Item = DataBlockedFrame>>(&self, iter: I) {
  function test_send_controler (line 415) | fn test_send_controler() {
  type RecvControllerBroker (line 451) | struct RecvControllerBroker(Arc<Mutex<Vec<MaxDataFrame>>>);
    method send_frame (line 454) | fn send_frame<I: IntoIterator<Item = MaxDataFrame>>(&self, iter: I) {
  function test_recv_controller (line 460) | fn test_recv_controller() {

FILE: qbase/src/frame.rs
  type GetFrameType (line 75) | pub trait GetFrameType {
    method frame_type (line 77) | fn frame_type(&self) -> FrameType;
    method frame_type (line 580) | fn frame_type(&self) -> FrameType {
  type EncodeSize (line 81) | pub trait EncodeSize {
    method max_encoding_size (line 90) | fn max_encoding_size(&self) -> usize {
    method encoding_size (line 95) | fn encoding_size(&self) -> usize {
    method max_encoding_size (line 617) | fn max_encoding_size(&self) -> usize {
    method encoding_size (line 645) | fn encoding_size(&self) -> usize {
  type Spec (line 105) | pub enum Spec {
  type ContainSpec (line 134) | pub trait ContainSpec {
    method contain (line 135) | fn contain(&self, spec: Spec) -> bool;
    method contain (line 140) | fn contain(&self, spec: Spec) -> bool {
  type FrameType (line 151) | pub enum FrameType {
    type Error (line 301) | type Error = Error;
    method try_from (line 303) | fn try_from(frame_type: VarInt) -> Result<Self, Self::Error> {
  type FrameFeature (line 207) | pub trait FrameFeature {
    method belongs_to (line 209) | fn belongs_to(&self, packet_type: Type) -> bool;
    method specs (line 211) | fn specs(&self) -> u8;
    method belongs_to (line 215) | fn belongs_to(&self, packet_type: Type) -> bool {
    method specs (line 219) | fn specs(&self) -> u8 {
    method belongs_to (line 225) | fn belongs_to(&self, packet_type: Type) -> bool {
    method specs (line 276) | fn specs(&self) -> u8 {
  method from (line 350) | fn from(frame_type: FrameType) -> Self {
  function be_frame_type (line 393) | pub fn be_frame_type(input: &[u8]) -> nom::IResult<&[u8], FrameType, Err...
  type StreamCtlFrame (line 406) | pub enum StreamCtlFrame {
  type ReliableFrame (line 424) | pub enum ReliableFrame {
    type Error (line 540) | type Error = &'f Frame<D>;
    method try_from (line 543) | fn try_from(frame: &'f Frame<D>) -> Result<Self, Self::Error> {
  type Frame (line 453) | pub enum Frame<D = Bytes> {
  function from (line 500) | fn from(frame: ReliableFrame) -> Self {
  type Error (line 528) | type Error = &'f Frame<D>;
  method try_from (line 531) | fn try_from(frame: &'f Frame<D>) -> Result<Self, Self::Error> {
  type FrameReader (line 674) | pub struct FrameReader {
    method new (line 683) | pub fn new(payload: Bytes, packet_type: Type) -> Self {
  type Item (line 692) | type Item = Result<(Frame, FrameType), Error>;
  method next (line 694) | fn next(&mut self) -> Option<Self::Item> {
  method put_frame (line 710) | fn put_frame(&mut self, frame: &StreamCtlFrame) {
  method put_frame (line 723) | fn put_frame(&mut self, frame: &ReliableFrame) {
  function test_frame_type_conversion (line 761) | fn test_frame_type_conversion() {
  function test_frame_type_specs (line 780) | fn test_frame_type_specs() {
  function test_frame_type_belongs_to (line 796) | fn test_frame_type_belongs_to() {
  function test_frame_reader (line 805) | fn test_frame_reader() {
  function test_invalid_frame_type (line 828) | fn test_invalid_frame_type() {
  function test_frame_reader_parses_add_address_frame (line 833) | fn test_frame_reader_parses_add_address_frame() {
  function test_frame_reader_rejects_add_address_frame_in_non_data_packets (line 855) | fn test_frame_reader_rejects_add_address_frame_in_non_data_packets() {
  function test_manual_unknown_custom_frame_fallback (line 879) | fn test_manual_unknown_custom_frame_fallback() {
  function test_frame_reader_stops_at_unknown_custom_frame (line 960) | fn test_frame_reader_stops_at_unknown_custom_frame() {

FILE: qbase/src/frame/ack.rs
  type Ecn (line 12) | pub enum Ecn {
    method from (line 29) | fn from(value: u8) -> Self {
  function from (line 20) | fn from(ecn: Ecn) -> u8 {
  type AckFrame (line 60) | pub struct AckFrame {
    method frame_type (line 69) | fn frame_type(&self) -> super::FrameType {
    method max_encoding_size (line 79) | fn max_encoding_size(&self) -> usize {
    method encoding_size (line 83) | fn encoding_size(&self) -> usize {
    method new (line 105) | pub fn new(
    method largest (line 122) | pub fn largest(&self) -> u64 {
    method delay (line 127) | pub fn delay(&self) -> u64 {
    method first_range (line 132) | pub fn first_range(&self) -> u64 {
    method ranges (line 137) | pub fn ranges(&self) -> &Vec<(VarInt, VarInt)> {
    method ecn (line 142) | pub fn ecn(&self) -> Option<EcnCounts> {
    method set_ecn (line 147) | pub fn set_ecn(&mut self, ecn: EcnCounts) {
    method take_ecn (line 152) | pub fn take_ecn(&mut self) -> Option<EcnCounts> {
    method iter (line 158) | pub fn iter(&self) -> impl Iterator<Item = RangeInclusive<u64>> + '_ {
  type EcnCounts (line 179) | pub struct EcnCounts {
    method new (line 187) | pub fn new(ect0: VarInt, ect1: VarInt, ce: VarInt) -> Self {
    method ect0 (line 192) | pub fn ect0(&self) -> u64 {
    method ect1 (line 197) | pub fn ect1(&self) -> u64 {
    method ce (line 202) | pub fn ce(&self) -> u64 {
    method encoding_size (line 207) | fn encoding_size(&self) -> usize {
  function ack_frame_with_ecn (line 214) | pub fn ack_frame_with_ecn(ecn: Ecn) -> impl Fn(&[u8]) -> nom::IResult<&[...
  function be_ecn_counts (line 250) | pub(super) fn be_ecn_counts(input: &[u8]) -> nom::IResult<&[u8], EcnCoun...
  method put_frame (line 258) | fn put_frame(&mut self, frame: &AckFrame) {
  function test_ack_frame (line 290) | fn test_ack_frame() {
  function test_read_ecn_count (line 315) | fn test_read_ecn_count() {
  function test_read_ack_frame (line 330) | fn test_read_ack_frame() {
  function test_write_ack_frame (line 353) | fn test_write_ack_frame() {
  function test_ack_frame_into_iter (line 378) | fn test_ack_frame_into_iter() {

FILE: qbase/src/frame/add_address.rs
  type AddAddressFrame (line 24) | pub struct AddAddressFrame {
    method new (line 88) | pub fn new(seq_num: u32, address: SocketAddr, tire: u32, nat_type: Nat...
    method seq_num (line 97) | pub fn seq_num(&self) -> u32 {
    method tire (line 101) | pub fn tire(&self) -> u32 {
    method nat_type (line 105) | pub fn nat_type(&self) -> NatType {
  function be_add_address_frame (line 32) | pub(crate) fn be_add_address_frame(
  method frame_type (line 59) | fn frame_type(&self) -> super::FrameType {
  method max_encoding_size (line 65) | fn max_encoding_size(&self) -> usize {
  method encoding_size (line 74) | fn encoding_size(&self) -> usize {
  method put_frame (line 111) | fn put_frame(&mut self, frame: &AddAddressFrame) {
  function test_add_address_frame (line 130) | fn test_add_address_frame() {

FILE: qbase/src/frame/connection_close.rs
  type Layer (line 15) | pub enum Layer {
    method from (line 32) | fn from(value: u8) -> Self {
  function from (line 23) | fn from(layer: Layer) -> u8 {
  type AppCloseFrame (line 40) | pub struct AppCloseFrame {
    method error_code (line 47) | pub fn error_code(&self) -> u64 {
    method reason (line 52) | pub fn reason(&self) -> &str {
    method conceal (line 63) | pub fn conceal(&self) -> QuicCloseFrame {
  type QuicCloseFrame (line 83) | pub struct QuicCloseFrame {
    method from (line 73) | fn from(_: AppCloseFrame) -> Self {
    method error_kind (line 91) | pub fn error_kind(&self) -> ErrorKind {
    method frame_type (line 96) | pub fn frame_type(&self) -> ErrorFrameType {
    method reason (line 101) | pub fn reason(&self) -> &str {
  type ConnectionCloseFrame (line 121) | pub enum ConnectionCloseFrame {
    method frame_type (line 127) | fn frame_type(&self) -> FrameType {
    method max_encoding_size (line 136) | fn max_encoding_size(&self) -> usize {
    method encoding_size (line 144) | fn encoding_size(&self) -> usize {
    method new_quic (line 164) | pub fn new_quic(
    method new_app (line 177) | pub fn new_app(error_code: VarInt, reason: impl Into<Cow<'static, str>...
  function be_app_close_frame (line 185) | fn be_app_close_frame(input: &[u8]) -> nom::IResult<&[u8], AppCloseFrame> {
  function be_quic_close_frame (line 199) | fn be_quic_close_frame(input: &[u8]) -> nom::IResult<&[u8], QuicCloseFra...
  function connection_close_frame_at_layer (line 225) | pub fn connection_close_frame_at_layer(
  method put_frame (line 238) | fn put_frame(&mut self, frame: &ConnectionCloseFrame) {
  function test_connection_close_frame (line 273) | fn test_connection_close_frame() {
  function test_read_connection_close_frame (line 281) | fn test_read_connection_close_frame() {
  function test_write_connection_close_frame (line 306) | fn test_write_connection_close_frame() {

FILE: qbase/src/frame/crypto.rs
  type CryptoFrame (line 25) | pub struct CryptoFrame {
    method frame_type (line 31) | fn frame_type(&self) -> super::FrameType {
    method max_encoding_size (line 37) | fn max_encoding_size(&self) -> usize {
    method encoding_size (line 41) | fn encoding_size(&self) -> usize {
    method new (line 48) | pub fn new(offset: VarInt, length: VarInt) -> Self {
    method offset (line 53) | pub fn offset(&self) -> u64 {
    method len (line 58) | pub fn len(&self) -> u64 {
    method estimate_max_capacity (line 68) | pub fn estimate_max_capacity(capacity: usize, offset: u64) -> Option<u...
    method range (line 95) | pub fn range(&self) -> Range<u64> {
  function be_crypto_frame (line 104) | pub fn be_crypto_frame(input: &[u8]) -> nom::IResult<&[u8], CryptoFrame> {
  method put_data_frame (line 120) | fn put_data_frame(&mut self, frame: &CryptoFrame, data: &D) {
  function test_crypto_frame (line 141) | fn test_crypto_frame() {
  function test_read_crypto_frame (line 152) | fn test_read_crypto_frame() {
  function test_write_crypto_frame (line 164) | fn test_write_crypto_frame() {
  function test_encoding_capacity_estimate (line 176) | fn test_encoding_capacity_estimate() {
  function test_encoding_with_offset_exceeded (line 193) | fn test_encoding_with_offset_exceeded() {
  function test_encoding_with_length_too_large (line 199) | fn test_encoding_with_length_too_large() {

FILE: qbase/src/frame/data_blocked.rs
  type DataBlockedFrame (line 18) | pub struct DataBlockedFrame {
    method frame_type (line 23) | fn frame_type(&self) -> super::FrameType {
    method max_encoding_size (line 29) | fn max_encoding_size(&self) -> usize {
    method encoding_size (line 33) | fn encoding_size(&self) -> usize {
    method new (line 40) | pub fn new(limit: VarInt) -> Self {
    method limit (line 45) | pub fn limit(&self) -> u64 {
  function be_data_blocked_frame (line 52) | pub fn be_data_blocked_frame(input: &[u8]) -> nom::IResult<&[u8], DataBl...
  method put_frame (line 58) | fn put_frame(&mut self, frame: &DataBlockedFrame) {
  function test_data_blocked_frame (line 73) | fn test_data_blocked_frame() {
  function test_read_data_blocked_frame (line 81) | fn test_read_data_blocked_frame() {
  function test_write_data_blocked_frame (line 89) | fn test_write_data_blocked_frame() {

FILE: qbase/src/frame/datagram.rs
  type DatagramFrame (line 24) | pub struct DatagramFrame {
    method new (line 31) | pub fn new(encode_len: bool, len: VarInt) -> Self {
    method encode_len (line 36) | pub fn encode_len(&self) -> bool {
    method len (line 41) | pub fn len(&self) -> VarInt {
    method max_encoding_size (line 53) | fn max_encoding_size(&self) -> usize {
    method encoding_size (line 57) | fn encoding_size(&self) -> usize {
  method frame_type (line 47) | fn frame_type(&self) -> FrameType {
  function datagram_frame_with_flag (line 68) | pub fn datagram_frame_with_flag(flag: u8) -> impl FnOnce(&[u8]) -> IResu...
  method put_data_frame (line 93) | fn put_data_frame(&mut self, frame: &DatagramFrame, data: &D) {
  function test_datagram_frame (line 108) | fn test_datagram_frame() {
  function test_datagram_frame_with_flag (line 119) | fn test_datagram_frame_with_flag() {
  function test_datagram_frame_with_flag_no_length (line 131) | fn test_datagram_frame_with_flag_no_length() {
  function test_put_datagram_frame_with_length (line 143) | fn test_put_datagram_frame_with_length() {
  function test_put_datagram_frame_no_length (line 154) | fn test_put_datagram_frame_no_length() {

FILE: qbase/src/frame/error.rs
  type Error (line 13) | pub enum Error {
    method from (line 55) | fn from(error: nom::Err<Error>) -> Self {
    method from_error_kind (line 66) | fn from_error_kind(_input: &[u8], _kind: NomErrorKind) -> Self {
    method append (line 71) | fn append(_input: &[u8], _kind: NomErrorKind, source: Self) -> Self {
  method from (line 29) | fn from(e: Error) -> Self {
  function test_error_conversion_to_transport_error (line 92) | fn test_error_conversion_to_transport_error() {
  function test_nom_error_conversion (line 124) | fn test_nom_error_conversion() {
  function test_parse_error_impl (line 136) | fn test_parse_error_impl() {
  function test_parse_error_unreachable (line 144) | fn test_parse_error_unreachable() {
  function test_error_display (line 149) | fn test_error_display() {

FILE: qbase/src/frame/handshake_done.rs
  type HandshakeDoneFrame (line 14) | pub struct HandshakeDoneFrame;
    method frame_type (line 17) | fn frame_type(&self) -> super::FrameType {
  function be_handshake_done_frame (line 27) | pub fn be_handshake_done_frame(input: &[u8]) -> nom::IResult<&[u8], Hand...
  method put_frame (line 32) | fn put_frame(&mut self, frame: &HandshakeDoneFrame) {
  function test_handshake_done_frame (line 48) | fn test_handshake_done_frame() {
  function test_read_handshake_done_frame (line 55) | fn test_read_handshake_done_frame() {
  function test_write_handshake_done_frame (line 76) | fn test_write_handshake_done_frame() {

FILE: qbase/src/frame/io.rs
  function complete_frame (line 29) | fn complete_frame(
  function be_frame (line 128) | pub fn be_frame(raw: &Bytes, packet_type: Type) -> Result<(usize, Frame,...
  type WriteFrame (line 155) | pub trait WriteFrame<F>: bytes::BufMut {
    method put_frame (line 157) | fn put_frame(&mut self, frame: &F);
  method put_frame (line 166) | fn put_frame(&mut self, frame: &Frame<D>) {
  type WriteDataFrame (line 200) | pub trait WriteDataFrame<F, D: ContinuousData>: bytes::BufMut {
    method put_data_frame (line 202) | fn put_data_frame(&mut self, frame: &F, data: &D);
  type WriteFrameType (line 206) | pub trait WriteFrameType: bytes::BufMut {
    method put_frame_type (line 208) | fn put_frame_type(&mut self, frame_type: FrameType);
    method put_frame_type (line 212) | fn put_frame_type(&mut self, frame_type: FrameType) {
  type SendFrame (line 224) | pub trait SendFrame<T> {
    method send_frame (line 226) | fn send_frame<I: IntoIterator<Item = T>>(&self, iter: I);
  type ReceiveFrame (line 234) | pub trait ReceiveFrame<T> {
    method recv_frame (line 238) | fn recv_frame(&self, frame: T) -> Result<Self::Output, crate::error::E...
  type Output (line 242) | type Output = Result<Option<F>, ResetError>;
  method poll (line 244) | fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Outpu...
  type Output (line 269) | type Output = ();
  function recv_frame (line 271) | fn recv_frame(&self, frame: F) -> Result<Self::Output, crate::error::Err...

FILE: qbase/src/frame/max_data.rs
  type MaxDataFrame (line 18) | pub struct MaxDataFrame {
    method frame_type (line 23) | fn frame_type(&self) -> super::FrameType {
    method max_encoding_size (line 29) | fn max_encoding_size(&self) -> usize {
    method encoding_size (line 33) | fn encoding_size(&self) -> usize {
    method new (line 40) | pub fn new(max_data: VarInt) -> Self {
    method max_data (line 45) | pub fn max_data(&self) -> u64 {
  function be_max_data_frame (line 52) | pub fn be_max_data_frame(input: &[u8]) -> nom::IResult<&[u8], MaxDataFra...
  method put_frame (line 58) | fn put_frame(&mut self, frame: &MaxDataFrame) {
  function test_max_data_frame (line 76) | fn test_max_data_frame() {
  function test_read_max_data_frame (line 84) | fn test_read_max_data_frame() {
  function test_write_max_data_frame (line 105) | fn test_write_max_data_frame() {

FILE: qbase/src/frame/max_stream_data.rs
  type MaxStreamDataFrame (line 20) | pub struct MaxStreamDataFrame {
    method new (line 27) | pub fn new(stream_id: StreamId, max_stream_data: VarInt) -> Self {
    method stream_id (line 35) | pub fn stream_id(&self) -> StreamId {
    method max_stream_data (line 40) | pub fn max_stream_data(&self) -> u64 {
    method frame_type (line 46) | fn frame_type(&self) -> super::FrameType {
    method max_encoding_size (line 52) | fn max_encoding_size(&self) -> usize {
    method encoding_size (line 56) | fn encoding_size(&self) -> usize {
  function be_max_stream_data_frame (line 63) | pub fn be_max_stream_data_frame(input: &[u8]) -> nom::IResult<&[u8], Max...
  method put_frame (line 76) | fn put_frame(&mut self, frame: &MaxStreamDataFrame) {
  function test_max_stream_data_frame (line 95) | fn test_max_stream_data_frame() {
  function test_read_max_stream_data_frame (line 106) | fn test_read_max_stream_data_frame() {
  function test_write_max_stream_data_frame (line 115) | fn test_write_max_stream_data_frame() {

FILE: qbase/src/frame/max_streams.rs
  type MaxStreamsFrame (line 19) | pub enum MaxStreamsFrame {
    method with (line 25) | pub fn with(dir: Dir, max_streams: VarInt) -> Self {
    method frame_type (line 34) | fn frame_type(&self) -> super::FrameType {
    method max_encoding_size (line 43) | fn max_encoding_size(&self) -> usize {
    method encoding_size (line 47) | fn encoding_size(&self) -> usize {
  function max_streams_frame_with_dir (line 57) | pub fn max_streams_frame_with_dir(
  method put_frame (line 80) | fn put_frame(&mut self, frame: &MaxStreamsFrame) {
  function test_max_streams_frame (line 109) | fn test_max_streams_frame() {
  function test_read_max_streams_frame (line 122) | fn test_read_max_streams_frame() {
  function test_read_too_large_max_streams_frame (line 153) | fn test_read_too_large_max_streams_frame() {
  function test_write_max_streams_frame (line 175) | fn test_write_max_streams_frame() {

FILE: qbase/src/frame/new_connection_id.rs
  type NewConnectionIdFrame (line 24) | pub struct NewConnectionIdFrame {
    method new (line 33) | pub fn new(cid: ConnectionId, sequence: VarInt, retire_prior_to: VarIn...
    method sequence (line 44) | pub fn sequence(&self) -> u64 {
    method retire_prior_to (line 49) | pub fn retire_prior_to(&self) -> u64 {
    method connection_id (line 54) | pub fn connection_id(&self) -> &ConnectionId {
    method reset_token (line 59) | pub fn reset_token(&self) -> &ResetToken {
    method frame_type (line 65) | fn frame_type(&self) -> super::FrameType {
    method max_encoding_size (line 71) | fn max_encoding_size(&self) -> usize {
    method encoding_size (line 75) | fn encoding_size(&self) -> usize {
  function be_new_connection_id_frame (line 86) | pub fn be_new_connection_id_frame(input: &[u8]) -> nom::IResult<&[u8], N...
  method put_frame (line 122) | fn put_frame(&mut self, frame: &NewConnectionIdFrame) {
  function test_new_connection_id_frame (line 142) | fn test_new_connection_id_frame() {
  function test_frame_parsing (line 164) | fn test_frame_parsing() {
  function test_invalid_retire_prior_to (line 186) | fn test_invalid_retire_prior_to() {
  function test_zero_length_connection_id (line 196) | fn test_zero_length_connection_id() {

FILE: qbase/src/frame/new_token.rs
  type NewTokenFrame (line 20) | pub struct NewTokenFrame {
    method frame_type (line 26) | fn frame_type(&self) -> super::FrameType {
    method max_encoding_size (line 32) | fn max_encoding_size(&self) -> usize {
    method encoding_size (line 37) | fn encoding_size(&self) -> usize {
    method new (line 44) | pub fn new(token: Vec<u8>) -> Self {
    method from_slice (line 49) | pub fn from_slice(token: &[u8]) -> Self {
    method token (line 56) | pub fn token(&self) -> &[u8] {
  function be_new_token_frame (line 63) | pub fn be_new_token_frame(input: &[u8]) -> nom::IResult<&[u8], NewTokenF...
  method put_frame (line 76) | fn put_frame(&mut self, frame: &NewTokenFrame) {
  function test_new_token_frame (line 90) | fn test_new_token_frame() {
  function test_read_new_token_frame (line 98) | fn test_read_new_token_frame() {
  function test_write_new_token_frame (line 107) | fn test_write_new_token_frame() {

FILE: qbase/src/frame/padding.rs
  type PaddingFrame (line 13) | pub struct PaddingFrame;
    method frame_type (line 16) | fn frame_type(&self) -> super::FrameType {
  function be_padding_frame (line 26) | pub fn be_padding_frame(input: &[u8]) -> nom::IResult<&[u8], PaddingFram...
  method put_frame (line 31) | fn put_frame(&mut self, frame: &PaddingFrame) {
  function test_padding_frame (line 48) | fn test_padding_frame() {
  function test_read_padding_frame (line 55) | fn test_read_padding_frame() {
  function test_write_padding_frame (line 75) | fn test_write_padding_frame() {

FILE: qbase/src/frame/path_challenge.rs
  type PathChallengeFrame (line 17) | pub struct PathChallengeFrame {
    method from_slice (line 23) | pub fn from_slice(data: &[u8]) -> Self {
    method random (line 29) | pub fn random() -> Self {
    method frame_type (line 38) | fn frame_type(&self) -> super::FrameType {
    method max_encoding_size (line 44) | fn max_encoding_size(&self) -> usize {
    method encoding_size (line 48) | fn encoding_size(&self) -> usize {
  function be_path_challenge_frame (line 55) | pub fn be_path_challenge_frame(input: &[u8]) -> nom::IResult<&[u8], Path...
  method put_frame (line 62) | fn put_frame(&mut self, frame: &PathChallengeFrame) {
  function test_path_challenge_frame (line 81) | fn test_path_challenge_frame() {
  function test_read_path_challenge_frame (line 91) | fn test_read_path_challenge_frame() {
  function test_write_path_challenge_frame (line 115) | fn test_write_path_challenge_frame() {

FILE: qbase/src/frame/path_response.rs
  type PathResponseFrame (line 18) | pub struct PathResponseFrame {
    method from_slice (line 24) | fn from_slice(data: &[u8]) -> Self {
    method from (line 33) | fn from(challenge: super::PathChallengeFrame) -> Self {
    method frame_type (line 39) | fn frame_type(&self) -> super::FrameType {
    method max_encoding_size (line 45) | fn max_encoding_size(&self) -> usize {
    method encoding_size (line 49) | fn encoding_size(&self) -> usize {
  function be_path_response_frame (line 56) | pub fn be_path_response_frame(input: &[u8]) -> nom::IResult<&[u8], PathR...
  method put_frame (line 62) | fn put_frame(&mut self, frame: &PathResponseFrame) {
  function test_path_response_frame (line 77) | fn test_path_response_frame() {
  function test_read_path_response_frame (line 86) | fn test_read_path_response_frame() {
  function test_write_path_response_frame (line 114) | fn test_write_path_response_frame() {

FILE: qbase/src/frame/ping.rs
  type PingFrame (line 13) | pub struct PingFrame;
    method frame_type (line 16) | fn frame_type(&self) -> super::FrameType {
  function be_ping_frame (line 26) | pub fn be_ping_frame(input: &[u8]) -> nom::IResult<&[u8], PingFrame> {
  method put_frame (line 31) | fn put_frame(&mut self, frame: &PingFrame) {
  function test_ping_frame (line 47) | fn test_ping_frame() {
  function test_read_ping_frame (line 54) | fn test_read_ping_frame() {
  function test_write_ping_frame (line 75) | fn test_write_ping_frame() {

FILE: qbase/src/frame/punch_done.rs
  type PunchDoneFrame (line 17) | pub struct PunchDoneFrame {
    method new (line 24) | pub fn new(local_seq: u32, remote_seq: u32, probe_id: u32) -> Self {
    method local_seq (line 32) | pub fn local_seq(&self) -> u32 {
    method remote_seq (line 36) | pub fn remote_seq(&self) -> u32 {
    method probe_id (line 40) | pub fn probe_id(&self) -> u32 {
    method respond_to (line 46) | pub fn respond_to(hello: &PunchHelloFrame) -> Self {
  method frame_type (line 52) | fn frame_type(&self) -> super::FrameType {
  method max_encoding_size (line 58) | fn max_encoding_size(&self) -> usize {
  method encoding_size (line 62) | fn encoding_size(&self) -> usize {
  method put_frame (line 71) | fn put_frame(&mut self, frame: &PunchDoneFrame) {
  function be_punch_done_frame (line 79) | pub(crate) fn be_punch_done_frame(input: &[u8]) -> nom::IResult<&[u8], P...

FILE: qbase/src/frame/punch_hello.rs
  type PunchHelloFrame (line 14) | pub struct PunchHelloFrame {
    method new (line 21) | pub fn new(local_seq: u32, remote_seq: u32, probe_id: u32) -> Self {
    method local_seq (line 29) | pub fn local_seq(&self) -> u32 {
    method remote_seq (line 33) | pub fn remote_seq(&self) -> u32 {
    method probe_id (line 37) | pub fn probe_id(&self) -> u32 {
  method frame_type (line 43) | fn frame_type(&self) -> super::FrameType {
  method max_encoding_size (line 49) | fn max_encoding_size(&self) -> usize {
  method encoding_size (line 53) | fn encoding_size(&self) -> usize {
  method put_frame (line 62) | fn put_frame(&mut self, frame: &PunchHelloFrame) {
  function be_punch_hello_frame (line 70) | pub(crate) fn be_punch_hello_frame(input: &[u8]) -> nom::IResult<&[u8], ...

FILE: qbase/src/frame/punch_me_now.rs
  type PunchMeNowFrame (line 29) | pub struct PunchMeNowFrame {
    method new (line 88) | pub fn new(
    method local_seq (line 104) | pub fn local_seq(&self) -> u32 {
    method remote_seq (line 108) | pub fn remote_seq(&self) -> u32 {
    method nat_type (line 112) | pub fn nat_type(&self) -> NatType {
    method set_addr (line 116) | pub fn set_addr(&mut self, addr: SocketAddr) {
    method address (line 120) | pub fn address(&self) -> SocketAddr {
    method tire (line 124) | pub fn tire(&self) -> u32 {
  function be_punch_me_now_frame (line 38) | pub(crate) fn be_punch_me_now_frame(
  method frame_type (line 67) | fn frame_type(&self) -> super::FrameType {
  method max_encoding_size (line 73) | fn max_encoding_size(&self) -> usize {
  method encoding_size (line 77) | fn encoding_size(&self) -> usize {
  method put_frame (line 130) | fn put_frame(&mut self, frame: &PunchMeNowFrame) {
  function test_punch_me_now_frame (line 152) | fn test_punch_me_now_frame() {

FILE: qbase/src/frame/remove_address.rs
  type RemoveAddressFrame (line 14) | pub struct RemoveAddressFrame {
  function be_remove_address_frame (line 19) | pub(crate) fn be_remove_address_frame(input: &[u8]) -> nom::IResult<&[u8...
  method frame_type (line 30) | fn frame_type(&self) -> super::FrameType {
  method max_encoding_size (line 36) | fn max_encoding_size(&self) -> usize {
  method encoding_size (line 40) | fn encoding_size(&self) -> usize {
  method put_frame (line 46) | fn put_frame(&mut self, frame: &RemoveAddressFrame) {
  function test_remove_address_frame (line 60) | fn test_remove_address_frame() {

FILE: qbase/src/frame/reset_stream.rs
  type ResetStreamFrame (line 23) | pub struct ResetStreamFrame {
    method frame_type (line 30) | fn frame_type(&self) -> super::FrameType {
    method max_encoding_size (line 36) | fn max_encoding_size(&self) -> usize {
    method encoding_size (line 40) | fn encoding_size(&self) -> usize {
    method new (line 49) | pub fn new(stream_id: StreamId, app_error_code: VarInt, final_size: Va...
    method stream_id (line 58) | pub fn stream_id(&self) -> StreamId {
    method app_error_code (line 63) | pub fn app_error_code(&self) -> u64 {
    method final_size (line 68) | pub fn final_size(&self) -> u64 {
  function be_reset_stream_frame (line 75) | pub fn be_reset_stream_frame(input: &[u8]) -> nom::IResult<&[u8], ResetS...
  method put_frame (line 89) | fn put_frame(&mut self, frame: &ResetStreamFrame) {
  type ResetStreamError (line 99) | pub struct ResetStreamError {
    method new (line 105) | pub fn new(app_error_code: VarInt, final_size: VarInt) -> Self {
    method error_code (line 112) | pub fn error_code(&self) -> u64 {
    method combine (line 116) | pub fn combine(self, sid: StreamId) -> ResetStreamFrame {
    method from (line 126) | fn from(frame: &ResetStreamFrame) -> Self {
  function test_reset_stream_frame (line 148) | fn test_reset_stream_frame() {
  function test_read_reset_stream_frame (line 169) | fn test_read_reset_stream_frame() {
  function test_write_reset_stream_frame (line 194) | fn test_write_reset_stream_frame() {

FILE: qbase/src/frame/retire_connection_id.rs
  type RetireConnectionIdFrame (line 18) | pub struct RetireConnectionIdFrame {
    method frame_type (line 23) | fn frame_type(&self) -> super::FrameType {
    method max_encoding_size (line 29) | fn max_encoding_size(&self) -> usize {
    method encoding_size (line 33) | fn encoding_size(&self) -> usize {
    method new (line 40) | pub fn new(sequence: VarInt) -> Self {
    method sequence (line 45) | pub fn sequence(&self) -> u64 {
  function be_retire_connection_id_frame (line 52) | pub fn be_retire_connection_id_frame(input: &[u8]) -> nom::IResult<&[u8]...
  method put_frame (line 58) | fn put_frame(&mut self, frame: &RetireConnectionIdFrame) {
  function test_retire_connection_id_frame (line 76) | fn test_retire_connection_id_frame() {
  function test_read_retire_connection_id_frame (line 85) | fn test_read_retire_connection_id_frame() {
  function test_write_retire_connection_id_frame (line 96) | fn test_write_retire_connection_id_frame() {

FILE: qbase/src/frame/stop_sending.rs
  type StopSendingFrame (line 20) | pub struct StopSendingFrame {
    method new (line 27) | pub fn new(stream_id: StreamId, app_err_code: VarInt) -> Self {
    method stream_id (line 35) | pub fn stream_id(&self) -> StreamId {
    method app_err_code (line 40) | pub fn app_err_code(&self) -> u64 {
    method reset_stream (line 45) | pub fn reset_stream(&self, final_size: VarInt) -> super::ResetStreamFr...
    method frame_type (line 51) | fn frame_type(&self) -> super::FrameType {
    method max_encoding_size (line 57) | fn max_encoding_size(&self) -> usize {
    method encoding_size (line 61) | fn encoding_size(&self) -> usize {
  function be_stop_sending_frame (line 68) | pub fn be_stop_sending_frame(input: &[u8]) -> nom::IResult<&[u8], StopSe...
  method put_frame (line 80) | fn put_frame(&mut self, frame: &StopSendingFrame) {
  function test_stop_sending_frame (line 99) | fn test_stop_sending_frame() {
  function test_parse_stop_sending_frame (line 110) | fn test_parse_stop_sending_frame() {
  function test_write_stop_sending_frame (line 132) | fn test_write_stop_sending_frame() {

FILE: qbase/src/frame/stream.rs
  type Offset (line 13) | pub enum Offset {
    method from (line 30) | fn from(value: u64) -> Self {
  function from (line 21) | fn from(offset: Offset) -> u8 {
  type Len (line 40) | pub enum Len {
    method from (line 57) | fn from(value: u64) -> Self {
  function from (line 48) | fn from(length: Len) -> u8 {
  type Fin (line 67) | pub enum Fin {
    method from (line 84) | fn from(value: u64) -> Self {
  function from (line 75) | fn from(fin: Fin) -> u8 {
  type StreamFrame (line 112) | pub struct StreamFrame {
    method max_encoding_size (line 134) | fn max_encoding_size(&self) -> usize {
    method encoding_size (line 138) | fn encoding_size(&self) -> usize {
    method new (line 176) | pub fn new(id: StreamId, offset: u64, length: usize) -> Self {
    method stream_id (line 189) | pub fn stream_id(&self) -> StreamId {
    method is_fin (line 194) | pub fn is_fin(&self) -> bool {
    method offset (line 199) | pub fn offset(&self) -> u64 {
    method len (line 204) | pub fn len(&self) -> usize {
    method is_empty (line 209) | pub fn is_empty(&self) -> bool {
    method range (line 214) | pub fn range(&self) -> Range<u64> {
    method set_eos_flag (line 219) | pub fn set_eos_flag(&mut self, is_eos: bool) {
    method set_len_bit (line 228) | pub fn set_len_bit(&mut self, len_bit: Len) {
    method encoding_strategy (line 242) | pub fn encoding_strategy(&self, capacity: usize) -> EncodingStrategy {
    method estimate_max_capacity (line 280) | pub fn estimate_max_capacity(capacity: usize, sid: StreamId, offset: u...
  constant STREAM_FRAME_MAX_ENCODING_SIZE (line 120) | pub const STREAM_FRAME_MAX_ENCODING_SIZE: usize = 1 + 8 + 8 + 8;
  method frame_type (line 123) | fn frame_type(&self) -> super::FrameType {
  type EncodingStrategy (line 157) | pub struct EncodingStrategy {
    method len_bit (line 164) | pub fn len_bit(&self) -> Len {
    method pre_padding (line 169) | pub fn pre_padding(&self) -> usize {
  function stream_frame_with_flag (line 296) | pub fn stream_frame_with_flag(
  method put_data_frame (line 338) | fn put_data_frame(&mut self, frame: &StreamFrame, data: &D) {
  function test_stream_frame (line 365) | fn test_stream_frame() {
  function test_read_stream_frame (line 382) | fn test_read_stream_frame() {
  function test_read_last_stream_frame (line 416) | fn test_read_last_stream_frame() {
  function test_write_initial_stream_frame (line 450) | fn test_write_initial_stream_frame() {
  function test_write_last_stream_frame (line 470) | fn test_write_last_stream_frame() {
  function test_write_eos_frame (line 489) | fn test_write_eos_frame() {
  function test_write_unfinished_stream_frame (line 509) | fn test_write_unfinished_stream_frame() {

FILE: qbase/src/frame/stream_data_blocked.rs
  type StreamDataBlockedFrame (line 20) | pub struct StreamDataBlockedFrame {
    method frame_type (line 26) | fn frame_type(&self) -> super::FrameType {
    method max_encoding_size (line 32) | fn max_encoding_size(&self) -> usize {
    method encoding_size (line 36) | fn encoding_size(&self) -> usize {
    method new (line 43) | pub fn new(stream_id: StreamId, maximum_stream_data: VarInt) -> Self {
    method stream_id (line 51) | pub fn stream_id(&self) -> StreamId {
    method maximum_stream_data (line 56) | pub fn maximum_stream_data(&self) -> u64 {
  function be_stream_data_blocked_frame (line 63) | pub fn be_stream_data_blocked_frame(input: &[u8]) -> nom::IResult<&[u8],...
  method put_frame (line 76) | fn put_frame(&mut self, frame: &StreamDataBlockedFrame) {
  function test_stream_data_blocked_frame (line 95) | fn test_stream_data_blocked_frame() {
  function test_read_stream_data_blocked (line 106) | fn test_read_stream_data_blocked() {
  function test_write_stream_data_blocked_frame (line 117) | fn test_write_stream_data_blocked_frame() {

FILE: qbase/src/frame/streams_blocked.rs
  type StreamsBlockedFrame (line 19) | pub enum StreamsBlockedFrame {
    method with (line 25) | pub fn with(dir: Dir, max_streams: VarInt) -> Self {
    method frame_type (line 34) | fn frame_type(&self) -> super::FrameType {
    method max_encoding_size (line 43) | fn max_encoding_size(&self) -> usize {
    method encoding_size (line 47) | fn encoding_size(&self) -> usize {
  function streams_blocked_frame_with_dir (line 57) | pub fn streams_blocked_frame_with_dir(
  method put_frame (line 73) | fn put_frame(&mut self, frame: &StreamsBlockedFrame) {
  function test_stream_data_blocked_frame (line 100) | fn test_stream_data_blocked_frame() {
  function test_read_streams_blocked_frame (line 113) | fn test_read_streams_blocked_frame() {
  function test_write_streams_blocked_frame (line 149) | fn test_write_streams_blocked_frame() {

FILE: qbase/src/handshake.rs
  type ClientHandshake (line 23) | pub struct ClientHandshake {
    method is_handshake_done (line 29) | pub fn is_handshake_done(&self) -> bool {
    method recv_handshake_done_frame (line 39) | pub fn recv_handshake_done_frame(&self, _frame: HandshakeDoneFrame) ->...
  type ServerHandshake (line 59) | pub struct ServerHandshake<T>
  function new (line 75) | pub fn new(output: T) -> Self {
  function is_handshake_done (line 83) | pub fn is_handshake_done(&self) -> bool {
  function done (line 100) | pub fn done(&self) -> bool {
  type Handshake (line 119) | pub enum Handshake<T>
  function new (line 134) | pub fn new(role: Role, output: T) -> Self {
  function new_client (line 142) | pub fn new_client() -> Self {
  function new_server (line 149) | pub fn new_server(output: T) -> Self {
  function is_handshake_done (line 154) | pub fn is_handshake_done(&self) -> bool {
  function done (line 166) | pub fn done(&self) -> bool {
  function role (line 174) | pub fn role(&self) -> Role {
  type Output (line 186) | type Output = bool;
  function recv_frame (line 197) | fn recv_frame(&self, frame: HandshakeDoneFrame) -> Result<bool, Error> {
  type HandshakeDoneFrameTx (line 221) | struct HandshakeDoneFrameTx(ArcAsyncDeque<HandshakeDoneFrame>);
    method send_frame (line 224) | fn send_frame<I: IntoIterator<Item = HandshakeDoneFrame>>(&self, iter:...
  function test_client_handshake (line 230) | fn test_client_handshake() {
  function test_client_handshake_done (line 240) | fn test_client_handshake_done() {
  function test_server_handshake (line 253) | fn test_server_handshake() {
  function test_server_recv_handshake_done_frame (line 266) | fn test_server_recv_handshake_done_frame() {
  function test_server_send_handshake_done_frame (line 282) | fn test_server_send_handshake_done_frame() {

FILE: qbase/src/lib.rs
  type Epoch (line 58) | pub enum Epoch {
    constant EPOCHS (line 69) | pub const EPOCHS: [Epoch; 3] = [Epoch::Initial, Epoch::Handshake, Epoc...
    method iter (line 73) | pub fn iter() -> std::slice::Iter<'static, Epoch> {
    method count (line 78) | pub const fn count() -> usize {
  type GetEpoch (line 64) | pub trait GetEpoch {
    method epoch (line 65) | fn epoch(&self) -> Epoch;
  type Output (line 87) | type Output = T;
  function index (line 89) | fn index(&self, index: Epoch) -> &Self::Output {
  function index_mut (line 98) | fn index_mut(&mut self, index: Epoch) -> &mut Self::Output {
  type Receiving (line 104) | pub enum Receiving<F> {
  function recv_frame (line 114) | fn recv_frame(&mut self, frame: F) {
  function reset (line 127) | fn reset(&mut self) {
  type ResetError (line 136) | pub struct ResetError;
  type ArcReceiving (line 139) | pub struct ArcReceiving<F>(Arc<Mutex<Receiving<F>>>);
  function reset (line 142) | pub fn reset(&self) {
  type Output (line 148) | type Output = Result<Option<F>, ResetError>;
  method poll (line 150) | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {

FILE: qbase/src/metric.rs
  type ConnectionMetrics (line 13) | pub struct ConnectionMetrics {
    method new_pending (line 26) | pub fn new_pending(&self, bytes: u64) {
    method on_data_sent (line 34) | pub fn on_data_sent(&self, bytes: u64) {
    method on_data_acked (line 43) | pub fn on_data_acked(&self, bytes: u64) {
    method pending_bytes (line 49) | pub fn pending_bytes(&self) -> u64 {
    method inflight_bytes (line 54) | pub fn inflight_bytes(&self) -> u64 {
    method acked_bytes (line 59) | pub fn acked_bytes(&self) -> u64 {
  type ArcConnectionMetrics (line 65) | pub type ArcConnectionMetrics = Arc<ConnectionMetrics>;
  function test_connection_metrics_new (line 72) | fn test_connection_metrics_new() {
  function test_add_pending_send (line 80) | fn test_add_pending_send() {
  function test_on_data_sent (line 89) | fn test_on_data_sent() {
  function test_on_data_acked (line 98) | fn test_on_data_acked() {
  function test_full_data_flow (line 109) | fn test_full_data_flow() {
  function test_arc_connection_metrics (line 144) | fn test_arc_connection_metrics() {

FILE: qbase/src/net.rs
  type Family (line 29) | pub enum Family {
  method fmt (line 37) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  type UnknownFamily (line 52) | pub struct UnknownFamily;
  type Err (line 55) | type Err = UnknownFamily;
  method from_str (line 57) | fn from_str(s: &str) -> Result<Self, Self::Err> {
  type AddrFamily (line 66) | pub trait AddrFamily {
    method family (line 70) | fn family(&self) -> Family;
    method family (line 74) | fn family(&self) -> Family {
    method family (line 80) | fn family(&self) -> Family {
    method family (line 86) | fn family(&self) -> Family {
    method family (line 95) | fn family(&self) -> Family {
  type WriteSocketAddr (line 100) | pub trait WriteSocketAddr {
    method put_socket_addr (line 101) | fn put_socket_addr(&mut self, addr: &SocketAddr);
    method put_socket_addr (line 105) | fn put_socket_addr(&mut self, addr: &SocketAddr) {
  function be_socket_addr (line 114) | pub fn be_socket_addr(input: &[u8], family: Family) -> IResult<&[u8], So...
  function be_ip_addr (line 121) | pub fn be_ip_addr(family: Family) -> impl Fn(&[u8]) -> IResult<&[u8], Ip...
  method max_encoding_size (line 129) | fn max_encoding_size(&self) -> usize {
  method encoding_size (line 133) | fn encoding_size(&self) -> usize {
  function test_ip_family_display_and_parse (line 146) | fn test_ip_family_display_and_parse() {

FILE: qbase/src/net/addr.rs
  type EndpointAddr (line 14) | pub enum EndpointAddr {
    method direct (line 25) | pub fn direct(addr: SocketAddr) -> Self {
    method with_agent (line 29) | pub fn with_agent(agent: SocketAddr, outer: SocketAddr) -> Self {
    method addr (line 38) | pub fn addr(&self) -> SocketAddr {
    method encoding_size (line 45) | pub fn encoding_size(&self) -> usize {
    method from (line 139) | fn from(addr: SocketAddr) -> Self {
    method from (line 145) | fn from((agent, outer): (SocketAddr, SocketAddr)) -> Self {
  type WriteEndpointAddr (line 66) | pub trait WriteEndpointAddr {
    method put_endpoint_addr (line 67) | fn put_endpoint_addr(&mut self, endpoint: EndpointAddr);
    method put_endpoint_addr (line 71) | fn put_endpoint_addr(&mut self, endpoint: EndpointAddr) {
  function be_endpoint_addr (line 86) | pub fn be_endpoint_addr(
  method fmt (line 102) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  type Target (line 111) | type Target = SocketAddr;
  method deref (line 113) | fn deref(&self) -> &Self::Target {
  type Err (line 122) | type Err = AddrParseError;
  method from_str (line 124) | fn from_str(s: &str) -> Result<Self, Self::Err> {

FILE: qbase/src/net/nat.rs
  type NatType (line 18) | pub enum NatType {
    type Error (line 34) | type Error = io::Error;
    method try_from (line 36) | fn try_from(value: u8) -> Result<Self, Self::Error> {
    type Error (line 53) | type Error = io::Error;
    method try_from (line 55) | fn try_from(value: VarInt) -> Result<Self, Self::Error> {
    method from (line 61) | fn from(value: NetFeature) -> Self {
  method from (line 28) | fn from(nat_type: NatType) -> Self {

FILE: qbase/src/net/route.rs
  type Pathway (line 14) | pub struct Pathway<E = EndpointAddr> {
  function new (line 21) | pub fn new(local: E, remote: E) -> Self {
  function local (line 26) | pub fn local(&self) -> E
  function remote (line 34) | pub fn remote(&self) -> E
  function map (line 42) | pub fn map<E1>(self, mut f: impl FnMut(E) -> E1) -> Pathway<E1> {
  function flip (line 50) | pub fn flip(self) -> Self {
  method fmt (line 59) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  type Link (line 65) | pub struct Link {
    method new (line 118) | pub fn new(src: SocketAddr, dst: SocketAddr) -> Self {
    method flip (line 123) | pub fn flip(self) -> Self {
  method fmt (line 71) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  function be_link (line 76) | pub fn be_link(input: &[u8]) -> nom::IResult<&[u8], Link> {
  type WriteLink (line 93) | pub trait WriteLink {
    method put_link (line 94) | fn put_link(&mut self, link: &Link);
    method put_link (line 98) | fn put_link(&mut self, link: &Link) {
  method max_encoding_size (line 107) | fn max_encoding_size(&self) -> usize {
  method encoding_size (line 111) | fn encoding_size(&self) -> usize {
  function from (line 132) | fn from(link: Link) -> Self {
  type Line (line 138) | pub struct Line {
    constant DEFAULT_TTL (line 150) | pub const DEFAULT_TTL: u8 = 64;
    method new (line 152) | pub fn new(link: Link, ttl: u8, ecn: Option<u8>, seg_size: u16) -> Self {
  method default (line 163) | fn default() -> Self {
  type Route (line 177) | pub struct Route {
    method new (line 185) | pub fn new(pathway: Pathway, line: Line) -> Self {
    method empty (line 190) | pub fn empty() -> Self {
    method pathway (line 197) | pub fn pathway(&self) -> Pathway {
    method link (line 201) | pub fn link(&self) -> Link {
    method ttl (line 205) | pub fn ttl(&self) -> u8 {
    method ecn (line 209) | pub fn ecn(&self) -> Option<u8> {
    method seg_size (line 213) | pub fn seg_size(&self) -> u16 {
  function test_endpoint_addr_from_str (line 223) | fn test_endpoint_addr_from_str() {

FILE: qbase/src/net/tx.rs
  type SignalsBits (line 10) | type SignalsBits = u16;
  type SendWaker (line 29) | pub struct SendWaker {
    method new (line 36) | pub fn new() -> Self {
    constant WAITING (line 40) | const WAITING: SignalsBits = 0;
    method poll_wait_for (line 43) | pub fn poll_wait_for(&mut self, cx: &mut Context, signals: Signals) ->...
    method wake_by (line 58) | fn wake_by(&mut self, signals: Signals) {
  type ArcSendWaker (line 72) | pub struct ArcSendWaker(Arc<Mutex<SendWaker>>);
    method new (line 76) | pub fn new() -> Self {
    method wait_for (line 81) | pub async fn wait_for(&self, signals: Signals) {
    method wake_by (line 86) | pub fn wake_by(&self, signals: Signals) {
    method state (line 178) | fn state(&self) -> SignalsBits {
  type SendWakers (line 93) | pub struct SendWakers {
    method new (line 100) | pub fn new() -> Self {
    method insert (line 105) | pub fn insert(&mut self, pathway: Pathway, waker: &ArcSendWaker) {
    method remove (line 110) | pub fn remove(&mut self, pathway: &Pathway) {
    method wake_all_by (line 115) | pub fn wake_all_by(&mut self, signals: Signals) {
  type ArcSendWakers (line 145) | pub struct ArcSendWakers(Arc<Mutex<SendWakers>>);
    method new (line 149) | pub fn new() -> Self {
    method lock_guard (line 153) | fn lock_guard(&self) -> MutexGuard<'_, SendWakers> {
    method insert (line 158) | pub fn insert(&self, pathway: Pathway, waker: &ArcSendWaker) {
    method remove (line 163) | pub fn remove(&self, pathway: &Pathway) {
    method wake_all_by (line 168) | pub fn wake_all_by(&self, signals: Signals) {
  function single_condition (line 186) | async fn single_condition() {
  function all_condition (line 215) | async fn all_condition() {
  function wake_before_register (line 249) | async fn wake_before_register() {
  function state_change (line 274) | async fn state_change() {
  function mult_wake_signals (line 333) | async fn mult_wake_signals() {
  function not_wake (line 364) | async fn not_wake() {

FILE: qbase/src/packet.rs
  type DataHeader (line 66) | pub enum DataHeader {
  type DataPacket (line 86) | pub struct DataPacket {
  method get_type (line 96) | fn get_type(&self) -> Type {
  type PacketContent (line 102) | pub enum PacketContent {
    method is_ack_eliciting (line 110) | pub fn is_ack_eliciting(self) -> bool {
    method from (line 116) | fn from(frame_type: FrameType) -> Self {
    method add_assign (line 126) | fn add_assign(&mut self, rhs: FrameType) {
    method add_assign (line 136) | fn add_assign(&mut self, rhs: Self) {
  type Packet (line 149) | pub enum Packet {
  type PacketReader (line 165) | pub struct PacketReader {
    method new (line 172) | pub fn new(raw_bytes: BytesMut, dcid_len: usize) -> Self {
  type Item (line 181) | type Item = Result<Packet, error::Error>;
  method next (line 183) | fn next(&mut self) -> Option<Self::Item> {

FILE: qbase/src/packet/decrypt.rs
  function remove_protection_of_long_packet (line 27) | pub fn remove_protection_of_long_packet(
  function remove_protection_of_short_packet (line 69) | pub fn remove_protection_of_short_packet(
  function decrypt_packet (line 107) | pub fn decrypt_packet(

FILE: qbase/src/packet/encrypt.rs
  function encrypt_packet (line 20) | pub fn encrypt_packet(key: &dyn PacketKey, pn: u64, pkt_buf: &mut [u8], ...
  function protect_header (line 44) | pub fn protect_header(
  function encode_long_first_byte (line 61) | pub fn encode_long_first_byte(first_byte: &mut u8, pn_len: usize) {
  function encode_short_first_byte (line 68) | pub fn encode_short_first_byte(first_byte: &mut u8, pn_len: usize, key_p...

FILE: qbase/src/packet/error.rs
  type Error (line 8) | pub enum Error {
    method from_error_kind (line 30) | fn from_error_kind(_input: &[u8], _kind: NomErrorKind) -> Self {
    method append (line 35) | fn append(_input: &[u8], _kind: NomErrorKind, source: Self) -> Self {
  function from (line 44) | fn from(e: Error) -> Self {

FILE: qbase/src/packet/header.rs
  type GetType (line 27) | pub trait GetType {
    method get_type (line 29) | fn get_type(&self) -> Type;
  type EncodeHeader (line 38) | pub trait EncodeHeader {
    method size (line 40) | fn size(&self) -> usize {
    method length_encoding (line 44) | fn length_encoding(&self) -> usize {
  type GetDcid (line 51) | pub trait GetDcid {
    method dcid (line 53) | fn dcid(&self) -> &ConnectionId;
  type GetScid (line 58) | pub trait GetScid {
    method scid (line 60) | fn scid(&self) -> &ConnectionId;
  type Header (line 66) | pub enum Header {
  function be_header (line 94) | pub fn be_header(
  type WriteHeader (line 118) | pub trait WriteHeader<H>: bytes::BufMut {
    method put_header (line 120) | fn put_header(&mut self, header: &H);
  method put_header (line 133) | fn put_header(&mut self, header: &Header) {
  function test_read_header (line 169) | fn test_read_header() {
  function test_write_header (line 275) | fn test_write_header() {

FILE: qbase/src/packet/header/long.rs
  type LongHeader (line 27) | pub struct LongHeader<T> {
  function dcid (line 36) | fn dcid(&self) -> &ConnectionId {
  function scid (line 42) | fn scid(&self) -> &ConnectionId {
  type VersionNegotiation (line 57) | pub struct VersionNegotiation {
    method new (line 63) | pub fn new(versions: Vec<u32>) -> Self {
    method versions (line 68) | pub fn versions(&self) -> &Vec<u32> {
  type Retry (line 80) | pub struct Retry {
    method new (line 90) | pub fn new(token: &[u8], integrity: &[u8]) -> Self {
    method token (line 100) | pub fn token(&self) -> &Vec<u8> {
    method integrity (line 105) | pub fn integrity(&self) -> &[u8; 16] {
  type Initial (line 117) | pub struct Initial {
    method with_token (line 123) | pub fn with_token(token: Vec<u8>) -> Self {
    method from_slice (line 128) | pub fn from_slice(token: &[u8]) -> Self {
    method token (line 135) | pub fn token(&self) -> &Vec<u8> {
  type ZeroRtt (line 142) | pub struct ZeroRtt;
  type Handshake (line 146) | pub struct Handshake;
  method size (line 149) | fn size(&self) -> usize {
  type VersionNegotiationHeader (line 164) | pub type VersionNegotiationHeader = LongHeader<VersionNegotiation>;
  type RetryHeader (line 170) | pub type RetryHeader = LongHeader<Retry>;
  type InitialHeader (line 176) | pub type InitialHeader = LongHeader<Initial>;
  type HandshakeHeader (line 182) | pub type HandshakeHeader = LongHeader<Handshake>;
  type ZeroRttHeader (line 188) | pub type ZeroRttHeader = LongHeader<ZeroRtt>;
  method size (line 191) | fn size(&self) -> usize {
  method length_encoding (line 198) | fn length_encoding(&self) -> usize {
  type DataHeader (line 227) | pub enum DataHeader {
  function be_version_negotiation (line 261) | pub fn be_version_negotiation(input: &[u8]) -> nom::IResult<&[u8], Versi...
  function be_retry (line 268) | pub fn be_retry(input: &[u8]) -> nom::IResult<&[u8], Retry> {
  function be_initial (line 279) | pub fn be_initial(input: &[u8]) -> nom::IResult<&[u8], Initial> {
  function be_zero_rtt (line 285) | pub fn be_zero_rtt(input: &[u8]) -> nom::IResult<&[u8], ZeroRtt> {
  function be_handshake (line 291) | pub fn be_handshake(input: &[u8]) -> nom::IResult<&[u8], Handshake> {
  type LongHeaderBuilder (line 306) | pub struct LongHeaderBuilder {
    method with_cid (line 314) | pub fn with_cid(dcid: ConnectionId, scid: ConnectionId) -> Self {
    method vn (line 319) | pub fn vn(self, versions: Vec<u32>) -> LongHeader<VersionNegotiation> {
    method retry (line 324) | pub fn retry(self, token: Vec<u8>, integrity: [u8; 16]) -> LongHeader<...
    method initial (line 329) | pub fn initial(self, token: Vec<u8>) -> LongHeader<Initial> {
    method zero_rtt (line 334) | pub fn zero_rtt(self) -> LongHeader<ZeroRtt> {
    method handshake (line 339) | pub fn handshake(self) -> LongHeader<Handshake> {
    method wrap (line 345) | pub fn wrap<T>(self, specific: T) -> LongHeader<T> {
    method parse (line 357) | pub fn parse(self, ty: LongType, input: &[u8]) -> nom::IResult<&[u8], ...
  type WriteSpecific (line 386) | pub trait WriteSpecific<S>: BufMut {
    method put_specific (line 388) | fn put_specific(&mut self, _specific: &S) {}
  method put_specific (line 392) | fn put_specific(&mut self, specific: &VersionNegotiation) {
  method put_specific (line 400) | fn put_specific(&mut self, specific: &Retry) {
  method put_specific (line 407) | fn put_specific(&mut self, specific: &Initial) {
  method put_header (line 426) | fn put_header(&mut self, header: &LongHeader<S>) {
  function test_be_version_negotiation (line 441) | fn test_be_version_negotiation() {
  function test_be_retry (line 451) | fn test_be_retry() {
  function test_be_initial (line 479) | fn test_be_initial() {
  function test_write_version_negotiation_long_header (line 490) | fn test_write_version_negotiation_long_header() {
  function test_write_retry_long_header (line 503) | fn test_write_retry_long_header() {
  function test_write_initial_long_header (line 529) | fn test_write_initial_long_header() {

FILE: qbase/src/packet/header/short.rs
  type OneRttHeader (line 23) | pub struct OneRttHeader {
    method new (line 31) | pub fn new(spin: SpinBit, dcid: ConnectionId) -> Self {
    method spin (line 36) | pub fn spin(&self) -> SpinBit {
    method dcid (line 54) | fn dcid(&self) -> &ConnectionId {
  method size (line 42) | fn size(&self) -> usize {
  method get_type (line 48) | fn get_type(&self) -> Type {
  function be_one_rtt_header (line 68) | pub fn be_one_rtt_header(
  method put_header (line 80) | fn put_header(&mut self, header: &OneRttHeader) {
  function test_read_one_rtt_header (line 93) | fn test_read_one_rtt_header() {
  function test_write_one_rtt_header (line 105) | fn test_write_one_rtt_header() {

FILE: qbase/src/packet/io.rs
  function be_payload (line 24) | fn be_payload(
  function be_packet (line 47) | pub fn be_packet(datagram: &mut BytesMut, dcid_len: usize) -> Result<Pac...
  type ProductHeader (line 109) | pub trait ProductHeader<H> {
    method new_header (line 110) | fn new_header(&self) -> Result<H, Signals>;
  type PacketSpace (line 113) | pub trait PacketSpace<H> {
    method new_packet (line 118) | fn new_packet<'b>(
  type Package (line 126) | pub trait Package<Target: ?Sized> {
    method dump (line 127) | fn dump(&mut self, target: &mut Target) -> Result<PacketContent, Signa...
  function dump (line 132) | fn dump(&mut self, target: &mut Target) -> Result<PacketContent, Signals> {
  function dump (line 139) | fn dump(&mut self, target: &mut Target) -> Result<PacketContent, Signals> {
  function dump (line 146) | fn dump(&mut self, target: &mut Target) -> Result<PacketContent, Signals> {
  function dump (line 154) | fn dump(&mut self, target: &mut Target) -> Result<PacketContent, Signals> {
  function dump (line 173) | fn dump(&mut self, target: &mut Target) -> Result<PacketContent, Signals> {
  type PadTo20 (line 190) | pub struct PadTo20;
    method dump (line 197) | fn dump(&mut self, target: &mut P) -> Result<PacketContent, Signals> {
  type PadToFull (line 210) | pub struct PadToFull;
    method dump (line 217) | fn dump(&mut self, target: &mut P) -> Result<PacketContent, Signals> {
  type PadProbe (line 230) | pub struct PadProbe;
    method dump (line 237) | fn dump(&mut self, target: &mut P) -> Result<PacketContent, Signals> {
  type Repeat (line 246) | pub struct Repeat<P>(pub P);
  function dump (line 250) | fn dump(&mut self, target: &mut Target) -> Result<PacketContent, Signals> {
  type Packages (line 266) | pub struct Packages<T>(pub T);
  type Keys (line 379) | pub enum Keys {
    method hpk (line 406) | fn hpk(&self) -> &dyn rustls::quic::HeaderProtectionKey {
    method pk (line 414) | fn pk(&self) -> &dyn rustls::quic::PacketKey {
    method key_phase (line 422) | fn key_phase(&self) -> Option<KeyPhaseBit> {
  method fmt (line 390) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  type PacketLayout (line 431) | struct PacketLayout {
    method payload_len (line 441) | pub fn payload_len(&self) -> usize {
    method is_empty (line 445) | pub fn is_empty(&self) -> bool {
  type PacketInfo (line 451) | pub struct PacketInfo {
    method new (line 478) | pub fn new(ty: Type, pn: u64) -> Self {
    method epoch (line 489) | pub fn epoch(&self) -> Option<Epoch> {
    method add_frame (line 504) | pub fn add_frame<F: FrameFeature + 'static>(&mut self, frame: &F) {
    method record_frame (line 528) | fn record_frame(&mut self, frame: &Frame<D>) {
  type RecordFrame (line 523) | pub trait RecordFrame<F, D: ContinuousData> {
    method record_frame (line 524) | fn record_frame(&mut self, frame: &F);
  function record_frame (line 552) | fn record_frame(&mut self, frame: &F) {
  type PacketWriter (line 557) | pub struct PacketWriter<'b> {
  function new_long (line 565) | pub fn new_long<S>(
  function new_short (line 601) | pub fn new_short(
  function buffer (line 631) | pub fn buffer(&self) -> &[u8] {
  function is_short_header (line 636) | pub fn is_short_header(&self) -> bool {
  function packet_type (line 641) | pub fn packet_type(&self) -> Type {
  function packet_number (line 646) | pub fn packet_number(&self) -> u64 {
  function is_ack_eliciting (line 651) | pub fn is_ack_eliciting(&self) -> bool {
  function in_flight (line 656) | pub fn in_flight(&self) -> bool {
  function is_probe_new_path (line 661) | pub fn is_probe_new_path(&self) -> bool {
  function payload_len (line 666) | pub fn payload_len(&self) -> usize {
  function tag_len (line 671) | pub fn tag_len(&self) -> usize {
  function is_empty (line 676) | pub fn is_empty(&self) -> bool {
  function packet_len (line 681) | pub fn packet_len(&self) -> usize {
  method remaining_mut (line 688) | fn remaining_mut(&self) -> usize {
  method advance_mut (line 693) | unsafe fn advance_mut(&mut self, cnt: usize) {
  method chunk_mut (line 706) | fn chunk_mut(&mut self) -> &mut UninitSlice {
  type AssemblePacket (line 712) | pub trait AssemblePacket: BufMut {
    method assemble_packet (line 714) | fn assemble_packet(
    method encrypt_and_protect_packet (line 721) | fn encrypt_and_protect_packet(self) -> (usize, PacketInfo);
    method encrypt_and_protect_packet (line 725) | fn encrypt_and_protect_packet(self) -> (usize, PacketInfo) {
  type TransparentKeys (line 787) | struct TransparentKeys;
    method decrypt_in_place (line 790) | fn decrypt_in_place<'a>(
    method encrypt_in_place (line 799) | fn encrypt_in_place(
    method confidentiality_limit (line 808) | fn confidentiality_limit(&self) -> u64 {
    method integrity_limit (line 812) | fn integrity_limit(&self) -> u64 {
    method tag_len (line 816) | fn tag_len(&self) -> usize {
    method decrypt_in_place (line 822) | fn decrypt_in_place(
    method encrypt_in_place (line 831) | fn encrypt_in_place(
    method sample_len (line 840) | fn sample_len(&self) -> usize {
  function test_initial_packet_writer (line 846) | fn test_initial_packet_writer() {

FILE: qbase/src/packet/keys.rs
  type DirectionalKeys (line 17) | pub struct DirectionalKeys {
    method from (line 25) | fn from(keys: RustlsDirectionalKeys) -> Self {
  type Keys (line 35) | pub struct Keys {
    method from (line 43) | fn from(keys: RustlsKeys) -> Self {
  type KeysState (line 55) | enum KeysState<K> {
  function set (line 62) | fn set(&mut self, keys: K) {
  function get (line 75) | fn get(&mut self) -> Option<&K> {
  function invalid (line 82) | fn invalid(&mut self) -> Option<K> {
  type Output (line 97) | type Output = Option<K>;
  method poll (line 99) | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
  type ArcKeys (line 132) | pub struct ArcKeys(Arc<Mutex<KeysState<Keys>>>);
    method lock_guard (line 135) | fn lock_guard(&self) -> MutexGuard<'_, KeysState<Keys>> {
    method new_pending (line 145) | pub fn new_pending() -> Self {
    method with_keys (line 152) | pub fn with_keys(keys: Keys) -> Self {
    method get_remote_keys (line 180) | pub fn get_remote_keys(&self) -> GetRemoteKeys<'_, Keys> {
    method get_local_keys (line 207) | pub fn get_local_keys(&self) -> Option<Keys> {
    method set_keys (line 217) | pub fn set_keys(&self, keys: Keys) {
    method invalid (line 227) | pub fn invalid(&self) -> Option<Keys> {
  type GetRemoteKeys (line 234) | pub struct GetRemoteKeys<'k, K>(&'k Mutex<KeysState<K>>);
  type Output (line 237) | type Output = Option<K>;
  method poll (line 239) | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
  type ArcZeroRttKeys (line 245) | pub struct ArcZeroRttKeys {
    method new_pending (line 251) | pub fn new_pending(role: Role) -> Self {
    method lock_guard (line 258) | fn lock_guard(&self) -> MutexGuard<'_, KeysState<DirectionalKeys>> {
    method set_keys (line 262) | pub fn set_keys(&self, keys: DirectionalKeys) {
    method get_encrypt_keys (line 266) | pub fn get_encrypt_keys(&self) -> Option<DirectionalKeys> {
    method get_decrypt_keys (line 273) | pub fn get_decrypt_keys(&self) -> Option<GetRemoteKeys<'_, Directional...
    method invalid (line 280) | pub fn invalid(&self) -> Option<DirectionalKeys> {
  type OneRttPacketKeys (line 290) | pub struct OneRttPacketKeys {
    method new (line 302) | fn new(remote: Box<dyn PacketKey>, local: Box<dyn PacketKey>, secrets:...
    method update (line 316) | pub fn update(&mut self) {
    method phase_out (line 328) | pub fn phase_out(&mut self) {
    method get_remote (line 336) | pub fn get_remote(&mut self, key_phase: KeyPhaseBit, _pn: u64) -> Arc<...
    method get_local (line 346) | pub fn get_local(&self) -> (KeyPhaseBit, Arc<dyn PacketKey>) {
  type ArcOneRttPacketKeys (line 358) | pub struct ArcOneRttPacketKeys(Arc<(Mutex<OneRttPacketKeys>, usize)>);
    method lock_guard (line 364) | pub fn lock_guard(&self) -> MutexGuard<'_, OneRttPacketKeys> {
    method tag_len (line 379) | pub fn tag_len(&self) -> usize {
  type HeaderProtectionKeys (line 386) | pub struct HeaderProtectionKeys {
  type OneRttKeysState (line 391) | enum OneRttKeysState {
  type ArcOneRttKeys (line 409) | pub struct ArcOneRttKeys(Arc<Mutex<OneRttKeysState>>);
    method lock_guard (line 412) | fn lock_guard(&self) -> MutexGuard<'_, OneRttKeysState> {
    method new_pending (line 418) | pub fn new_pending() -> Self {
    method set_keys (line 427) | pub fn set_keys(&self, keys: RustlsKeys, secrets: Secrets) {
    method invalid (line 454) | pub fn invalid(&self) -> Option<(HeaderProtectionKeys, ArcOneRttPacket...
    method get_local_keys (line 473) | pub fn get_local_keys(&self) -> Option<(Arc<dyn HeaderProtectionKey>, ...
    method remote_keys (line 481) | pub fn remote_keys(&self) -> Option<(Arc<dyn HeaderProtectionKey>, Arc...
    method get_remote_keys (line 491) | pub fn get_remote_keys(&self) -> GetRemoteOneRttKeys<'_> {
  type GetRemoteOneRttKeys (line 498) | pub struct GetRemoteOneRttKeys<'k>(&'k ArcOneRttKeys);
  type Output (line 501) | type Output = Option<(Arc<dyn HeaderProtectionKey>, ArcOneRttPacketKeys)>;
  method poll (line 503) | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {

FILE: qbase/src/packet/number.rs
  type PacketNumber (line 14) | pub enum PacketNumber {
    method encode (line 90) | pub fn encode(pn: u64, largest_acked: u64) -> Self {
    method size (line 107) | pub fn size(self) -> usize {
    method decode (line 125) | pub fn decode(self, expected: u64) -> u64 {
  type InvalidPacketNumber (line 22) | pub enum InvalidPacketNumber {
  type WritePacketNumber (line 32) | pub trait WritePacketNumber {
    method put_packet_number (line 34) | fn put_packet_number(&mut self, pn: PacketNumber);
    method put_packet_number (line 38) | fn put_packet_number(&mut self, pn: PacketNumber) {
  function take_pn_len (line 66) | pub fn take_pn_len(pn_len: u8) -> impl FnMut(&[u8]) -> nom::IResult<&[u8...
  function test_read_packet_number (line 161) | fn test_read_packet_number() {
  function test_read_packet_number_too_large (line 189) | fn test_read_packet_number_too_large() {
  function test_write_packet_number (line 195) | fn test_write_packet_number() {
  function test_encode_packet_number (line 215) | fn test_encode_packet_number() {
  function test_encode_packet_number_overflow (line 225) | fn test_encode_packet_number_overflow() {

FILE: qbase/src/packet/signal.rs
  constant SPIN_BIT (line 2) | const SPIN_BIT: u8 = 0x20;
  constant KEY_PHASE_BIT (line 4) | const KEY_PHASE_BIT: u8 = 0x04;
  type Toggle (line 8) | pub enum Toggle<const B: u8> {
  type SpinBit (line 17) | pub type SpinBit = Toggle<SPIN_BIT>;
  type KeyPhaseBit (line 20) | pub type KeyPhaseBit = Toggle<KEY_PHASE_BIT>;
  function toggle (line 24) | pub fn toggle(&mut self) {
  function value (line 32) | pub fn value(&self) -> u8 {
  function imply (line 40) | pub fn imply(&self, byte: &mut u8) {
  function as_index (line 48) | pub(crate) fn as_index(&self) -> usize {
  type Output (line 57) | type Output = Self;
  function not (line 59) | fn not(self) -> Self::Output {
  function from (line 68) | fn from(value: u8) -> Self {
  function from (line 78) | fn from(value: Toggle<B>) -> Self {
  function from (line 84) | fn from(value: bool) -> Self {
  function from (line 90) | fn from(value: Toggle<B>) -> Self {

FILE: qbase/src/packet/type.rs
  constant HEADER_FORM_MASK (line 11) | const HEADER_FORM_MASK: u8 = 0x80;
  constant FIXED_BIT (line 13) | const FIXED_BIT: u8 = 0x40;
  constant LONG_RESERVED_MASK (line 16) | pub const LONG_RESERVED_MASK: u8 = 0x0C;
  constant SHORT_RESERVED_MASK (line 18) | pub const SHORT_RESERVED_MASK: u8 = 0x18;
  type SpecificBits (line 26) | pub struct SpecificBits<const R: u8>(pub(super) u8);
  type LongSpecificBits (line 32) | pub type LongSpecificBits = SpecificBits<LONG_RESERVED_MASK>;
  type ShortSpecificBits (line 38) | pub type ShortSpecificBits = SpecificBits<SHORT_RESERVED_MASK>;
    method set_key_phase (line 55) | pub fn set_key_phase(&mut self, key_phase_bit: KeyPhaseBit) {
    method key_phase (line 60) | pub fn key_phase(&self) -> KeyPhaseBit {
  function from_pn (line 42) | pub fn from_pn(pn: &PacketNumber) -> Self {
  function with_pn_len (line 47) | pub fn with_pn_len(pn_size: usize) -> Self {
  function from (line 66) | fn from(byte: u8) -> Self {
  type GetPacketNumberLength (line 77) | pub trait GetPacketNumberLength {
    constant PN_LEN_MASK (line 79) | const PN_LEN_MASK: u8 = 0x03;
    method pn_len (line 82) | fn pn_len(&self) -> Result<u8, Error>;
    method pn_len (line 86) | fn pn_len(&self) -> Result<u8, Error> {
  type Type (line 107) | pub enum Type {
    method encoding_size (line 114) | pub fn encoding_size(&self) -> usize {
  function be_packet_type (line 130) | pub fn be_packet_type(input: &[u8]) -> nom::IResult<&[u8], Type, Error> {
  type WritePacketType (line 141) | pub trait WritePacketType: BufMut {
    method put_packet_type (line 143) | fn put_packet_type(&mut self, ty: &Type);
    method put_packet_type (line 147) | fn put_packet_type(&mut self, ty: &Type) {
  function test_long_clear_bits (line 161) | fn test_long_clear_bits() {
  function test_short_specific_bits (line 189) | fn test_short_specific_bits() {
  function test_set_key_phase_bit (line 217) | fn test_set_key_phase_bit() {

FILE: qbase/src/packet/type/long.rs
  type Version (line 12) | pub struct Version<const N: u32, Ty>(#[deref] pub(crate) Ty);
  type GetVersion (line 16) | pub trait GetVersion {
    method get_version (line 18) | fn get_version(&self) -> u32;
    method get_version (line 22) | fn get_version(&self) -> u32 {
  constant RETRY (line 30) | pub const RETRY: Self = Self(v1::Type::Retry);
  constant INITIAL (line 32) | pub const INITIAL: Self = Self(v1::Type::Initial);
  constant ZERO_RTT (line 34) | pub const ZERO_RTT: Self = Self(v1::Type::ZeroRtt);
  constant HANDSHAKE (line 36) | pub const HANDSHAKE: Self = Self(v1::Type::Handshake);
  type Ver1 (line 40) | pub type Ver1 = Version<1, v1::Type>;
  type Type (line 44) | pub enum Type {
  constant LONG_HEADER_BIT (line 59) | const LONG_HEADER_BIT: u8 = 0x80;
  function parse_long_type (line 63) | pub fn parse_long_type(ty: u8) -> impl FnMut(&[u8]) -> nom::IResult<&[u8...
  type WriteLongType (line 80) | pub trait WriteLongType: BufMut {
    method put_long_type (line 82) | fn put_long_type(&mut self, value: &Type);
    method put_long_type (line 86) | fn put_long_type(&mut self, value: &Type) {
  function test_read_long_type (line 107) | fn test_read_long_type() {
  function test_read_long_type_with_wrong_version (line 123) | fn test_read_long_type_with_wrong_version() {
  function test_write_long_type (line 133) | fn test_write_long_type() {
  function test_write_version_negotiation_long_type (line 144) | fn test_write_version_negotiation_long_type() {

FILE: qbase/src/packet/type/long/v1.rs
  type Type (line 9) | pub enum Type {
    type Error (line 38) | type Error = Error;
    method try_from (line 40) | fn try_from(value: u8) -> Result<Self, Self::Error> {
  constant LONG_PACKET_TYPE_MASK (line 20) | const LONG_PACKET_TYPE_MASK: u8 = 0x30;
  constant INITIAL_PACKET_TYPE (line 21) | const INITIAL_PACKET_TYPE: u8 = 0x00;
  constant ZERO_RTT_PACKET_TYPE (line 22) | const ZERO_RTT_PACKET_TYPE: u8 = 0x10;
  constant HANDSHAKE_PACKET_TYPE (line 23) | const HANDSHAKE_PACKET_TYPE: u8 = 0x20;
  constant RETRY_PACKET_TYPE (line 24) | const RETRY_PACKET_TYPE: u8 = 0x30;
  function from (line 27) | fn from(value: Type) -> u8 {
  function test_try_from (line 58) | fn test_try_from() {

FILE: qbase/src/packet/type/short.rs
  constant SHORT_HEADER_BIT (line 6) | const SHORT_HEADER_BIT: u8 = 0x00;
  type OneRtt (line 11) | pub struct OneRtt(#[deref] pub SpinBit);
    method from (line 14) | fn from(value: u8) -> Self {
  function from (line 20) | fn from(one_rtt: OneRtt) -> Self {
  type WriteShortType (line 26) | pub trait WriteShortType: BufMut {
    method put_short_type (line 28) | fn put_short_type(&mut self, ty: &OneRtt);
    method put_short_type (line 32) | fn put_short_type(&mut self, ty: &OneRtt) {
  function test_write_short_type (line 42) | fn test_write_short_type() {

FILE: qbase/src/param.rs
  type Requirements (line 57) | enum Requirements {
  type Parameters (line 90) | pub struct Parameters {
    constant CLIENT_READY (line 106) | const CLIENT_READY: u8 = 1;
    constant SERVER_READY (line 107) | const SERVER_READY: u8 = 2;
    method new_client (line 114) | pub fn new_client(
    method new_server (line 138) | pub fn new_server(server: ServerParameters) -> Self {
    method role (line 149) | pub fn role(&self) -> Role {
    method client (line 156) | pub fn client(&self) -> Option<&Arc<ClientParameters>> {
    method server (line 164) | pub fn server(&self) -> Option<&Arc<ServerParameters>> {
    method remembered (line 178) | pub fn remembered(&self) -> Option<&Arc<ServerParameters>> {
    method get_local (line 182) | pub fn get_local<V: TryFrom<ParameterValue>>(&self, id: ParameterId) -...
    method get_remote (line 189) | pub fn get_remote<V: TryFrom<ParameterValue>>(&self, id: ParameterId) ...
    method poll_ready (line 201) | pub fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<()> {
    method is_remote_params_received (line 210) | pub fn is_remote_params_received(&self) -> bool {
    method is_remote_params_ready (line 221) | pub fn is_remote_params_ready(&self) -> bool {
    method recv_remote_params (line 229) | pub fn recv_remote_params(
    method wake_all (line 260) | fn wake_all(&mut self) {
    method initial_scid_from_peer_need_equal (line 274) | pub fn initial_scid_from_peer_need_equal(
    method retry_scid_from_server_need_equal (line 301) | pub fn retry_scid_from_server_need_equal(&mut self, cid: ConnectionId) {
    method initial_scid_from_peer (line 308) | pub fn initial_scid_from_peer(&self) -> Option<ConnectionId> {
    method authenticate_cids (line 315) | fn authenticate_cids(&self) -> Result<bool, QuicError> {
    method negotiated_max_idle_timeout (line 381) | pub fn negotiated_max_idle_timeout(&self) -> Option<Duration> {
  method drop (line 100) | fn drop(&mut self) {
  type ArcParameters (line 420) | pub struct ArcParameters(Arc<Mutex<Result<Parameters, Error>>>);
    method from (line 442) | fn from(params: Parameters) -> Self {
    method lock_guard (line 449) | pub fn lock_guard(&self) -> Result<ParametersGuard<'_>, Error> {
    method remote_ready (line 458) | pub async fn remote_ready(&self) -> Result<ParametersGuard<'_>, Error> {
    method on_conn_error (line 480) | pub fn on_conn_error(&self, error: &Error) {
  type ParametersGuard (line 425) | pub struct ParametersGuard<'a>(MutexGuard<'a, Result<Parameters, Error>>);
  type Target (line 428) | type Target = Parameters;
  method deref (line 430) | fn deref(&self) -> &Self::Target {
  method deref_mut (line 436) | fn deref_mut(&mut self) -> &mut Self::Target {
  function create_test_client_params (line 495) | fn create_test_client_params() -> ClientParameters {
  function create_test_server_params (line 506) | fn create_test_server_params() -> ServerParameters {
  function test_parameters_new (line 524) | fn test_parameters_new() {
  function test_authenticate_cids (line 538) | fn test_authenticate_cids() {
  function test_parameters_as_client (line 565) | fn test_parameters_as_client() {
  function test_validate_remote_params (line 587) | fn test_validate_remote_params() {
  function test_write_parameters (line 614) | fn test_write_parameters() {
  function test_arc_parameters_error_handling (line 628) | async fn test_arc_parameters_error_handling() {

FILE: qbase/src/param/core.rs
  type ParameterValueType (line 15) | pub enum ParameterValueType {
  type ParameterValue (line 26) | pub enum ParameterValue {
    method value_type (line 37) | pub fn value_type(&self) -> ParameterValueType {
    method from (line 51) | fn from(value: u32) -> Self {
    method from (line 57) | fn from(value: String) -> Self {
  type Error (line 63) | type Error = TryIntoError<ParameterValue>;
  method try_from (line 66) | fn try_from(value: ParameterValue) -> Result<Self, TryIntoError<Paramete...
  type Error (line 75) | type Error = TryIntoError<ParameterValue>;
  method try_from (line 78) | fn try_from(value: ParameterValue) -> Result<Self, TryIntoError<Paramete...
  type Error (line 87) | type Error = TryIntoError<ParameterValue>;
  method try_from (line 90) | fn try_from(value: ParameterValue) -> Result<Self, TryIntoError<Paramete...
  type Error (line 99) | type Error = <VarInt as TryFrom<ParameterValue>>::Error;
  function try_from (line 102) | fn try_from(value: ParameterValue) -> Result<Self, Self::Error> {
  type Error (line 108) | type Error = TryIntoError<ParameterValue>;
  method try_from (line 111) | fn try_from(value: ParameterValue) -> Result<Self, TryIntoError<Paramete...
  type Error (line 124) | type Error = TryIntoError<ParameterValue>;
  method try_from (line 127) | fn try_from(value: ParameterValue) -> Result<Self, TryIntoError<Paramete...
  type Error (line 136) | type Error = TryIntoError<ParameterValue>;
  function try_from (line 139) | fn try_from(value: ParameterValue) -> Result<Self, Self::Error> {
  type Error (line 148) | type Error = TryIntoError<ParameterValue>;
  method try_from (line 151) | fn try_from(value: ParameterValue) -> Result<Self, TryIntoError<Paramete...
  type Error (line 160) | type Error = <Bytes as TryFrom<ParameterValue>>::Error;
  method try_from (line 163) | fn try_from(value: ParameterValue) -> Result<Self, Self::Error> {
  type ParameterId (line 171) | pub enum ParameterId {
    method belong_to (line 216) | pub fn belong_to(self, role: Role) -> Result<(), Error> {
    method fmt (line 235) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  type Parameters (line 241) | pub struct Parameters<Role> {
  function get (line 247) | pub fn get<V>(&self, id: ParameterId) -> Option<V>
  function contains (line 255) | pub fn contains(&self, id: ParameterId) -> bool {
  function is_empty (line 259) | pub fn is_empty(&self) -> bool {
  function new (line 265) | pub fn new() -> Self {
  function set (line 269) | pub fn set(&mut self, id: ParameterId, value: impl Into<ParameterValue>)...
  type ClientParameters (line 279) | pub type ClientParameters = Parameters<Client>;
  type ServerParameters (line 280) | pub type ServerParameters = Parameters<Server>;
    method is_0rtt_accepted (line 284) | pub fn is_0rtt_accepted(&self, server_params: &ServerParameters) -> bo...
  type PeerParameters (line 306) | pub enum PeerParameters {

FILE: qbase/src/param/error.rs
  type Error (line 16) | pub enum Error {
    method from_error_kind (line 44) | fn from_error_kind(_input: &[u8], _kind: NomErrorKind) -> Self {
    method append (line 48) | fn append(_input: &[u8], _kind: NomErrorKind, source: Self) -> Self {
  method from (line 34) | fn from(e: Error) -> Self {

FILE: qbase/src/param/handy.rs
  function client_parameters (line 5) | pub fn client_parameters() -> super::ClientParameters {
  function server_parameters (line 27) | pub fn server_parameters() -> super::ServerParameters {

FILE: qbase/src/param/io.rs
  type WriteParameterId (line 21) | pub trait WriteParameterId: bytes::BufMut {
    method put_parameter_id (line 23) | fn put_parameter_id(&mut self, param_id: ParameterId);
    method put_parameter_id (line 27) | fn put_parameter_id(&mut self, param_id: ParameterId) {
  function be_raw_parameter (line 32) | pub fn be_raw_parameter(input: &[u8]) -> nom::IResult<&[u8], (VarInt, &[...
  function be_parameter_value (line 38) | pub fn be_parameter_value(input: &[u8], id: ParameterId) -> nom::IResult...
  type WriteParameter (line 64) | pub trait WriteParameter {
    method put_bytes_parameter (line 65) | fn put_bytes_parameter(&mut self, id: ParameterId, bytes: &Bytes);
    method put_cid_parameter (line 67) | fn put_cid_parameter(&mut self, id: ParameterId, cid: &ConnectionId);
    method put_duration_parameter (line 69) | fn put_duration_parameter(&mut self, id: ParameterId, dur: &Duration) {
    method put_bool_parameter (line 74) | fn put_bool_parameter(&mut self, id: ParameterId);
    method put_preferred_address_parameter (line 76) | fn put_preferred_address_parameter(&mut self, id: ParameterId, addr: &...
    method put_reset_token_parameter (line 78) | fn put_reset_token_parameter(&mut self, id: ParameterId, token: &Reset...
    method put_varint_parameter (line 80) | fn put_varint_parameter(&mut self, id: ParameterId, value: &VarInt);
    method put_parameter (line 82) | fn put_parameter(&mut self, id: ParameterId, value: &ParameterValue) {
    method put_bytes_parameter (line 100) | fn put_bytes_parameter(&mut self, id: ParameterId, bytes: &Bytes) {
    method put_cid_parameter (line 106) | fn put_cid_parameter(&mut self, id: ParameterId, cid: &ConnectionId) {
    method put_bool_parameter (line 111) | fn put_bool_parameter(&mut self, id: ParameterId) {
    method put_preferred_address_parameter (line 116) | fn put_preferred_address_parameter(&mut self, id: ParameterId, addr: &...
    method put_reset_token_parameter (line 122) | fn put_reset_token_parameter(&mut self, id: ParameterId, token: &Reset...
    method put_varint_parameter (line 128) | fn put_varint_parameter(&mut self, id: ParameterId, value: &VarInt) {
  type WriteParameters (line 135) | pub trait WriteParameters<Role> {
    method put_parameters (line 136) | fn put_parameters(&mut self, params: &Parameters<Role>);
  method put_parameters (line 140) | fn put_parameters(&mut self, params: &Parameters<Role>) {
  function handle_nom_error (line 147) | fn handle_nom_error<F: Debug, E: Debug>(input: &[u8], nom_error: nom::Er...
  function parse_from_bytes (line 156) | pub fn parse_from_bytes(mut buf: &[u8]) -> Result<Self, QuicError> {
  method try_from_remembered_bytes (line 189) | pub fn try_from_remembered_bytes(mut buf: &[u8]) -> Result<Self, QuicErr...

FILE: qbase/src/param/preferred_address.rs
  type PreferredAddress (line 18) | pub struct PreferredAddress {
    method new (line 31) | pub fn new(
    method encoding_size (line 46) | pub fn encoding_size(&self) -> usize {
  function be_preferred_address (line 53) | pub fn be_preferred_address(input: &[u8]) -> nom::IResult<&[u8], Preferr...
  type WirtePreferredAddress (line 88) | pub trait WirtePreferredAddress: bytes::BufMut {
    method put_preferred_address (line 90) | fn put_preferred_address(&mut self, addr: &PreferredAddress);
    method put_preferred_address (line 94) | fn put_preferred_address(&mut self, addr: &PreferredAddress) {

FILE: qbase/src/role.rs
  type Role (line 35) | pub enum Role {
    method fmt (line 43) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    type Output (line 52) | type Output = Self;
    method not (line 53) | fn not(self) -> Self {
    method from (line 74) | fn from(_: Client) -> Self {
    method from (line 95) | fn from(_: Server) -> Self {
  type IntoRole (line 61) | pub trait IntoRole {
    method into_role (line 63) | fn into_role() -> Role;
    method into_role (line 80) | fn into_role() -> Role {
    method into_role (line 101) | fn into_role() -> Role {
  type RequiredParameters (line 66) | pub trait RequiredParameters {
    method required_parameters (line 67) | fn required_parameters() -> impl IntoIterator<Item = ParameterId>;
    method required_parameters (line 86) | fn required_parameters() -> impl IntoIterator<Item = ParameterId> {
    method required_parameters (line 107) | fn required_parameters() -> impl IntoIterator<Item = ParameterId> {
  type Client (line 71) | pub struct Client;
  type Server (line 92) | pub struct Server;

FILE: qbase/src/sid.rs
  type Dir (line 26) | pub enum Dir {
    method fmt (line 34) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  type StreamId (line 53) | pub struct StreamId(u64);
    method new (line 69) | pub fn new(role: Role, dir: Dir, id: u64) -> Self {
    method role (line 75) | pub fn role(&self) -> Role {
    method dir (line 84) | pub fn dir(&self) -> Dir {
    method id (line 89) | pub fn id(&self) -> u64 {
    method next_unchecked (line 93) | unsafe fn next_unchecked(&self) -> Self {
    method encoding_size (line 98) | pub fn encoding_size(&self) -> usize {
    method fmt (line 104) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    method from (line 116) | fn from(v: VarInt) -> Self {
  constant MAX_STREAMS_LIMIT (line 61) | pub const MAX_STREAMS_LIMIT: u64 = (1 << 60) - 1;
  method from (line 122) | fn from(s: StreamId) -> Self {
  function from (line 128) | fn from(s: StreamId) -> Self {
  function be_streamid (line 135) | pub fn be_streamid(input: &[u8]) -> nom::IResult<&[u8], StreamId> {
  type WriteStreamId (line 141) | pub trait WriteStreamId: bytes::BufMut {
    method put_streamid (line 143) | fn put_streamid(&mut self, stream_id: &StreamId);
    method put_streamid (line 147) | fn put_streamid(&mut self, stream_id: &StreamId) {
  type ControlStreamsConcurrency (line 166) | pub trait ControlStreamsConcurrency: fmt::Debug + Send + Sync {
    method on_accept_streams (line 175) | fn on_accept_streams(&mut self, dir: Dir, sid: u64) -> Option<u64>;
    method on_end_of_stream (line 186) | fn on_end_of_stream(&mut self, dir: Dir, sid: u64) -> Option<u64>;
    method on_streams_blocked (line 195) | fn on_streams_blocked(&mut self, dir: Dir, max_streams: u64) -> Option...
    method on_accept_streams (line 199) | fn on_accept_streams(&mut self, dir: Dir, sid: u64) -> Option<u64> {
    method on_end_of_stream (line 203) | fn on_end_of_stream(&mut self, dir: Dir, sid: u64) -> Option<u64> {
    method on_streams_blocked (line 207) | fn on_streams_blocked(&mut self, dir: Dir, max_streams: u64) -> Option...
  type ProductStreamsConcurrencyController (line 212) | pub trait ProductStreamsConcurrencyController: Send + Sync {
    method init (line 213) | fn init(
    method init (line 226) | fn init(
  type StreamIds (line 246) | pub struct StreamIds<BLOCKED, MAX> {
  function new (line 263) | pub fn new(

FILE: qbase/src/sid/handy.rs
  type ConsistentConcurrency (line 6) | pub struct ConsistentConcurrency {
    method new (line 11) | pub fn new(initial_max_bi: u64, initial_max_uni: u64) -> Self {
  method on_accept_streams (line 19) | fn on_accept_streams(&mut self, _dir: Dir, _sid: u64) -> Option<u64> {
  method on_end_of_stream (line 23) | fn on_end_of_stream(&mut self, dir: Dir, _sid: u64) -> Option<u64> {
  method on_streams_blocked (line 31) | fn on_streams_blocked(&mut self, _dir: Dir, _max_streams: u64) -> Option...
  type DemandConcurrency (line 39) | pub struct DemandConcurrency;
  method on_accept_streams (line 42) | fn on_accept_streams(&mut self, _dir: Dir, _sid: u64) -> Option<u64> {
  method on_end_of_stream (line 46) | fn on_end_of_stream(&mut self, _dir: Dir, _sid: u64) -> Option<u64> {
  method on_streams_blocked (line 50) | fn on_streams_blocked(&mut self, _dir: Dir, max_streams: u64) -> Option<...

FILE: qbase/src/sid/local_sid.rs
  type LocalStreamIds (line 20) | struct LocalStreamIds<BLOCKED> {
  function new (line 38) | fn new(
  function role (line 60) | fn role(&self) -> Role {
  function opened_streams (line 65) | fn opened_streams(&self, dir: Dir) -> u64 {
  function recv_max_streams_frame (line 71) | fn recv_max_streams_frame(&mut self, frame: MaxStreamsFrame) {
  function increase_limit (line 79) | fn increase_limit(&mut self, dir: Dir, val: u64) {
  function poll_alloc_sid (line 95) | fn poll_alloc_sid(&mut self, cx: &mut Context<'_>, dir: Dir) -> Poll<Opt...
  function revise_max_streams (line 116) | pub fn revise_max_streams(
  type ArcLocalStreamIds (line 141) | pub struct ArcLocalStreamIds<BLOCKED>(Arc<Mutex<LocalStreamIds<BLOCKED>>>);
  function new (line 150) | pub fn new(
  function role (line 163) | pub fn role(&self) -> Role {
  function opened_streams (line 174) | pub fn opened_streams(&self, dir: Dir) -> u64 {
  function recv_max_streams_frame (line 185) | pub fn recv_max_streams_frame(&self, frame: MaxStreamsFrame) {
  function poll_alloc_sid (line 208) | pub fn poll_alloc_sid(&self, cx: &mut Context<'_>, dir: Dir) -> Poll<Opt...
  function revise_max_streams (line 212) | pub fn revise_max_streams(
  type Output (line 230) | type Output = ();
  function recv_frame (line 232) | fn recv_frame(&self, frame: MaxStreamsFrame) -> Result<Self::Output, cra...
  type StreamsBlockedFrameTx (line 246) | struct StreamsBlockedFrameTx(ArcAsyncDeque<StreamsBlockedFrame>);
    method send_frame (line 249) | fn send_frame<I: IntoIterator<Item = StreamsBlockedFrame>>(&self, iter...
  function test_stream_id_new (line 255) | fn test_stream_id_new() {
  function test_recv_max_stream_frames (line 263) | fn test_recv_max_stream_frames() {

FILE: qbase/src/sid/remote_sid.rs
  type ExceedLimitError (line 21) | pub struct ExceedLimitError(StreamId, u64);
  type AcceptSid (line 26) | pub enum AcceptSid {
  type NeedCreate (line 37) | pub struct NeedCreate {
  type Item (line 43) | type Item = StreamId;
  method next (line 44) | fn next(&mut self) -> Option<Self::Item> {
  type RemoteStreamIds (line 58) | struct RemoteStreamIds<MAX> {
  function new (line 72) | fn new(
  function role (line 92) | fn role(&self) -> Role {
  function try_accept_sid (line 96) | fn try_accept_sid(&mut self, sid: StreamId) -> Result<AcceptSid, ExceedL...
  function on_end_of_stream (line 120) | fn on_end_of_stream(&mut self, sid: StreamId) {
  function recv_streams_blocked_frame (line 134) | fn recv_streams_blocked_frame(&mut self, frame: StreamsBlockedFrame) {
  type ArcRemoteStreamIds (line 166) | pub struct ArcRemoteStreamIds<MAX>(Arc<Mutex<RemoteStreamIds<MAX>>>);
  function new (line 181) | pub fn new(
  function role (line 194) | pub fn role(&self) -> Role {
  function try_accept_sid (line 215) | pub fn try_accept_sid(&self, sid: StreamId) -> Result<AcceptSid, ExceedL...
  function on_end_of_stream (line 220) | pub fn on_end_of_stream(&self, sid: StreamId) {
  function recv_streams_blocked_frame (line 225) | pub fn recv_streams_blocked_frame(&self, frame: StreamsBlockedFrame) {
  type Output (line 234) | type Output = ();
  function recv_frame (line 236) | fn recv_frame(&self, frame: StreamsBlockedFrame) -> Result<Self::Output,...
  type MaxStreamsFrameTx (line 250) | struct MaxStreamsFrameTx(ArcAsyncDeque<MaxStreamsFrame>);
    method send_frame (line 253) | fn send_frame<I: IntoIterator<Item = MaxStreamsFrame>>(&self, iter: I) {
  function test_try_accept_sid (line 259) | fn test_try_accept_sid() {

FILE: qbase/src/time.rs
  type TimeOut (line 10) | pub struct TimeOut;
  type IdleConfig (line 13) | pub struct IdleConfig {
    method suitable_heartbeat_interval (line 20) | fn suitable_heartbeat_interval(max_idle_timeout: Duration) -> Duration {
    method new (line 31) | pub fn new(max_idle_timeout: Duration, defer_idle_timeout: Duration) -...
    method negotiate_max_idle_timeout (line 45) | pub fn negotiate_max_idle_timeout(&mut self, max_idle_timeout: Duratio...
    method set_heartbeat_interval (line 55) | pub fn set_heartbeat_interval(&mut self, interval: Duration) {
  type ArcIdleConfig (line 61) | pub struct ArcIdleConfig(Arc<RwLock<IdleConfig>>);
    method new (line 65) | pub fn new(max_idle_timeout: Duration, defer_idle_timeout: Duration) -...
    method negotiate_max_idle_timeout (line 77) | pub fn negotiate_max_idle_timeout(&self, max_idle_timeout: Duration) {
    method set_heartbeat_interval (line 85) | pub fn set_heartbeat_interval(&self, interval: Duration) {
    method timer (line 89) | pub fn timer(&self) -> ArcIdleTimer {
    method defer_idle_timeout (line 98) | fn defer_idle_timeout(&self) -> Duration {
    method heartbeat_interval (line 102) | fn heartbeat_interval(&self) -> Duration {
    method timeout_after (line 106) | fn timeout_after(&self, idle_at: Instant) -> bool {
  type IdleTimer (line 115) | pub struct IdleTimer {
    method on_sent (line 124) | pub fn on_sent(&mut self, packet_content: PacketContent) {
    method on_rcvd (line 133) | pub fn on_rcvd(&mut self, packet_content: PacketContent) {
    method health (line 146) | pub fn health(&mut self) -> Result<Option<PingFrame>, TimeOut> {
  type ArcIdleTimer (line 172) | pub struct ArcIdleTimer(Arc<Mutex<IdleTimer>>);
    method on_sent (line 176) | pub fn on_sent(&self, packet_content: PacketContent) {
    method on_rcvd (line 181) | pub fn on_rcvd(&self, packet_content: PacketContent) {
    method health (line 187) | pub fn health(&self) -> Result<Option<PingFrame>, TimeOut> {

FILE: qbase/src/token.rs
  constant RESET_TOKEN_SIZE (line 13) | pub const RESET_TOKEN_SIZE: usize = 16;
  type ResetToken (line 16) | pub struct ResetToken([u8; RESET_TOKEN_SIZE]);
    method new (line 19) | pub fn new(bytes: &[u8]) -> Self {
    method random_gen (line 23) | pub fn random_gen() -> Self {
    method encoding_size (line 29) | pub fn encoding_size(&self) -> usize {
  function be_reset_token (line 34) | pub fn be_reset_token(input: &[u8]) -> IResult<&[u8], ResetToken> {
  type WriteResetToken (line 39) | pub trait WriteResetToken {
    method put_reset_token (line 40) | fn put_reset_token(&mut self, token: &ResetToken);
    method put_reset_token (line 44) | fn put_reset_token(&mut self, token: &ResetToken) {
  type TokenSink (line 49) | pub trait TokenSink: Send + Sync {
    method sink (line 50) | fn sink(&self, server_name: &str, token: Vec<u8>);
    method fetch_token (line 52) | fn fetch_token(&self, server_name: &str) -> Vec<u8>;
  type TokenProvider (line 55) | pub trait TokenProvider: Send + Sync {
    method gen_new_token (line 56) | fn gen_new_token(&self, server_name: &str) -> Vec<u8>;
    method gen_retry_token (line 58) | fn gen_retry_token(&self, server_name: &str) -> Vec<u8>;
    method verify_token (line 62) | fn verify_token(&self, server_name: &str, token: &[u8]) -> bool;
  type TokenRegistry (line 65) | pub enum TokenRegistry {
  type ArcTokenRegistry (line 71) | pub struct ArcTokenRegistry(Arc<TokenRegistry>);
    method with_sink (line 74) | pub fn with_sink(server_name: String, sink: Arc<dyn TokenSink>) -> Self {
    method with_provider (line 78) | pub fn with_provider(provider: Arc<dyn TokenProvider>) -> Self {
    type Output (line 92) | type Output = ();
    method recv_frame (line 94) | fn recv_frame(&self, frame: NewTokenFrame) -> Result<Self::Output, cra...
  type Target (line 84) | type Target = TokenRegistry;
  method deref (line 86) | fn deref(&self) -> &Self::Target {
  type NoopTokenRegistry (line 111) | pub struct NoopTokenRegistry;
    method sink (line 114) | fn sink(&self, _: &str, _: Vec<u8>) {}
    method fetch_token (line 116) | fn fetch_token(&self, _: &str) -> Vec<u8> {
    method gen_new_token (line 122) | fn gen_new_token(&self, _: &str) -> Vec<u8> {
    method gen_retry_token (line 126) | fn gen_retry_token(&self, _: &str) -> Vec<u8> {
    method verify_token (line 130) | fn verify_token(&self, _: &str, _: &[u8]) -> bool {
  function test_create_token (line 139) | fn test_create_token() {
  function test_creat_token_with_less_size (line 145) | fn test_creat_token_with_less_size() {
  function test_creat_token_with_more_size (line 151) | fn test_creat_token_with_more_size() {
  function test_read_reset_token (line 156) | fn test_read_reset_token() {
  function test_write_reset_token (line 171) | fn test_write_reset_token() {

FILE: qbase/src/util/async_deque.rs
  type AsyncDeque (line 17) | struct AsyncDeque<T> {
  function push_back (line 25) | fn push_back(&mut self, value: T) {
  function push_front (line 36) | fn push_front(&mut self, value: T) {
  function poll_pop (line 52) | fn poll_pop(&mut self, cx: &mut Context<'_>) -> Poll<Option<T>> {
  function len (line 77) | fn len(&self) -> usize {
  function is_empty (line 82) | fn is_empty(&self) -> bool {
  function close (line 93) | pub fn close(&mut self) {
  function extend (line 102) | fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
  type ArcAsyncDeque (line 120) | pub struct ArcAsyncDeque<T>(Arc<Mutex<AsyncDeque<T>>>);
  function new (line 124) | pub fn new() -> Self {
  function with_capacity (line 132) | pub fn with_capacity(capacity: usize) -> Self {
  function lock_guard (line 139) | fn lock_guard(&self) -> MutexGuard<'_, AsyncDeque<T>> {
  function push_front (line 156) | pub fn push_front(&self, value: T) {
  function push_back (line 173) | pub fn push_back(&self, value: T) {
  function pop (line 204) | pub fn pop(&self) -> Self {
  function poll_pop (line 231) | pub fn poll_pop(&self, cx: &mut Context<'_>) -> Poll<Option<T>> {
  function len (line 236) | pub fn len(&self) -> usize {
  function is_empty (line 253) | pub fn is_empty(&self) -> bool {
  function close (line 284) | pub fn close(&self) {
  method default (line 290) | fn default() -> Self {
  method clone (line 296) | fn clone(&self) -> Self {
  type Output (line 302) | type Output = Option<T>;
  method poll (line 304) | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
  type Item (line 310) | type Item = T;
  function poll_next (line 312) | fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<...
  function extend (line 318) | fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
  function push_pop (line 330) | async fn push_pop() {
  function close (line 349) | async fn close() {
  function wake (line 363) | async fn wake() {
  function cancel (line 388) | async fn cancel() {
  function racing (line 410) | async fn racing() {

FILE: qbase/src/util/bound_queue.rs
  type BoundQueueInner (line 10) | struct BoundQueueInner<T> {
  type BoundQueue (line 16) | pub struct BoundQueue<T>(Arc<BoundQueueInner<T>>);
  method clone (line 19) | fn clone(&self) -> Self {
  function new (line 26) | pub fn new(size: usize) -> Self {
  function try_send (line 32) | pub fn try_send(&self, item: T) -> Result<(), mpsc::TrySendError<T>> {
  function send (line 37) | pub async fn send(&self, item: T) -> Result<(), mpsc::SendError> {
  function recv (line 42) | pub async fn recv(&self) -> Option<T> {
  function close (line 47) | pub fn close(&self) {
  function is_closed (line 52) | pub fn is_closed(&self) -> bool {
  function same_queue (line 57) | pub fn same_queue(&self, other: &Self) -> bool {
  function test_send_receive (line 68) | async fn test_send_receive() {

FILE: qbase/src/util/data.rs
  type ContinuousData (line 3) | pub trait ContinuousData {
    method len (line 4) | fn len(&self) -> usize;
    method is_empty (line 6) | fn is_empty(&self) -> bool;
    method to_bytes (line 8) | fn to_bytes(&self) -> Bytes;
    method len (line 15) | fn len(&self) -> usize {
    method is_empty (line 20) | fn is_empty(&self) -> bool {
    method to_bytes (line 25) | fn to_bytes(&self) -> Bytes {
    method len (line 32) | fn len(&self) -> usize {
    method is_empty (line 37) | fn is_empty(&self) -> bool {
    method to_bytes (line 42) | fn to_bytes(&self) -> Bytes {
    method len (line 49) | fn len(&self) -> usize {
    method is_empty (line 54) | fn is_empty(&self) -> bool {
    method to_bytes (line 59) | fn to_bytes(&self) -> Bytes {
    method len (line 66) | fn len(&self) -> usize {
    method is_empty (line 71) | fn is_empty(&self) -> bool {
    method to_bytes (line 76) | fn to_bytes(&self) -> Bytes {
    method len (line 83) | fn len(&self) -> usize {
    method is_empty (line 88) | fn is_empty(&self) -> bool {
    method to_bytes (line 93) | fn to_bytes(&self) -> Bytes {
    method len (line 102) | fn len(&self) -> usize {
    method is_empty (line 107) | fn is_empty(&self) -> bool {
    method to_bytes (line 112) | fn to_bytes(&self) -> Bytes {
    method len (line 119) | fn len(&self) -> usize {
    method is_empty (line 124) | fn is_empty(&self) -> bool {
    method to_bytes (line 129) | fn to_bytes(&self) -> Bytes {
    method len (line 136) | fn len(&self) -> usize {
    method is_empty (line 141) | fn is_empty(&self) -> bool {
    method to_bytes (line 146) | fn to_bytes(&self) -> Bytes {
    method len (line 158) | fn len(&self) -> usize {
    method is_empty (line 163) | fn is_empty(&self) -> bool {
    method to_bytes (line 168) | fn to_bytes(&self) -> Bytes {
  type DataPair (line 11) | pub type DataPair<'a> = (&'a [u8], &'a [u8]);
  type NonData (line 98) | pub type NonData = ();
  type WriteData (line 173) | pub trait WriteData<D: ContinuousData + ?Sized>: BufMut {
    method put_data (line 174) | fn put_data(&mut self, data: &D);
  method put_data (line 179) | fn put_data(&mut self, data: &DataPair<'_>) {
  method put_data (line 187) | fn put_data(&mut self, data: &[u8]) {
  method put_data (line 194) | fn put_data(&mut self, data: &[u8; N]) {
  method put_data (line 201) | fn put_data(&mut self, data: &Bytes) {
  method put_data (line 208) | fn put_data(&mut self, &(): &()) {}
  method put_data (line 216) | fn put_data(&mut self, data: &&D) {
  method put_data (line 226) | fn put_data(&mut self, data: &[D]) {
  method put_data (line 238) | fn put_data(&mut self, data: &[D; N]) {

FILE: qbase/src/util/index_deque.rs
  type IndexError (line 10) | pub enum IndexError {
  type IndexDeque (line 30) | pub struct IndexDeque<T, const LIMIT: u64> {
  method default (line 36) | fn default() -> Self {
  function with_capacity (line 54) | pub fn with_capacity(capacity: usize) -> Self {
  function is_empty (line 73) | pub fn is_empty(&self) -> bool {
  function len (line 89) | pub fn len(&self) -> usize {
  function offset (line 107) | pub fn offset(&self) -> u64 {
  function largest (line 123) | pub fn largest(&self) -> u64 {
  function contain (line 140) | pub fn contain(&self, idx: u64) -> bool {
  function get (line 158) | pub fn get(&self, idx: u64) -> Option<&T> {
  function get_mut (line 183) | pub fn get_mut(&mut self, idx: u64) -> Option<&mut T> {
  function push_back (line 205) | pub fn push_back(&mut self, value: T) -> Result<u64, IndexError> {
  function pop_front (line 230) | pub fn pop_front(&mut self) -> Option<(u64, T)> {
  function front (line 238) | pub fn front(&self) -> Option<(u64, &T)> {
  function back (line 242) | pub fn back(&self) -> Option<(u64, &T)> {
  function iter (line 261) | pub fn iter(&self) -> impl DoubleEndedIterator<Item = &T> {
  function iter_mut (line 282) | pub fn iter_mut(&mut self) -> impl DoubleEndedIterator<Item = &mut T> {
  function enumerate (line 301) | pub fn enumerate(&self) -> impl DoubleEndedIterator<Item = (u64, &T)> {
  function enumerate_mut (line 326) | pub fn enumerate_mut(&mut self) -> impl DoubleEndedIterator<Item = (u64,...
  function advance (line 351) | pub fn advance(&mut self, n: usize) {
  function drain_to (line 372) | pub fn drain_to(&mut self, end: u64) -> impl DoubleEndedIterator<Item = ...
  function reset_offset (line 400) | pub fn reset_offset(&mut self, new_offset: u64) {
  function extend (line 407) | fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
  function insert (line 436) | pub fn insert(&mut self, idx: u64, value: T) -> Result<Option<T>, IndexE...
  function resize (line 457) | pub fn resize(&mut self, new_end: u64, value: T) -> Result<(), IndexErro...
  type Output (line 471) | type Output = T;
  function index (line 473) | fn index(&self, index: u64) -> &Self::Output {
  function index_mut (line 479) | fn index_mut(&mut self, index: u64) -> &mut Self::Output {
  function test_index_queue (line 489) | fn test_index_queue() {
  function test_insert (line 534) | fn test_insert() {
  function test_skip (line 547) | fn test_skip() {
  function test_reset_offset (line 563) | fn test_reset_offset() {
  function test_reset_offset_with_content (line 576) | fn test_reset_offset_with_content() {
  function test_reset_offset_panic2 (line 588) | fn test_reset_offset_panic2() {
  function test_resize (line 604) | fn test_resize() {

FILE: qbase/src/util/unique_id.rs
  type UniqueId (line 10) | pub struct UniqueId(usize);
  type UniqueIdGenerator (line 14) | pub struct UniqueIdGenerator(AtomicUsize);
    method new (line 35) | pub const fn new() -> Self {
    method generate (line 51) | pub fn generate(&self) -> UniqueId {
  method default (line 17) | fn default() -> Self {
  function test_unique_id_basic (line 65) | fn test_unique_id_basic() {
  function test_unique_id_hash (line 76) | fn test_unique_id_hash() {
  function test_unique_id_clone_copy (line 89) | fn test_unique_id_clone_copy() {
  function test_thread_safety (line 98) | fn test_thread_safety() {
  function test_default_generator (line 129) | fn test_default_generator() {

FILE: qbase/src/util/wakers.rs
  type WakerVec (line 11) | pub struct WakerVec<const N: usize = 4> {
  method default (line 16) | fn default() -> Self {
  function new (line 22) | pub const fn new() -> Self {
  function register (line 28) | pub fn register(&mut self, waker: &Waker) {
  function wake_all (line 34) | pub fn wake_all(&mut self) {
  method drop (line 42) | fn drop(&mut self) {
  type Wakers (line 48) | pub struct Wakers<const N: usize = 4> {
  method wake (line 53) | fn wake(self: Arc<Self>) {
  method wake_by_ref (line 57) | fn wake_by_ref(self: &Arc<Self>) {
  method default (line 63) | fn default() -> Self {
  function new (line 69) | pub const fn new() -> Self {
  function lock (line 75) | fn lock(&self) -> MutexGuard<'_, WakerVec<N>> {
  function register (line 79) | pub fn register(&self, waker: &Waker) {
  function wake_all (line 83) | pub fn wake_all(&self) {
  function to_waker (line 87) | pub fn to_waker(self: &Arc<Self>) -> Waker {
  function combine_with (line 91) | pub fn combine_with<T>(

FILE: qbase/src/varint.rs
  type VarInt (line 12) | pub struct VarInt(u64);
    constant MAX (line 30) | pub const MAX: Self = Self(VARINT_MAX);
    constant MAX_SIZE (line 32) | pub const MAX_SIZE: usize = 8;
    method from_u32 (line 35) | pub const fn from_u32(x: u32) -> Self {
    method from_u64 (line 41) | pub const fn from_u64(x: u64) -> Result<Self, err::Overflow> {
    method from_u64_unchecked (line 54) | pub unsafe fn from_u64_unchecked(x: u64) -> Self {
    method from_u128 (line 60) | pub fn from_u128(x: u128) -> Result<Self, err::Overflow> {
    method into_u64 (line 69) | pub fn into_u64(self) -> u64 {
    method encoding_size (line 74) | pub fn encoding_size(self) -> usize {
    method from (line 97) | fn from(x: u8) -> Self {
    method from (line 103) | fn from(x: u16) -> Self {
    method from (line 109) | fn from(x: u32) -> Self {
    type Error (line 115) | type Error = err::Overflow;
    method try_from (line 117) | fn try_from(x: u128) -> Result<Self, Self::Error> {
    type Error (line 123) | type Error = err::Overflow;
    method try_from (line 126) | fn try_from(x: u64) -> Result<Self, Self::Error> {
    type Error (line 132) | type Error = err::Overflow;
    method try_from (line 135) | fn try_from(x: usize) -> Result<Self, Self::Error> {
    method to_usize (line 141) | fn to_usize(&self) -> usize {
    method eq (line 147) | fn eq(&self, other: &u64) -> bool {
    method partial_cmp (line 153) | fn partial_cmp(&self, other: &u64) -> Option<Ordering> {
    method fmt (line 159) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  constant VARINT_MAX (line 15) | pub const VARINT_MAX: u64 = 0x3fff_ffff_ffff_ffff;
  type EncodeBytes (line 21) | pub enum EncodeBytes {
  function from (line 91) | fn from(x: VarInt) -> Self {
  type Overflow (line 173) | pub struct Overflow(pub(super) u128);
  function be_varint (line 190) | pub fn be_varint(input: &[u8]) -> IResult<&[u8], VarInt> {
  type WriteVarInt (line 205) | pub trait WriteVarInt: BufMut {
    method put_varint (line 230) | fn put_varint(&mut self, value: &VarInt);
    method encode_varint (line 233) | fn encode_varint(&mut self, value: &VarInt, nbytes: EncodeBytes);
    method put_varint (line 238) | fn put_varint(&mut self, value: &VarInt) {
    method encode_varint (line 253) | fn encode_varint(&mut self, value: &VarInt, nbytes: EncodeBytes) {
  function test_equal (line 280) | fn test_equal() {
  function test_be_varint (line 288) | fn test_be_varint() {
  function assert_put_varint_eq (line 316) | fn assert_put_varint_eq(val: u64, expected: &[u8]) {
  function test_put_varint (line 324) | fn test_put_varint() {
  function test_encode_varint (line 342) | fn test_encode_varint() {

FILE: qcongestion/src/algorithm.rs
  type Algorithm (line 10) | pub enum Algorithm {
  type Control (line 15) | pub trait Control: Send {
    method on_packet_sent_cc (line 16) | fn on_packet_sent_cc(&mut self, packet: &SentPacket);
    method on_packet_acked (line 18) | fn on_packet_acked(&mut self, acked_packet: &SentPacket);
    method on_packets_lost (line 20) | fn on_packets_lost(
    method process_ecn (line 26) | fn process_ecn(&mut self, ack: &AckFrame, sent_time: &Instant, epoch: ...
    method congestion_window (line 28) | fn congestion_window(&self) -> usize;
    method pacing_rate (line 30) | fn pacing_rate(&self) -> Option<usize>;
    method remove_from_bytes_in_flight (line 32) | fn remove_from_bytes_in_flight(&mut self, packets: &mut dyn Iterator<I...

FILE: qcongestion/src/algorithm/bbr.rs
  constant MSS (line 19) | const MSS: usize = 1200;
  constant RTPROP_FILTER_LEN (line 22) | const RTPROP_FILTER_LEN: Duration = Duration::from_secs(10);
  constant HIGH_GAIN (line 27) | const HIGH_GAIN: f64 = 2.89;
  constant PROBE_RTT_DURATION (line 32) | const PROBE_RTT_DURATION: Duration = Duration::from_millis(200);
  constant SEND_QUANTUM_THRESHOLD_PACING_RATE (line 35) | const SEND_QUANTUM_THRESHOLD_PACING_RATE: u64 = 1_200_000 / 8;
  constant INITIAL_CWND (line 38) | pub(crate) const INITIAL_CWND: u64 = 80 * MSS as u64;
  constant MIN_PIPE_CWND_PKTS (line 41) | const MIN_PIPE_CWND_PKTS: usize = 4;
  constant MINIMUM_WINDOW_PACKETS (line 43) | const MINIMUM_WINDOW_PACKETS: usize = 2;
  type BbrStateMachine (line 49) | enum BbrStateMachine {
  type Bbr (line 56) | pub(crate) struct Bbr {
    method new (line 166) | pub fn new() -> Self {
    method on_connection_init (line 239) | fn on_connection_init(&mut self) {
    method update_model_and_state (line 244) | fn update_model_and_state(&mut self, ack: &mut AckedPackets) {
    method update_control_parameters (line 253) | fn update_control_parameters(&mut self) {
    method on_transmit (line 260) | fn on_transmit(&mut self) {
  method from (line 148) | fn from(value: &Bbr) -> Self {
  method on_packet_sent_cc (line 212) | fn on_packet_sent_cc(&mut self, packet: &crate::packets::SentPacket) {
  method on_packet_acked (line 216) | fn on_packet_acked(&mut self, acked_packet: &crate::packets::SentPacket) {
  method on_packets_lost (line 220) | fn on_packets_lost(&mut self, lost_packets: &[crate::packets::SentPacket...
  method on_congestion_event (line 224) | fn on_congestion_event(&mut self, sent_time: &Instant) {
  method congestion_window (line 228) | fn congestion_window(&self) -> usize {
  method pacing_rate (line 232) | fn pacing_rate(&self) -> Option<usize> {
  function test_bbr_init (line 279) | fn test_bbr_init() {
  function test_bbr_sent (line 295) | fn test_bbr_sent() {
  function test_bbr_ack (line 308) | fn test_bbr_ack() {
  function simulate_round_trip (line 347) | pub(super) fn simulate_round_trip(

FILE: qcongestion/src/algorithm/bbr/delivery_rate.rs
  type Rate (line 8) | pub struct Rate {
    method on_packet_sent (line 40) | pub fn on_packet_sent(
    method update_rate_sample (line 63) | pub fn update_rate_sample(&mut self, pkt: &AckedPackets, now: Instant) {
    method generate_rate_sample (line 85) | pub fn generate_rate_sample(&mut self) {
    method update_app_limited (line 110) | pub fn update_app_limited(&mut self, v: bool) {
    method app_limited (line 114) | pub fn app_limited(&mut self) -> bool {
    method delivered (line 118) | pub fn delivered(&self) -> usize {
    method sample_delivery_rate (line 122) | pub fn sample_delivery_rate(&self) -> u64 {
    method sample_rtt (line 126) | pub fn sample_rtt(&self) -> Duration {
    method sample_is_app_limited (line 130) | pub fn sample_is_app_limited(&self) -> bool {
  method default (line 23) | fn default() -> Self {
  type RateSample (line 136) | struct RateSample {
  function test_rate (line 153) | fn test_rate() {

FILE: qcongestion/src/algorithm/bbr/min_max.rs
  type MinMax (line 4) | pub(super) struct MinMax {
    method fill (line 11) | fn fill(&mut self, sample: MinMaxSample) {
    method update_max (line 15) | pub(super) fn update_max(&mut self, current_round: u64, measurement: u...
    method subwin_update (line 41) | fn subwin_update(&mut self, sample: MinMaxSample) {
  method default (line 77) | fn default() -> Self {
  type MinMaxSample (line 86) | struct MinMaxSample {

FILE: qcongestion/src/algorithm/bbr/model.rs
  method init_round_counting (line 11) | pub(super) fn init_round_counting(&mut self) {
  method update_round (line 18) | fn update_round(&mut self, packet: &AckedPackets) {
  method update_btlbw (line 30) | pub(super) fn update_btlbw(&mut self, packet: &AckedPackets) {
  method update_rtprop (line 43) | pub(super) fn update_rtprop(&mut self) {

FILE: qcongestion/src/algorithm/bbr/parameters.rs
  method init_pacing_rate (line 15) | pub(super) fn init_pacing_rate(&mut self) {
  method set_pacing_rate (line 21) | pub(super) fn set_pacing_rate(&mut self) {
  method set_pacing_rate_with_gain (line 25) | pub(super) fn set_pacing_rate_with_gain(&mut self, pacing_gain: f64) {
  method set_send_quantum (line 33) | pub(super) fn set_send_quantum(&mut self) {
  method inflight (line 46) | pub fn inflight(&self, gain: f64) -> u64 {
  method update_target_cwnd (line 56) | fn update_target_cwnd(&mut self) {
  method save_cwnd (line 61) | pub(super) fn save_cwnd(&mut self) {
  method restore_cwnd (line 69) | pub fn restore_cwnd(&mut self) {
  method modulate_cwnd_for_recovery (line 73) | fn modulate_cwnd_for_recovery(&mut self, bytes_in_flight: u64) {
  method modulate_cwnd_for_probe_rtt (line 87) | fn modulate_cwnd_for_probe_rtt(&mut self) {
  method set_cwnd (line 94) | pub(super) fn set_cwnd(&mut self) {
  method min_pipe_cwnd (line 115) | pub(super) fn min_pipe_cwnd(&self) -> u64 {
  function test_init_pacing_rate (line 126) | fn test_init_pacing_rate() {
  function test_bbr_set_pacing_rate (line 136) | fn test_bbr_set_pacing_rate() {
  function test_bbr_set_send_quantum (line 145) | fn test_bbr_set_send_quantum() {
  function test_bbr_inflight (line 166) | fn test_bbr_inflight() {
  function test_bbr_modulate_cwnd_for_recovery (line 180) | fn test_bbr_modulate_cwnd_for_recovery() {
  function test_modulate_cwnd_for_probe_rtt (line 201) | fn test_modulate_cwnd_for_probe_rtt() {
  function test_bbr_set_cwnd (line 212) | fn test_bbr_set_cwnd() {

FILE: qcongestion/src/algorithm/bbr/state.rs
  constant GAIN_CYCLE_LEN (line 7) | const GAIN_CYCLE_LEN: usize = 8;
  constant PACING_GAIN_CYCLE (line 10) | const PACING_GAIN_CYCLE: [f64; GAIN_CYCLE_LEN] = [1.25, 0.75, 1.0, 1.0, ...
  method init (line 13) | pub(super) fn init(&mut self) {
  method enter_startup (line 29) | pub(crate) fn enter_startup(&mut self) {
  method init_full_pipe (line 36) | fn init_full_pipe(&mut self) {
  method check_full_pipe (line 43) | pub(super) fn check_full_pipe(&mut self) {
  method enter_drain (line 63) | fn enter_drain(&mut self) {
  method check_drain (line 69) | pub(super) fn check_drain(&mut self) {
  method enter_probe_bw (line 79) | pub fn enter_probe_bw(&mut self) {
  method check_cycle_phase (line 91) | pub(super) fn check_cycle_phase(&mut self) {
  method advance_cycle_phase (line 97) | fn advance_cycle_phase(&mut self) {
  method is_next_cycle_phase (line 104) | fn is_next_cycle_phase(&mut self) -> bool {
  method handle_restart_from_idle (line 125) | pub(super) fn handle_restart_from_idle(&mut self) {
  method check_probe_rtt (line 136) | pub(super) fn check_probe_rtt(&mut self) {
  method enter_probe_rtt (line 153) | fn enter_probe_rtt(&mut self) {
  method handle_probe_rtt (line 160) | fn handle_probe_rtt(&mut self) {
  method exit_probe_rtt (line 183) | fn exit_probe_rtt(&mut self, _: Instant) {
  function test_bbr_init (line 202) | fn test_bbr_init() {
  function test_bbr_enter_startup (line 212) | fn test_bbr_enter_startup() {
  function test_bbr_check_full_pipe (line 221) | fn test_bbr_check_full_pipe() {
  function test_bbr_check_drain (line 249) | fn test_bbr_check_drain() {
  function test_bbr_enter_probe_bw (line 265) | fn test_bbr_enter_probe_bw() {
  function test_bbr_advance_cycle_phase (line 274) | fn test_bbr_advance_cycle_phase() {
  function test_bbr_is_next_cycle_phase (line 287) | fn test_bbr_is_next_cycle_phase() {
  function test_restart_from_idle (line 308) | fn test_restart_from_idle() {

FILE: qcongestion/src/algorithm/new_reno.rs
  constant INFINITRE_SSTHRESH (line 15) | const INFINITRE_SSTHRESH: usize = usize::MAX;
  type NewReno (line 17) | pub(crate) struct NewReno {
    method new (line 37) | pub(crate) fn new(max_datagram_size: Arc<AtomicU16>) -> Self {
    method on_packet_sent_cc (line 56) | fn on_packet_sent_cc(&mut self, sent_bytes: usize) {
    method in_congestion_recovery (line 63) | fn in_congestion_recovery(&self, sent_time: &Instant) -> bool {
    method on_packet_acked (line 89) | fn on_packet_acked(&mut self, acked_packet: &SentPacket) {
    method on_congestion_event (line 122) | fn on_congestion_event(&mut self, sent_time: &Instant) {
    method process_ecn (line 147) | fn process_ecn(&mut self, ack: &AckFrame, sent_time: &Instant, epoch: ...
    method on_packets_lost (line 180) | fn on_packets_lost(
    method remove_from_bytes_in_flight (line 211) | fn remove_from_bytes_in_flight(
    method max_datagram_size (line 222) | fn max_datagram_size(&self) -> usize {
  method from (line 27) | fn from(reno: &NewReno) -> Self {
  method on_packet_sent_cc (line 228) | fn on_packet_sent_cc(&mut self, packet: &SentPacket) {
  method on_packet_acked (line 232) | fn on_packet_acked(&mut self, acked_packet: &SentPacket) {
  method on_packets_lost (line 236) | fn on_packets_lost(
  method congestion_window (line 244) | fn congestion_window(&self) -> usize {
  method pacing_rate (line 248) | fn pacing_rate(&self) -> Option<usize> {
  method remove_from_bytes_in_flight (line 252) | fn remove_from_bytes_in_flight(&mut self, packets: &mut dyn Iterator<Ite...
  method process_ecn (line 256) | fn process_ecn(&mut self, ack: &AckFrame, sent_time: &Instant, epoch: Ep...

FILE: qcongestion/src/congestion.rs
  constant INIT_CWND (line 20) | const INIT_CWND: usize = MSS * 10;
  constant PACKET_THRESHOLD (line 21) | const PACKET_THRESHOLD: usize = 3;
  type CongestionController (line 25) | pub struct CongestionController {
    method init (line 48) | fn init(
    method on_packet_sent (line 96) | pub fn on_packet_sent(
    method on_datagram_rcvd (line 132) | pub fn on_datagram_rcvd(&mut self) {
    method on_ack_rcvd (line 183) | pub fn on_ack_rcvd(&mut self, epoch: Epoch, ack_frame: &AckFrame, now:...
    method set_loss_detection_timer (line 242) | fn set_loss_detection_timer(&mut self) {
    method on_loss_detection_timeout (line 289) | fn on_loss_detection_timeout(&mut self) -> u32 {
    method get_loss_time_and_epoch (line 334) | fn get_loss_time_and_epoch(&self) -> Option<(Instant, Epoch)> {
    method get_pto_time_and_epoch (line 370) | fn get_pto_time_and_epoch(&self) -> Option<(Instant, Epoch)> {
    method no_ack_eliciting_in_flight (line 406) | fn no_ack_eliciting_in_flight(&self) -> bool {
    method peer_completed_address_validation (line 418) | fn peer_completed_address_validation(&self) -> bool {
    method process_ecn (line 424) | fn process_ecn(&mut self, ack: &AckFrame, sent_time: &Instant, epoch: ...
    method send_ack_eliciting_packet (line 428) | fn send_ack_eliciting_packet(&mut self, epoch: Epoch, count: usize) {
    method need_ack (line 434) | fn need_ack(&self) -> bool {
    method send_quota (line 439) | fn send_quota(&mut self) -> usize {
    method discard_epoch (line 459) | fn discard_epoch(&mut self, epoch: Epoch) {
    method get_pto (line 467) | fn get_pto(&self, epoch: Epoch) -> Duration {
  type ArcCC (line 477) | pub struct ArcCC(Arc<Mutex<CongestionController>>);
    method new (line 480) | pub fn new(
    method do_tick (line 498) | fn do_tick(&self) -> Result<(), TooManyPtos> {
    method send_quota (line 519) | fn send_quota(&self) -> Result<usize, Signals> {
    method retransmit_and_expire_time (line 530) | fn retransmit_and_expire_time(&self, epoch: Epoch) -> (Duration, Durat...
    method need_ack (line 539) | fn need_ack(&self, epoch: Epoch) -> Option<(u64, Instant)> {
    method on_pkt_sent (line 544) | fn on_pkt_sent(
    method on_ack_rcvd (line 567) | fn on_ack_rcvd(&self, epoch: Epoch, ack_frame: &AckFrame) {
    method on_pkt_rcvd (line 578) | fn on_pkt_rcvd(&self, epoch: Epoch, pn: u64, is_ack_eliciting: bool) {
    method get_pto (line 587) | fn get_pto(&self, epoch: Epoch) -> Duration {
    method discard_epoch (line 592) | fn discard_epoch(&self, epoch: Epoch) {
    method need_send_ack_eliciting (line 597) | fn need_send_ack_eliciting(&self, epoch: Epoch) -> usize {
    method grant_anti_amplification (line 602) | fn grant_anti_amplification(&self) {

FILE: qcongestion/src/lib.rs
  constant MSS (line 17) | pub const MSS: usize = 1200;
  type TooManyPtos (line 21) | pub struct TooManyPtos(u32);
  type Transport (line 24) | pub trait Transport {
    method do_tick (line 26) | fn do_tick(&self) -> Result<(), TooManyPtos>;
    method send_quota (line 30) | fn send_quota(&self) -> Result<usize, Signals>;
    method retransmit_and_expire_time (line 33) | fn retransmit_and_expire_time(&self, epoch: Epoch) -> (Duration, Durat...
    method on_pkt_sent (line 42) | fn on_pkt_sent(
    method on_pkt_rcvd (line 56) | fn on_pkt_rcvd(&self, space: Epoch, pn: u64, is_ack_elicition: bool);
    method need_ack (line 61) | fn need_ack(&self, space: Epoch) -> Option<(u64, Instant)>;
    method need_send_ack_eliciting (line 64) | fn need_send_ack_eliciting(&self, space: Epoch) -> usize;
    method on_ack_rcvd (line 67) | fn on_ack_rcvd(&self, space: Epoch, ack_frame: &AckFrame);
    method get_pto (line 72) | fn get_pto(&self, epoch: Epoch) -> Duration;
    method discard_epoch (line 75) | fn discard_epoch(&self, epoch: Epoch);
    method grant_anti_amplification (line 78) | fn grant_anti_amplification(&self);
  type Feedback (line 82) | pub trait Feedback: Send + Sync {
    method may_loss (line 86) | fn may_loss(&self, trigger: PacketLostTrigger, pns: &mut dyn Iterator<...

FILE: qcongestion/src/pacing.rs
  constant BURST_INTERVAL (line 4) | const BURST_INTERVAL: Duration = Duration::from_millis(10);
  constant MIN_BURST_SIZE (line 5) | const MIN_BURST_SIZE: usize = 10;
  constant MAX_BURST_SIZE (line 6) | const MAX_BURST_SIZE: usize = 1280;
  constant N (line 9) | const N: f64 = 1.25;
  type Pacer (line 11) | pub(super) struct Pacer {
    method new (line 20) | pub(super) fn new(
    method on_sent (line 38) | pub(super) fn on_sent(&mut self, packet_size: usize) {
    method schedule (line 43) | pub(super) fn schedule(
    method calculate_capacity (line 81) | fn calculate_capacity(
  function test_pacer_initialization (line 104) | fn test_pacer_initialization() {
  function test_on_sent (line 134) | fn test_on_sent() {
  function test_schedule_no_rate (line 152) | fn test_schedule_no_rate() {
  function test_schedule_with_rate (line 190) | fn test_schedule_with_rate() {

FILE: qcongestion/src/packets.rs
  type State (line 9) | pub(crate) enum State {
  type SentPacket (line 17) | pub struct SentPacket {
    method new (line 27) | pub(crate) fn new(
  method partial_cmp (line 46) | fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
  method eq (line 52) | fn eq(&self, other: &Self) -> bool {
  method cmp (line 58) | fn cmp(&self, other: &Self) -> Ordering {
  type RcvdRecords (line 67) | pub(crate) struct RcvdRecords {
    method new (line 76) | pub(crate) fn new(epoch: Epoch, max_ack_delay: Duration) -> Self {
    method on_pkt_rcvd (line 86) | pub(crate) fn on_pkt_rcvd(&mut self, pn: u64) {
    method need_ack (line 117) | pub(crate) fn need_ack(&self) -> Option<(u64, Instant)> {
    method on_ack_sent (line 134) | pub(crate) fn on_ack_sent(&mut self, _pn: u64, _largest_acked: u64) {
  type PacketSpace (line 142) | pub(crate) struct PacketSpace {
    method with_epoch (line 157) | pub(crate) fn with_epoch(epoch: Epoch, max_ack_delay: Duration) -> Self {
    method update_largest_acked_packet (line 168) | pub(crate) fn update_largest_acked_packet(&mut self, pn: u64) {
    method on_ack_rcvd (line 172) | pub(crate) fn on_ack_rcvd(
    method no_ack_eliciting_in_flight (line 225) | pub(crate) fn no_ack_eliciting_in_flight(&self) -> bool {
    method detect_lost_packets (line 231) | pub(crate) fn detect_lost_packets(
    method discard (line 295) | pub(crate) fn discard(&mut self, algorithm: &mut Box<dyn Control>) {
  type NewlyAckedPackets (line 151) | pub(crate) struct NewlyAckedPackets {
  function test_packet_space (line 318) | fn test_packet_space() {
  function test_rcvd_records (line 390) | async fn test_rcvd_records() {

FILE: qcongestion/src/rtt.rs
  constant INITIAL_RTT (line 6) | pub const INITIAL_RTT: Duration = Duration::from_millis(33);
  constant MAX_INITIAL_RTT (line 7) | pub const MAX_INITIAL_RTT: Duration = Duration::from_millis(333);
  constant GRANULARITY (line 8) | const GRANULARITY: Duration = Duration::from_millis(1);
  constant TIME_THRESHOLD (line 9) | const TIME_THRESHOLD: f32 = 1.125;
  type Rtt (line 12) | pub struct Rtt {
    method update (line 46) | fn update(
    method loss_delay (line 82) | fn loss_delay(&self) -> Duration {
    method base_pto (line 91) | fn base_pto(&self, pto_count: u32) -> Duration {
    method try_backoff_rtt (line 95) | fn try_backoff_rtt(&mut self) {
  method from (line 22) | fn from(rtt: &Rtt) -> Self {
  method default (line 33) | fn default() -> Self {
  type ArcRtt (line 109) | pub struct ArcRtt(Arc<Mutex<Rtt>>);
    method new (line 113) | pub fn new() -> Self {
    method update (line 117) | pub fn update(&self, latest_rtt: Duration, ack_delay: Duration, is_han...
    method loss_delay (line 124) | pub fn loss_delay(&self) -> Duration {
    method smoothed_rtt (line 128) | pub fn smoothed_rtt(&self) -> Duration {
    method rttvar (line 132) | pub fn rttvar(&self) -> Duration {
    method base_pto (line 136) | pub fn base_pto(&self, pto_count: u32) -> Duration {
    method try_backoff_rtt (line 141) | pub fn try_backoff_rtt(&self) {

FILE: qcongestion/src/status.rs
  type HandshakeStatus (line 7) | pub struct HandshakeStatus {
    method new (line 15) | pub fn new(is_server: bool) -> Self {
    method got_handshake_key (line 26) | pub fn got_handshake_key(&self) {
    method received_handshake_ack (line 30) | pub fn received_handshake_ack(&self) {
    method handshake_confirmed (line 35) | pub fn handshake_confirmed(&self) {
  type PathStatus (line 41) | pub struct PathStatus {
    method new (line 48) | pub fn new(handshake: Arc<HandshakeStatus>, pmut: Arc<AtomicU16>) -> S...
    method is_server (line 56) | pub(crate) fn is_server(&self) -> bool {
    method has_handshake_key (line 60) | pub(crate) fn has_handshake_key(&self) -> bool {
    method has_received_handshake_ack (line 64) | pub(crate) fn has_received_handshake_ack(&self) -> bool {
    method is_handshake_confirmed (line 70) | pub(crate) fn is_handshake_confirmed(&self) -> bool {
    method is_at_anti_amplification_limit (line 76) | pub(crate) fn is_at_anti_amplification_limit(&self) -> bool {
    method release_anti_amplification_limit (line 80) | pub fn release_anti_amplification_limit(&self) {
    method enter_anti_amplification_limit (line 85) | pub fn enter_anti_amplification_limit(&self) {
    method pmtu (line 90) | pub(super) fn pmtu(&self) -> Arc<AtomicU16> {
    method mtu (line 94) | pub(crate) fn mtu(&self) -> usize {

FILE: qconnection/src/builder.rs
  method new_client (line 65) | pub fn new_client(server_name: String, token_sink: Arc<dyn TokenSink>) -...
  method new_server (line 73) | pub fn new_server(token_provider: Arc<dyn TokenProvider>) -> ServerFound...
  type ClientFoundation (line 82) | pub struct ClientFoundation {
    method with_parameters (line 89) | pub fn with_parameters(mut self, params: ClientParameters) -> Self {
    method with_tls_config (line 130) | pub fn with_tls_config(
  type ServerFoundation (line 95) | pub struct ServerFoundation {
    method with_parameters (line 102) | pub fn with_parameters(mut self, params: ServerParameters) -> Self {
    method with_client_auther (line 107) | pub fn with_client_auther(mut self, authers: Box<dyn AuthClient>) -> S...
    method with_tls_config (line 173) | pub fn with_tls_config(
  type ConnectionFoundation (line 113) | pub struct ConnectionFoundation<Foundation, TlsConfig> {
  type ClientConnectionFoundation (line 126) | pub type ClientConnectionFoundation = ConnectionFoundation<ClientFoundat...
  type ServerConnectionFoundation (line 127) | pub type ServerConnectionFoundation = ConnectionFoundation<ServerFoundat...
  function with_streams_concurrency_strategy (line 149) | pub fn with_streams_concurrency_strategy<F>(self, strategy_factory: &F) ...
  function with_zero_rtt (line 166) | pub fn with_zero_rtt(mut self, enabled: bool) -> Self {
  function with_streams_concurrency_strategy (line 192) | pub fn with_streams_concurrency_strategy<F>(self, strategy_factory: &F) ...
  function with_zero_rtt (line 209) | pub fn with_zero_rtt(mut self, enabled: bool) -> Self {
  function with_iface_factory (line 219) | pub fn with_iface_factory(mut self, factory: Arc<dyn ProductIO>) -> Self {
  function with_iface_manager (line 224) | pub fn with_iface_manager(mut self, ifaces: Arc<InterfaceManager>) -> Se...
  function with_quic_router (line 229) | pub fn with_quic_router(mut self, quic_router: Arc<QuicRouter>) -> Self {
  function with_locations (line 234) | pub fn with_locations(mut self, locations: Arc<Locations>) -> Self {
  function with_stun_servers (line 239) | pub fn with_stun_servers(mut self, stun_servers: Arc<[SocketAddr]>) -> S...
  function with_defer_idle_timeout (line 244) | pub fn with_defer_idle_timeout(mut self, timeout: Duration) -> Self {
  function initial_keys_with (line 250) | fn initial_keys_with(
  function with_cids (line 271) | pub fn with_cids(self, origin_dcid: ConnectionId) -> PendingConnection {
  function with_cids (line 343) | pub fn with_cids(self, origin_dcid: ConnectionId) -> PendingConnection {
  type PendingConnection (line 404) | pub struct PendingConnection {
    method with_qlog (line 467) | pub fn with_qlog(mut self, qlogger: Arc<dyn QLog>) -> Self {
    method run (line 472) | pub fn run(self) -> Connection {
  function init_stream_and_datagram (line 429) | fn init_stream_and_datagram<LR: IntoRole, RR: IntoRole>(
  function spawn_tls_handshake (line 590) | fn spawn_tls_handshake(components: &Components, tx_wakers: ArcSendWakers) {
  function tls_fin_handler (line 622) | fn tls_fin_handler(
  function spawn_drive_connection (line 736) | fn spawn_drive_connection(mut events: mpsc::UnboundedReceiver<Event>, st...

FILE: qconnection/src/events.rs
  type Event (line 15) | pub enum Event {
  type EmitEvent (line 30) | pub trait EmitEvent: Send + Sync {
    method emit (line 31) | fn emit(&self, event: Event);
    method emit (line 50) | fn emit(&self, event: Event) {
    method emit (line 84) | fn emit(&self, event: Event) {
  type ArcEventBroker (line 35) | pub struct ArcEventBroker {
    method new (line 41) | pub fn new<E: EmitEvent + 'static>(conn_state: ArcConnState, event_bro...
  function test_emit_event (line 96) | fn test_emit_event() {

FILE: qconnection/src/handshake.rs
  type RawHandshake (line 18) | pub type RawHandshake<T> = qbase::handshake::Handshake<T>;
  type Handshake (line 24) | pub struct Handshake<T>
  function new (line 37) | pub fn new(
  function discard_spaces_on_server_handshake_done (line 49) | pub fn discard_spaces_on_server_handshake_done(&self, paths: &ArcPathCon...
  function role (line 59) | pub fn role(&self) -> Role {
  function status (line 63) | pub fn status(&self) -> Arc<HandshakeStatus> {
  function discard_spaces_on_client_handshake_done (line 67) | pub fn discard_spaces_on_client_handshake_done(
  type HandshakeDoneReceiver (line 78) | pub struct HandshakeDoneReceiver<T>
  type Output (line 90) | type Output = ();
  function recv_frame (line 92) | fn recv_frame(&self, frame: HandshakeDoneFrame) -> Result<(), Error> {
  type Target (line 106) | type Target = HandshakeStatus;
  method deref (line 108) | fn deref(&self) -> &Self::Target {

FILE: qconnection/src/lib.rs
  type GuaranteedFrame (line 115) | pub enum GuaranteedFrame {
    type Error (line 122) | type Error = &'f Frame<D>;
    method try_from (line 124) | fn try_from(frame: &'f Frame<D>) -> Result<Self, Self::Error> {
  type InitialJournal (line 135) | pub type InitialJournal = journal::Journal<CryptoFrame>;
  type HandshakeJournal (line 137) | pub type HandshakeJournal = journal::Journal<CryptoFrame>;
  type DataJournal (line 139) | pub type DataJournal = journal::Journal<GuaranteedFrame>;
  type ArcReliableFrameDeque (line 141) | pub type ArcReliableFrameDeque = reliable::ArcReliableFrameDeque<Reliabl...
  type QuicRouterRegistry (line 142) | pub type QuicRouterRegistry = route::QuicRouterRegistry<ArcReliableFrame...
  type ArcLocalCids (line 143) | pub type ArcLocalCids = cid::ArcLocalCids<QuicRouterRegistry>;
  type ArcRemoteCids (line 144) | pub type ArcRemoteCids = cid::ArcRemoteCids<ArcReliableFrameDeque>;
  type CidRegistry (line 145) | pub type CidRegistry = cid::Registry<ArcLocalCids, ArcRemoteCids>;
  type ArcDcidCell (line 146) | pub type ArcDcidCell = cid::ArcCidCell<ArcReliableFrameDeque>;
  type FlowController (line 148) | pub type FlowController = flow::FlowController<ArcReliableFrameDeque>;
  type Credit (line 149) | pub type Credit<'a> = flow::Credit<'a, ArcReliableFrameDeque>;
  type Handshake (line 151) | pub type Handshake = handshake::Handshake<ArcReliableFrameDeque>;
  type RawHandshake (line 152) | pub type RawHandshake = handshake::RawHandshake<ArcReliableFrameDeque>;
  type DataStreams (line 154) | pub type DataStreams = streams::DataStreams<ArcReliableFrameDeque>;
  type StreamReader (line 155) | pub type StreamReader = recv::Reader<Ext<ArcReliableFrameDeque>>;
  type StreamWriter (line 156) | pub type StreamWriter = send::Writer<Ext<ArcReliableFrameDeque>>;
  type ArcPuncher (line 157) | pub type ArcPuncher =
  type Components (line 161) | pub struct Components {
    method role (line 204) | pub fn role(&self) -> Role {
    method metrics (line 212) | pub fn metrics(&self) -> &qbase::metric::ArcConnectionMetrics {
    method open_bi_stream (line 217) | pub fn open_bi_stream(
    method open_uni_stream (line 234) | pub fn open_uni_stream(&self) -> Impl_Future![Result<Option<(StreamId,...
    method accept_bi_stream (line 250) | pub fn accept_bi_stream(
    method accept_uni_stream (line 260) | pub fn accept_uni_stream(&self) -> Impl_Future![Result<(StreamId, Stre...
    method datagram_reader (line 269) | pub fn datagram_reader(&self) -> io::Result<DatagramReader> {
    method datagram_writer (line 275) | pub fn datagram_writer(&self) -> Impl_Future![io::Result<DatagramWrite...
    method add_path (line 290) | pub fn add_path(
    method del_path (line 300) | pub fn del_path(&self, pathway: &Pathway) {
    method local_agent (line 304) | pub fn local_agent(&self) -> Impl_Future![Result<Option<LocalAgent>, E...
    method remote_agent (line 316) | pub fn remote_agent(&self) -> Impl_Future![Result<Option<RemoteAgent>,...
    method enter_closing (line 332) | pub fn enter_closing(self, error: Error) -> Termination {
    method enter_draining (line 376) | pub fn enter_draining(self, ccf: ConnectionCloseFrame) -> Termination {
  type SpecificComponents (line 188) | pub enum SpecificComponents {
  type ConnectionState (line 423) | struct ConnectionState {
    method enter_closing (line 431) | pub fn enter_closing(&self, error: QuicError) -> Result<(), Error> {
    method application_close (line 440) | pub fn application_close(
    method enter_draining (line 458) | pub fn enter_draining(&self, ccf: ConnectionCloseFrame) -> bool {
    method try_map_components (line 470) | fn try_map_components<T>(&self, op: impl FnOnce(&Components) -> T) -> ...
    method try_map_components_future (line 480) | fn try_map_components_future<F, M>(
    method validate (line 494) | fn validate(&self) -> Result<(), Error> {
  method drop (line 518) | fn drop(&mut self) {
  type Connection (line 530) | pub struct Connection(Arc<ConnectionState>);
    method role (line 533) | pub fn role(&self) -> Result<Role, Error> {
    method close (line 540) | pub fn close(&self, reason: impl Into<Cow<'static, str>>, code: u64) -...
    method metrics (line 550) | pub fn metrics(&self) -> Result<qbase::metric::ArcConnectionMetrics, E...
    method open_bi_stream (line 556) | pub fn open_bi_stream(
    method open_uni_stream (line 564) | pub fn open_uni_stream(&self) -> Impl_Future![Result<Option<(StreamId,...
    method accept_bi_stream (line 571) | pub fn accept_bi_stream(
    method accept_uni_stream (line 579) | pub fn accept_uni_stream(&self) -> Impl_Future![Result<(StreamId, Stre...
    method datagram_reader (line 588) | pub fn datagram_reader(&self) -> Result<io::Result<DatagramReader>, Er...
    method datagram_writer (line 596) | pub async fn datagram_writer(&self) -> Result<io::Result<DatagramWrite...
    method add_path (line 603) | pub fn add_path(
    method del_path (line 614) | pub fn del_path(&self, pathway: &Pathway) -> Result<(), Error> {
    method origin_dcid (line 619) | pub fn origin_dcid(&self) -> Result<cid::ConnectionId, Error> {
    method handshaked (line 624) | pub fn handshaked(&self) -> Impl_Future![Result<(), Error>] {
    method terminated (line 630) | pub fn terminated(&self) -> Impl_Future![Error] {
    method local_agent (line 636) | pub fn local_agent(&self) -> Impl_Future![Result<Option<LocalAgent>, E...
    method remote_agent (line 642) | pub fn remote_agent(&self) -> Impl_Future![Result<Option<RemoteAgent>,...
    method server_name (line 648) | pub fn server_name(&self) -> Impl_Future![Result<String, Error>] {
    method add_local_endpoint (line 663) | pub fn add_local_endpoint(&self, bind: BindUri, addr: EndpointAddr) ->...
    method add_peer_endpoint (line 668) | pub fn add_peer_endpoint(
    method remove_address (line 677) | pub fn remove_address(&self, addr: SocketAddr) -> Result<(), Error> {
    method subscribe_local_address (line 682) | pub fn subscribe_local_address(&self) -> Result<(), Error> {
    method path_context (line 687) | pub fn path_context(&self) -> Result<ArcPathContexts, Error> {
    method validate (line 695) | pub fn validate(&self) -> Result<(), Error> {

FILE: qconnection/src/path.rs
  type Path (line 48) | pub struct Path {
    method new (line 193) | pub fn new(
    method cc (line 234) | pub fn cc(&self) -> &ArcCC {
    method on_packet_rcvd (line 238) | pub fn on_packet_rcvd(
    method grant_anti_amplification (line 254) | pub fn grant_anti_amplification(&self) {
    method mtu (line 259) | pub fn mtu(&self) -> u16 {
    method send_packets (line 263) | pub async fn send_packets(&self, bufs: &[io::IoSlice<'_>]) -> io::Resu...
    method deactivate (line 274) | pub fn deactivate(&self) {
    method active (line 278) | pub fn active(&self) {
    method link (line 282) | pub fn link(&self) -> &Link {
    method pathway (line 286) | pub fn pathway(&self) -> &Pathway {
    method bind_uri (line 290) | pub fn bind_uri(&self) -> BindUri {
    type Output (line 302) | type Output = ();
    method recv_frame (line 304) | fn recv_frame(&self, frame: PathChallengeFrame) -> Result<Self::Output...
    type Output (line 311) | type Output = ();
    method recv_frame (line 313) | fn recv_frame(&self, frame: PathResponseFrame) -> Result<Self::Output,...
  method get_or_try_create_path (line 68) | pub fn get_or_try_create_path(
  method drop (line 296) | fn drop(&mut self) {

FILE: qconnection/src/path/aa.rs
  constant DEFAULT_ANTI_FACTOR (line 5) | pub const DEFAULT_ANTI_FACTOR: usize = 3;
  type AntiAmplifier (line 10) | pub struct AntiAmplifier<const N: usize = DEFAULT_ANTI_FACTOR> {
  constant NORMAL (line 21) | const NORMAL: u8 = 0;
  constant GRANTED (line 22) | const GRANTED: u8 = 1;
  constant ABORTED (line 23) | const ABORTED: u8 = 2;
  function new (line 25) | pub fn new(tx_waker: ArcSendWaker) -> Self {
  function on_rcvd (line 34) | pub fn on_rcvd(&self, amount: usize) {
  function balance (line 44) | pub fn balance(&self) -> Result<Option<usize>, Signals> {
  function on_sent (line 71) | pub fn on_sent(&self, amount: usize) {
  function grant (line 77) | pub fn grant(&self) {
  function abort (line 92) | pub fn abort(&self) {
  function test_deposit_and_poll_apply (line 112) | fn test_deposit_and_poll_apply() {
  function test_multiple_deposits (line 133) | fn test_multiple_deposits() {

FILE: qconnection/src/path/burst.rs
  type PacketSpace (line 51) | pub trait PacketSpace<H> {
    method new_packet (line 54) | fn new_packet<'b, 's>(
  type Burst (line 62) | pub struct Burst {
    method assembler (line 296) | fn assembler<'a>(&'a self) -> Result<PacketsAssembler<'a>, BurstError> {
    method load_spaces (line 308) | fn load_spaces(
    method load_ping (line 450) | fn load_ping(&self, buffer: &mut [u8]) -> Result<(usize, PacketContent...
    method load_heartbeat (line 500) | fn load_heartbeat(&self, buffer: &mut [u8]) -> Result<(usize, PacketCo...
    method burst (line 515) | pub async fn burst<'b>(
  function new_burst (line 74) | pub fn new_burst(self: &Arc<Self>, components: &Components) -> Burst {
  type BurstError (line 93) | pub enum BurstError {
  type PacketsAssembler (line 98) | pub struct PacketsAssembler<'a> {
  function new (line 108) | fn new(
  function initial_scid (line 137) | fn initial_scid(&self) -> Result<ConnectionId, Signals> {
  function applied_dcid (line 144) | fn applied_dcid(&self) -> Result<ConnectionId, Signals> {
  function initial_dcid (line 162) | fn initial_dcid(&self) -> Result<ConnectionId, Signals> {
  function commit (line 169) | pub fn commit(&mut self, sent_bytes: usize, pkt_info: PacketInfo) {
  function new_header (line 183) | fn new_header(&self) -> Result<InitialHeader, Signals> {
  function new_header (line 192) | fn new_header(&self) -> Result<ZeroRttHeader, Signals> {
  function new_header (line 198) | fn new_header(&self) -> Result<HandshakeHeader, Signals> {
  function new_header (line 204) | fn new_header(&self) -> Result<OneRttHeader, Signals> {
  function assemble (line 210) | pub fn assemble<'s, 'b, H, Space, P>(
  type PackageIntoSpace (line 232) | pub type PackageIntoSpace<H, S> =
  type DataSources (line 235) | pub struct DataSources {
  method packages (line 243) | pub(super) fn packages(&self) -> DataSources {
  function ack_package (line 282) | fn ack_package<'s, S, F>(space: &'s S, cc: &ArcCC) -> AckPackege<'s>
  type PingSource (line 425) | struct PingSource {
    method dump (line 433) | fn dump(&mut self, target: &mut Target) -> Result<PacketContent, Signa...
  function ping_package (line 442) | fn ping_package(cc: &ArcCC, epoch: Epoch) -> PingSource {

FILE: qconnection/src/path/drive.rs
  function drive (line 7) | pub async fn drive(&self, _tls_handshake: ArcTlsHandshake) -> Result<(),...

FILE: qconnection/src/path/error.rs
  type CreatePathFailure (line 10) | pub enum CreatePathFailure {
  type PathDeactivated (line 18) | pub enum PathDeactivated {

FILE: qconnection/src/path/paths.rs
  type PathContext (line 28) | pub struct PathContext {
  type ArcPathContexts (line 35) | pub struct ArcPathContexts {
    method new (line 43) | pub fn new(tx_wakers: ArcSendWakers, broker: ArcEventBroker) -> Self {
    method assign_handshake_path (line 52) | pub fn assign_handshake_path(
    method handshake_path (line 67) | pub fn handshake_path(&self) -> Option<Arc<Path>> {
    method get_or_try_create_with (line 76) | pub fn get_or_try_create_with<T>(
    method get (line 105) | pub fn get(&self, pathway: &Pathway) -> Option<Arc<Path>> {
    method remove (line 109) | pub fn remove(&self, pathway: &Pathway, reason: &PathDeactivated) {
    method is_empty (line 123) | pub fn is_empty(&self) -> bool {
    method max_pto_duration (line 127) | pub fn max_pto_duration(&self) -> Option<Duration> {
    method paths (line 131) | pub fn paths<C: FromIterator<(Pathway, Arc<Path>)>>(&self) -> C {
    method discard_initial_and_handshake_space (line 138) | pub fn discard_initial_and_handshake_space(&self) {
    method clear (line 145) | pub fn clear(&self) {
    method on_path_validated (line 149) | pub fn on_path_validated(&self, pathway: Pathway) {

FILE: qconnection/src/path/util.rs
  type SendBuffer (line 18) | pub struct SendBuffer<T> {
  function new (line 24) | pub fn new(tx_waker: ArcSendWaker) -> Self {
  function write (line 35) | pub fn write(&self, frame: T) {
  function try_load_frames_into (line 43) | pub fn try_load_frames_into<P: ?Sized>(&self, packet: &mut P) -> Result<...
  function dump (line 64) | fn dump(&mut self, into: &mut P) -> Result<PacketContent, Signals> {
  type RecvBuffer (line 99) | pub struct RecvBuffer<T>(ArcAsyncDeque<T>);
  function new (line 103) | pub fn new() -> Self {
  function write (line 108) | pub fn write(&self, value: T) {
  function receive (line 113) | pub async fn receive(&self) -> Option<T> {
  function dismiss (line 121) | pub fn dismiss(&self) {
  type Item (line 127) | type Item = T;
  function poll_next (line 129) | fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<...
  type Item (line 135) | type Item = T;
  function poll_next (line 137) | fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<...
  type Constraints (line 144) | pub struct Constraints {
    method new (line 162) | pub fn new(credit_limit: usize, send_quota: usize) -> Self {
    method is_available (line 178) | pub fn is_available(&self) -> bool {
    method constrain (line 183) | pub fn constrain<'b>(&self, buf: &'b mut [u8]) -> &'b mut [u8] {
    method available (line 191) | pub fn available(&self) -> usize {
    method commit (line 203) | pub fn commit(&mut self, len: usize, in_flight: bool) {
  type ApplyConstraints (line 212) | pub trait ApplyConstraints {
    method apply (line 214) | fn apply(self, constraints: &Constraints) -> Self;
    method apply (line 218) | fn apply(self, constraints: &Constraints) -> Self {

FILE: qconnection/src/path/validate.rs
  type ValidateFailure (line 9) | pub enum ValidateFailure {
  function validated (line 19) | pub fn validated(&self) {
  function validate (line 24) | pub async fn validate(&self) -> Result<(), ValidateFailure> {

FILE: qconnection/src/space.rs
  type Spaces (line 42) | pub struct Spaces {
    method new (line 49) | pub fn new(
    method initial (line 61) | pub fn initial(&self) -> &Arc<initial::InitialSpace> {
    method handshake (line 65) | pub fn handshake(&self) -> &Arc<handshake::HandshakeSpace> {
    method data (line 69) | pub fn data(&self) -> &Arc<data::DataSpace> {
    method send_ccf_packets (line 103) | pub async fn send_ccf_packets(&self, t: &Terminator) {
  function assemble_closing_packet (line 74) | fn assemble_closing_packet<'s, 'b: 's, H, S>(
  function pipe (line 125) | fn pipe<F: Send + Debug + 'static>(
  type FlowControlledDataStreams (line 147) | struct FlowControlledDataStreams {
    method new (line 153) | fn new(streams: DataStreams, flow_ctrl: FlowController) -> Self {
    type Output (line 159) | type Output = ();
    method recv_frame (line 161) | fn recv_frame(&self, data_frame: (StreamFrame, Bytes)) -> Result<Self:...
    type Output (line 170) | type Output = ();
    method recv_frame (line 172) | fn recv_frame(&self, frame: StreamCtlFrame) -> Result<Self::Output, Er...
  type AckInitialSpace (line 180) | struct AckInitialSpace {
    method new (line 186) | fn new(journal: &Journal<CryptoFrame>, crypto_stream: &CryptoStream) -...
    type Output (line 195) | type Output = ();
    method recv_frame (line 197) | fn recv_frame(&self, ack_frame: AckFrame) -> Result<Self::Output, Erro...
  type AckHandshakeSpace (line 216) | struct AckHandshakeSpace {
    method new (line 222) | fn new(journal: &Journal<CryptoFrame>, crypto_stream: &CryptoStream) -...
    type Output (line 231) | type Output = ();
    method recv_frame (line 233) | fn recv_frame(&self, ack_frame: AckFrame) -> Result<Self::Output, Erro...
  type AckDataSpace (line 252) | struct AckDataSpace {
    method new (line 259) | fn new(
    type Output (line 273) | type Output = ();
    method recv_frame (line 275) | fn recv_frame(&self, ack_frame: AckFrame) -> Result<Self::Output, Erro...
  function spawn_deliver_and_parse (line 304) | pub fn spawn_deliver_and_parse(components: &Components) {
  function filter_odcid_packet (line 339) | fn filter_odcid_packet<H: GetDcid>(
  function read_plain_packet (line 362) | fn read_plain_packet<H>(

FILE: qconnection/src/space/data.rs
  type CipherZeroRttPacket (line 51) | pub type CipherZeroRttPacket = CipherPacket<ZeroRttHeader>;
  type PlainZeroRttPacket (line 52) | pub type PlainZeroRttPacket = PlainPacket<ZeroRttHeader>;
  type ReceivedZeroRttFrom (line 53) | pub type ReceivedZeroRttFrom = (CipherZeroRttPacket, (BindUri, Pathway, ...
  type CipherOneRttPacket (line 55) | pub type CipherOneRttPacket = CipherPacket<OneRttHeader>;
  type PlainOneRttPacket (line 56) | pub type PlainOneRttPacket = PlainPacket<OneRttHeader>;
  type ReceivedOneRttFrom (line 57) | pub type ReceivedOneRttFrom = (CipherOneRttPacket, (BindUri, Pathway, Li...
  type DataSpace (line 59) | pub struct DataSpace {
    method as_ref (line 66) | fn as_ref(&self) -> &DataJournal {
    method new (line 72) | pub fn new(zero_rtt_keys: ArcZeroRttKeys) -> Self {
    method decrypt_0rtt_packet (line 80) | pub async fn decrypt_0rtt_packet(
    method decrypt_1rtt_packet (line 98) | pub async fn decrypt_1rtt_packet(
    method is_one_rtt_keys_ready (line 113) | pub fn is_one_rtt_keys_ready(&self) -> bool {
    method is_zero_rtt_avaliable (line 117) | pub fn is_zero_rtt_avaliable(&self) -> bool {
    method one_rtt_keys (line 121) | pub fn one_rtt_keys(&self) -> ArcOneRttKeys {
    method zero_rtt_keys (line 125) | pub fn zero_rtt_keys(&self) -> ArcZeroRttKeys {
    method journal (line 129) | pub(crate) fn journal(&self) -> &DataJournal {
    method tracker (line 133) | pub fn tracker(
    type JournalFrame (line 155) | type JournalFrame = GuaranteedFrame;
    method new_packet (line 157) | fn new_packet<'b, 's>(
    type PacketAssembler (line 184) | type PacketAssembler<'a> = TrivialPacketWriter<'a, 'a, GuaranteedFrame>;
    method new_packet (line 187) | fn new_packet<'a>(
    type JournalFrame (line 205) | type JournalFrame = GuaranteedFrame;
    method new_packet (line 207) | fn new_packet<'b, 's>(
    type PacketAssembler (line 232) | type PacketAssembler<'a> = TrivialPacketWriter<'a, 'a, GuaranteedFrame>;
    method new_packet (line 235) | fn new_packet<'a>(
  method epoch (line 149) | fn epoch(&self) -> Epoch {
  function frame_dispathcer (line 255) | fn frame_dispathcer(
  function parse_normal_zero_rtt_packet (line 420) | async fn parse_normal_zero_rtt_packet(
  function parse_normal_one_rtt_packet (line 460) | async fn parse_normal_one_rtt_packet(
  function parse_closing_one_rtt_packet (line 503) | fn parse_closing_one_rtt_packet(
  function deliver_and_parse_packets (line 524) | pub async fn deliver_and_parse_packets(
  type DataTracker (line 599) | pub struct DataTracker {
  method may_loss (line 607) | fn may_loss(&self, trigger: PacketLostTrigger, pns: &mut dyn Iterator<It...

FILE: qconnection/src/space/handshake.rs
  type CipherHanshakePacket (line 35) | pub type CipherHanshakePacket = CipherPacket<HandshakeHeader>;
  type PlainHandshakePacket (line 36) | pub type PlainHandshakePacket = PlainPacket<HandshakeHeader>;
  type ReceivedFrom (line 37) | pub type ReceivedFrom = (CipherHanshakePacket, Way);
  type HandshakeSpace (line 39) | pub struct HandshakeSpace {
    method as_ref (line 45) | fn as_ref(&self) -> &HandshakeJournal {
    method new (line 51) | pub fn new() -> Self {
    method keys (line 58) | pub fn keys(&self) -> ArcKeys {
    method decrypt_packet (line 62) | pub async fn decrypt_packet(
    method tracker (line 79) | pub fn tracker(&self, crypto_stream: CryptoStream) -> HandshakeTracker {
    type JournalFrame (line 100) | type JournalFrame = CryptoFrame;
    method new_packet (line 102) | fn new_packet<'b, 's>(
    type PacketAssembler (line 122) | type PacketAssembler<'a> = TrivialPacketWriter<'a, 'a, CryptoFrame>;
    method new_packet (line 125) | fn new_packet<'a>(
  method default (line 88) | fn default() -> Self {
  method epoch (line 94) | fn epoch(&self) -> Epoch {
  function frame_dispathcer (line 135) | fn frame_dispathcer(
  function parse_normal_packet (line 171) | async fn parse_normal_packet(
  function parse_closing_packet (line 215) | fn parse_closing_packet(
  function deliver_and_parse_packets (line 239) | pub async fn deliver_and_parse_packets(
  type HandshakeTracker (line 288) | pub struct HandshakeTracker {
  method may_loss (line 294) | fn may_loss(&self, trigger: PacketLostTrigger, pns: &mut dyn Iterator<It...

FILE: qconnection/src/space/initial.rs
  type CipherInitialPacket (line 40) | pub type CipherInitialPacket = CipherPacket<InitialHeader>;
  type PlainInitialPacket (line 41) | pub type PlainInitialPacket = PlainPacket<InitialHeader>;
  type ReceivedFrom (line 42) | pub type ReceivedFrom = (CipherInitialPacket, Way);
  type InitialSpace (line 44) | pub struct InitialSpace {
    method as_ref (line 50) | fn as_ref(&self) -> &InitialJournal {
    method new (line 57) | pub fn new(keys: Keys) -> Self {
    method keys (line 65) | pub fn keys(&self) -> ArcKeys {
    method decrypt_packet (line 69) | pub async fn decrypt_packet(
    method tracker (line 86) | pub fn tracker(&self, crypto_stream: CryptoStream) -> InitialTracker {
    type JournalFrame (line 101) | type JournalFrame = CryptoFrame;
    method new_packet (line 103) | fn new_packet<'b, 's>(
    type PacketAssembler (line 123) | type PacketAssembler<'a> = TrivialPacketWriter<'a, 'a, CryptoFrame>;
    method new_packet (line 126) | fn new_packet<'a>(
  method epoch (line 95) | fn epoch(&self) -> Epoch {
  function frame_dispathcer (line 136) | fn frame_dispathcer(
  function parse_normal_packet (line 170) | async fn parse_normal_packet(
  function parse_closing_packet (line 250) | fn parse_closing_packet(
  function deliver_and_parse_packets (line 274) | pub async fn deliver_and_parse_packets(
  type InitialTracker (line 324) | pub struct InitialTracker {
  method may_loss (line 330) | fn may_loss(&self, trigger: PacketLostTrigger, pns: &mut dyn Iterator<It...

FILE: qconnection/src/state.rs
  type ArcConnState (line 27) | pub struct ArcConnState {
    method new (line 44) | pub fn new() -> Self {
    method try_entry_attempted (line 53) | pub fn try_entry_attempted(&self, components: &Components, link: Link)...
    method update (line 98) | pub fn update(&self, state: QlogConnectionState) -> Option<QlogConnect...
    method enter_handshaked (line 127) | pub fn enter_handshaked(&self) -> Option<QlogConnectionState> {
    method enter_closing (line 135) | pub fn enter_closing(&self, error: &(impl Into<Error> + Clone)) -> Opt...
    method enter_draining (line 145) | pub fn enter_draining(&self, ccf: &ConnectionCloseFrame) -> Option<Qlo...
    method handshaked (line 157) | pub fn handshaked(&self) -> impl Future<Output = Result<(), Error>> + ...
    method terminated (line 170) | pub fn terminated(&self) -> impl Future<Output = Error> + Send + use<> {
    method current (line 177) | pub fn current(&self) -> Option<QlogConnectionState> {
  method default (line 34) | fn default() -> Self {
  constant HANDSHAKE_CONFIRMED (line 213) | pub const HANDSHAKE_CONFIRMED: QlogConnectionState =
  constant CLOSING (line 216) | pub const CLOSING: QlogConnectionState =
  constant DRAINING (line 219) | pub const DRAINING: QlogConnectionState =
  constant CLOSED (line 222) | pub const CLOSED: QlogConnectionState =

FILE: qconnection/src/termination.rs
  type Terminator (line 31) | pub struct Terminator {
    method new_header (line 47) | fn new_header(&self) -> Result<InitialHeader, Signals> {
    method new_header (line 57) | fn new_header(&self) -> Result<HandshakeHeader, Signals> {
    method new_header (line 66) | fn new_header(&self) -> Result<OneRttHeader, Signals> {
    method new (line 76) | pub fn new(ccf: ConnectionCloseFrame, components: &Components) -> Self {
    method should_send (line 87) | pub fn should_send(&self) -> bool {
    method try_send (line 102) | pub async fn try_send<W>(&self, mut write: W)
    method try_send_on (line 118) | pub async fn try_send_on<W>(&self, pathway: Pathway, write: W)
  method drop (line 41) | fn drop(&mut self) {
  type State (line 139) | enum State {
  type Termination (line 145) | pub struct Termination {
    method closing (line 154) | pub fn closing(error: Error, local_cids: ArcLocalCids, state: Arc<Rcvd...
    method draining (line 162) | pub fn draining(error: Error, local_cids: ArcLocalCids) -> Self {
    method error (line 170) | pub fn error(&self) -> Error {
    method enter_draining (line 175) | pub fn enter_draining(&mut self) -> bool {

FILE: qconnection/src/tls.rs
  type TlsSession (line 33) | pub enum TlsSession {
    method poll_read_hs (line 41) | fn poll_read_hs(&mut self, cx: &mut Context, buf: &mut Vec<u8>) -> Pol...
    method write_hs (line 57) | fn write_hs(&mut self, buf: &[u8]) -> Result<(), rustls::Error> {
    method alert (line 71) | fn alert(&self) -> Option<rustls::AlertDescription> {
    method is_handshaking (line 78) | fn is_handshaking(&self) -> bool {
    method handshake_kind (line 85) | fn handshake_kind(&self) -> Option<HandshakeKind> {
    method is_finished (line 92) | fn is_finished(&self) -> bool {
    method r#yield (line 96) | fn r#yield(&self) -> TlsHandshakeInfo {
  constant QUIC_VERSION (line 38) | pub const QUIC_VERSION: rustls::quic::Version = rustls::quic::Version::V1;
  type ClientTlsSession (line 112) | pub struct ClientTlsSession {
    method init (line 158) | pub fn init(
    method local_agent (line 192) | fn local_agent(&self) -> MutexGuard<'_, Option<LocalAgent>> {
    method load_zero_rtt (line 197) | pub fn load_zero_rtt(&self) -> Option<(ServerParameters, DirectionalKe...
    method try_process_sh (line 210) | fn try_process_sh(&mut self) {
    method try_process_ee (line 215) | fn try_process_ee(&mut self, parameters: &ArcParameters) -> Result<(),...
  type ClientCertResolver (line 124) | struct ClientCertResolver {
  method resolve (line 131) | fn resolve(
  method only_raw_public_keys (line 148) | fn only_raw_public_keys(&self) -> bool {
  method has_certs (line 152) | fn has_certs(&self) -> bool {
  method drop (line 236) | fn drop(&mut self) {
  type ServerTlsSession (line 243) | pub struct ServerTlsSession {
    method init (line 280) | pub fn init(
    method send_lock (line 311) | pub fn send_lock(&self) -> &ArcSendLock {
    method local_agent (line 315) | fn local_agent(&self) -> MutexGuard<'_, Option<LocalAgent>> {
    method server_name (line 319) | pub fn server_name(&self) -> Option<String> {
    method try_process_ch (line 323) | fn try_process_ch(
    method try_process_cert (line 387) | fn try_process_cert(&mut self) -> Result<(), Error> {
  type ServerCertResolver (line 256) | struct ServerCertResolver {
  method resolve (line 262) | fn resolve(&self, client_hello: ClientHello<'_>) -> Option<Arc<Certified...
  method only_raw_public_keys (line 274) | fn only_raw_public_keys(&self) -> bool {
  method drop (line 427) | fn drop(&mut self) {
  type TlsHandshakeInfo (line 435) | pub enum TlsHandshakeInfo {
    method zero_rtt_accepted (line 448) | pub fn zero_rtt_accepted(&self) -> Option<bool> {
  type InfoState (line 458) | enum InfoState {
    method set (line 464) | fn set(&mut self, info: Arc<TlsHandshakeInfo>) {
    method poll_get (line 469) | fn poll_get(&mut self, cx: &mut Context) -> Poll<Arc<TlsHandshakeInfo>> {
    method get (line 479) | fn get(&self) -> Option<&Arc<TlsHandshakeInfo>> {
  method default (line 488) | fn default() -> Self {
  method drop (line 494) | fn drop(&mut self) {
  type TlsHandshake (line 503) | pub struct TlsHandshake {
  type ArcTlsHandshake (line 509) | pub struct ArcTlsHandshake(Arc<Mutex<Result<TlsHandshake, Error>>>);
    method new (line 512) | pub fn new(session: TlsSession) -> ArcTlsHandshake {
    method state (line 519) | fn state(&self) -> MutexGuard<'_, Result<TlsHandshake, Error>> {
    method read_hs (line 523) | async fn read_hs(&self, buf: &mut Vec<u8>) -> Result<Option<KeyChange>...
    method write_hs (line 534) | fn write_hs(&self, buf: &[u8]) -> Result<(), Error> {
    method info (line 552) | pub fn info(
    method is_finished (line 564) | pub fn is_finished(&self) -> Result<bool, Error> {
    method server_name (line 572) | pub fn server_name(&self) -> Result<Option<String>, Error> {
    method on_conn_error (line 581) | pub fn on_conn_error(&self, error: &Error) {
    method try_process_tls_message (line 585) | fn try_process_tls_message(
    method start (line 622) | pub fn start(

FILE: qconnection/src/tls/agent.rs
  type LocalAgent (line 13) | pub struct LocalAgent {
    method new (line 30) | pub fn new(name: Arc<str>, certified_key: Arc<CertifiedKey>) -> Self {
    method name (line 37) | pub fn name(&self) -> &str {
    method cert_chain (line 41) | pub fn cert_chain(&self) -> &[CertificateDer<'static>] {
    method public_key (line 45) | pub fn public_key(&self) -> SubjectPublicKeyInfoDer<'_> {
    method sign_algorithm (line 49) | pub fn sign_algorithm(&self) -> rustls::SignatureAlgorithm {
    method sign (line 53) | pub fn sign(&self, scheme: SignatureScheme, data: &[u8]) -> Result<Vec...
    method verify (line 57) | pub fn verify(
  type SignError (line 19) | pub enum SignError {
  ty
Condensed preview — 300 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,247K chars).
[
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 834,
    "preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Describe the b"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 595,
    "preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Is your fea"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/r2cn.md",
    "chars": 906,
    "preview": "---\nname: r2cn\nabout: r2cn 任务模板\ntitle: \"[r2cn] \"\nlabels: r2cn\nassignees: \"\"\n---\n\n[__任务__]\n\n[__任务分值__] 4 分\n\n[__背景描述__]\n\n["
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 505,
    "preview": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where "
  },
  {
    "path": ".github/workflows/benchmark.yml",
    "chars": 2824,
    "preview": "name: Benchmarks\n\non:\n  workflow_dispatch:  # Allows manual triggering\n  schedule:\n    - cron: '0 2 * * *'  # UTC 2:00 A"
  },
  {
    "path": ".github/workflows/codecov.yml",
    "chars": 667,
    "preview": "name: Coverage\n\non:\n  push:\n    branches: [\"main\"]\n  pull_request:\n    branches: ['main']\n\njobs:\n  coverage:\n    runs-on"
  },
  {
    "path": ".github/workflows/commitlint.yml",
    "chars": 234,
    "preview": "name: Commitlint\n\non:\n  push:\n    branches: [\"main\"]\n  pull_request:\n    branches: [\"main\"]\n\njobs:\n  commitlint:\n    run"
  },
  {
    "path": ".github/workflows/feishu-bot.yml",
    "chars": 1460,
    "preview": "name: feishu bot\n\non:\n  branch_protection_rule:\n    types: [created, deleted]\n  check_run:\n    types: [rerequested, comp"
  },
  {
    "path": ".github/workflows/rust.yml",
    "chars": 2159,
    "preview": "name: Rust\n\non:\n  push:\n    branches: [\"main\"]\n  pull_request:\n    branches: [\"main\"]\n\nenv:\n  CARGO_TERM_COLOR: always\n\n"
  },
  {
    "path": ".github/workflows/traversal.yml",
    "chars": 4504,
    "preview": "name: Traversal\n\non:\n  push:\n    branches: [\"main\", \"build/*\"]\n  pull_request:\n    branches: [\"main\"]\n  workflow_dispatc"
  },
  {
    "path": ".gitignore",
    "chars": 654,
    "preview": "# Generated by Cargo\n# will have compiled files and executables\ndebug/\ntarget/\n\n# Remove Cargo.lock from gitignore if cr"
  },
  {
    "path": ".pre-commit-config.yaml",
    "chars": 512,
    "preview": "repos:\n  - hooks:\n      - id: commitizen\n        stages:\n          - commit-msg\n    repo: https://github.com/commitizen-"
  },
  {
    "path": ".rustfmt.toml",
    "chars": 88,
    "preview": "imports_granularity = \"Crate\"\ngroup_imports = \"StdExternalCrate\"\nstyle_edition = \"2024\"\n"
  },
  {
    "path": ".rusty-hook.toml",
    "chars": 275,
    "preview": "[hooks]\n#pre-commit = \"cargo check && cargo clippy --all-targets --all -- -D warnings\"\n#pre-push = \"cargo check && cargo"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 5225,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participa"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 678,
    "preview": "# Contributing to dquic\n\nWelcome all feedback and PRs, including bug reports, feature requests, documentation improvemen"
  },
  {
    "path": "Cargo.toml",
    "chars": 2763,
    "preview": "[workspace]\nresolver = \"2\"\nmembers = [\n    \"qmacro\",\n    \"qbase\",\n    \"qevent\",\n    \"qrecovery\",\n    \"qcongestion\",\n    "
  },
  {
    "path": "LICENSE",
    "chars": 11356,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "README.md",
    "chars": 13622,
    "preview": "# dquic\n\n[![License: Apache-2.0](https://img.shields.io/github/license/genmeta/dquic)](https://www.apache.org/licenses/L"
  },
  {
    "path": "README_CN.md",
    "chars": 7719,
    "preview": "# dquic\n\n[![License: Apache-2.0](https://img.shields.io/github/license/genmeta/dquic)](https://www.apache.org/licenses/L"
  },
  {
    "path": "SECURITY.md",
    "chars": 520,
    "preview": "# Security Policy\n\n## Supported Versions\n\nUse this section to tell people about which versions of your project are\ncurre"
  },
  {
    "path": "benchmark/launch.py",
    "chars": 18301,
    "preview": "#!/usr/bin/env python3\n\n\nimport os\nimport subprocess\nimport re\nimport json\nimport logging\nimport shutil\nimport argparse\n"
  },
  {
    "path": "codecov.yml",
    "chars": 71,
    "preview": "coverage:\n  status:\n    patch: off\n    project: off\n  range: \"70..100\"\n"
  },
  {
    "path": "commitlint.config.js",
    "chars": 228,
    "preview": "module.exports = {\n  extends: ['@commitlint/config-conventional'],\n  rules: {\n    'header-max-length': [2, 'always', 160"
  },
  {
    "path": "dquic/Cargo.toml",
    "chars": 1662,
    "preview": "[package]\nname = \"dquic\"\nversion = \"0.5.0\"\nedition.workspace = true\ndescription = \"An IETF quic transport protocol imple"
  },
  {
    "path": "dquic/examples/echo-client.rs",
    "chars": 7453,
    "preview": "use std::{\n    borrow::Cow,\n    path::{Path, PathBuf},\n    sync::Arc,\n    time::Duration,\n};\n\nuse clap::Parser;\nuse dqui"
  },
  {
    "path": "dquic/examples/echo-server.rs",
    "chars": 4294,
    "preview": "use std::{path::PathBuf, sync::Arc, time::Duration};\n\nuse clap::Parser;\nuse dquic::{prelude::*, qinterface::io::IO};\nuse"
  },
  {
    "path": "dquic/examples/http-client.rs",
    "chars": 5799,
    "preview": "use std::{path::PathBuf, sync::Arc};\n\nuse clap::Parser;\nuse dquic::prelude::{handy::ToCertificate, *};\nuse http::{Uri, u"
  },
  {
    "path": "dquic/examples/http-server.rs",
    "chars": 5465,
    "preview": "use std::{path::PathBuf, sync::Arc};\n\nuse clap::Parser;\nuse dquic::{prelude::*, qinterface::io::IO};\nuse tokio::{\n    fs"
  },
  {
    "path": "dquic/examples/traversal-client.rs",
    "chars": 5039,
    "preview": "// use std::{io, net::SocketAddr};\n\n// use clap::Parser;\n// use dquic::{\n//     prelude::{\n//         Connection, Endpoi"
  },
  {
    "path": "dquic/examples/traversal-server.rs",
    "chars": 4495,
    "preview": "// use std::{io, net::SocketAddr, sync::Arc};\n\n// use clap::Parser;\n// use dquic::{\n//     prelude::{Connection, Paramet"
  },
  {
    "path": "dquic/src/cert.rs",
    "chars": 2896,
    "preview": "use std::path::Path;\n\nuse rustls::pki_types::{CertificateDer, PrivateKeyDer, pem::PemObject};\n\npub trait ToCertificate {"
  },
  {
    "path": "dquic/src/client.rs",
    "chars": 33899,
    "preview": "use std::{\n    collections::HashMap,\n    io,\n    net::SocketAddr,\n    str::FromStr,\n    sync::{\n        Arc,\n        ato"
  },
  {
    "path": "dquic/src/common.rs",
    "chars": 6610,
    "preview": "use std::{net::SocketAddr, sync::Arc};\n\nuse futures::{Stream, StreamExt, stream};\nuse qconnection::{\n    prelude::{Endpo"
  },
  {
    "path": "dquic/src/lib.rs",
    "chars": 1088,
    "preview": "#![doc=include_str!(\"../README.md\")]\n\npub mod prelude {\n    pub use ::qconnection;\n    pub use qconnection::prelude::*;\n"
  },
  {
    "path": "dquic/src/server.rs",
    "chars": 32535,
    "preview": "use std::{\n    collections::HashMap,\n    fmt::Debug,\n    io,\n    ops::{Deref, DerefMut},\n    pin::pin,\n    sync::Arc,\n  "
  },
  {
    "path": "dquic/tests/auth.rs",
    "chars": 14767,
    "preview": "use std::{future::Future, sync::Arc, time::Duration};\n\nuse dquic::{\n    prelude::{handy::*, *},\n    qbase,\n    qresolve:"
  },
  {
    "path": "dquic/tests/common/mod.rs",
    "chars": 3654,
    "preview": "// common is submod for both echo and auth tests\n#![allow(unused)]\n\nuse std::{\n    future::Future,\n    net::SocketAddr,\n"
  },
  {
    "path": "dquic/tests/echo.rs",
    "chars": 13896,
    "preview": "use std::{sync::Arc, time::Duration};\n\nuse dquic::{\n    prelude::{handy::*, *},\n    qbase::param::{ClientParameters, Ser"
  },
  {
    "path": "dquic/tests/echo_common/mod.rs",
    "chars": 2362,
    "preview": "// common is submod for echo, auth and traversal\n#![allow(unused)]\n\nuse std::sync::Arc;\n\nuse dquic::{prelude::*, qbase::"
  },
  {
    "path": "dquic/tests/traversal.rs",
    "chars": 12480,
    "preview": "use std::{\n    collections::HashMap,\n    io,\n    net::SocketAddr,\n    sync::{Arc, LazyLock},\n    time::Duration,\n};\n\nuse"
  },
  {
    "path": "h3-shim/Cargo.toml",
    "chars": 1445,
    "preview": "[package]\nname = \"h3-shim\"\nversion = \"0.5.0\"\nedition.workspace = true\ndescription = \"Shim libray between dquic and h3\"\nr"
  },
  {
    "path": "h3-shim/examples/README.md",
    "chars": 2192,
    "preview": "# h3-shim测试\n\n本测试所使用的密钥来自<https://github.com/hyperium/h3/tree/master/examples>,`h3-server.rs`和`h3-client.rs`的源代码亦是在其基础上修改"
  },
  {
    "path": "h3-shim/examples/h3-client.rs",
    "chars": 9958,
    "preview": "use std::{collections::HashMap, path::PathBuf, sync::Arc, time::Instant};\n\nuse clap::Parser;\nuse dquic::prelude::{\n    h"
  },
  {
    "path": "h3-shim/examples/h3-server.rs",
    "chars": 7514,
    "preview": "use std::{ops::Deref, path::PathBuf, sync::Arc};\n\nuse bytes::{Bytes, BytesMut};\nuse clap::Parser;\nuse dquic::{\n    prelu"
  },
  {
    "path": "h3-shim/src/conn.rs",
    "chars": 8736,
    "preview": "use std::{\n    ops::Deref,\n    pin::Pin,\n    sync::Arc,\n    task::{Context, Poll},\n};\n\nuse dquic::prelude::{Connection, "
  },
  {
    "path": "h3-shim/src/error.rs",
    "chars": 1177,
    "preview": "use std::{error::Error, sync::Arc};\n\nuse dquic::qbase;\nuse h3::quic::{ConnectionErrorIncoming, StreamErrorIncoming};\nuse"
  },
  {
    "path": "h3-shim/src/ext.rs",
    "chars": 2592,
    "preview": "// See https://github.com/hyperium/h3/issues/307\"\n\n// use std::{\n//     io,\n//     ops::Deref,\n//     task::{Context, Po"
  },
  {
    "path": "h3-shim/src/lib.rs",
    "chars": 283,
    "preview": "pub mod conn;\nmod error;\npub mod pool;\npub use conn::{OpenStreams, QuicConnection};\n#[cfg(feature = \"datagram\")]\npub mod"
  },
  {
    "path": "h3-shim/src/pool.rs",
    "chars": 24,
    "preview": "//! TODO: unimplemented\n"
  },
  {
    "path": "h3-shim/src/streams.rs",
    "chars": 6170,
    "preview": "use std::{\n    mem::MaybeUninit,\n    pin::Pin,\n    task::{Context, Poll, ready},\n};\n\nuse bytes::Buf;\nuse dquic::{\n    pr"
  },
  {
    "path": "interop/Dockerfile",
    "chars": 1199,
    "preview": "FROM docker.io/martenseemann/quic-network-simulator-endpoint:latest\n\nRUN env\n\n# download and build your QUIC implementat"
  },
  {
    "path": "interop/run_endpoint.sh",
    "chars": 1729,
    "preview": "#!/bin/bash\n\n# Set up the routing needed for the simulation\n/setup.sh\n\n# The following variables are available for use:\n"
  },
  {
    "path": "qbase/Cargo.toml",
    "chars": 1212,
    "preview": "[package]\nname = \"qbase\"\nversion = \"0.5.0\"\nedition.workspace = true\ndescription = \"Core structure of the QUIC protocol, "
  },
  {
    "path": "qbase/src/cid/connection_id.rs",
    "chars": 5902,
    "preview": "use std::{\n    hash::{Hash, Hasher},\n    ops::Deref,\n};\n\nuse nom::{IResult, bytes::streaming::take, number::streaming::b"
  },
  {
    "path": "qbase/src/cid/local_cid.rs",
    "chars": 14682,
    "preview": "use std::sync::{Arc, Mutex};\n\nuse super::{ConnectionId, GenUniqueCid, RetireCid};\nuse crate::{\n    error::{Error, ErrorK"
  },
  {
    "path": "qbase/src/cid/remote_cid.rs",
    "chars": 23713,
    "preview": "use std::{\n    collections::VecDeque,\n    ops::Deref,\n    sync::{Arc, Mutex},\n};\n\nuse super::ConnectionId;\nuse crate::{\n"
  },
  {
    "path": "qbase/src/cid.rs",
    "chars": 1334,
    "preview": "mod connection_id;\npub use connection_id::*;\n\nmod local_cid;\npub use local_cid::*;\n\nmod remote_cid;\npub use remote_cid::"
  },
  {
    "path": "qbase/src/error.rs",
    "chars": 14809,
    "preview": "use std::{borrow::Cow, fmt::Display};\n\nuse derive_more::From;\nuse thiserror::Error;\n\nuse crate::{\n    frame::{Connection"
  },
  {
    "path": "qbase/src/flow.rs",
    "chars": 16993,
    "preview": "use std::{\n    ops::{Deref, DerefMut},\n    sync::{Arc, Mutex},\n};\n\nuse crate::{\n    error::{Error, ErrorFrameType, Error"
  },
  {
    "path": "qbase/src/frame/ack.rs",
    "chars": 11886,
    "preview": "use std::ops::RangeInclusive;\n\nuse nom::{Parser, combinator::map};\n\nuse crate::{\n    frame::{GetFrameType, io::WriteFram"
  },
  {
    "path": "qbase/src/frame/add_address.rs",
    "chars": 3898,
    "preview": "use std::net::{IpAddr, SocketAddr};\n\nuse derive_more::Deref;\n\nuse super::{\n    EncodeSize, GetFrameType,\n    io::{WriteF"
  },
  {
    "path": "qbase/src/frame/connection_close.rs",
    "chars": 10320,
    "preview": "use std::borrow::Cow;\n\nuse derive_more::From;\nuse nom::bytes::complete::take;\n\nuse super::FrameType;\nuse crate::{\n    er"
  },
  {
    "path": "qbase/src/frame/crypto.rs",
    "chars": 7388,
    "preview": "use std::ops::Range;\n\nuse nom::Parser;\n\nuse crate::{\n    frame::{GetFrameType, io::WriteFrameType},\n    util::{Continuou"
  },
  {
    "path": "qbase/src/frame/data_blocked.rs",
    "chars": 2697,
    "preview": "use crate::{\n    frame::{GetFrameType, io::WriteFrameType},\n    varint::{VarInt, WriteVarInt, be_varint},\n};\n\n/// DATA_B"
  },
  {
    "path": "qbase/src/frame/datagram.rs",
    "chars": 4390,
    "preview": "use bytes::Buf;\nuse nom::IResult;\n\nuse super::{FrameType, GetFrameType, io::WriteFrameType};\nuse crate::{\n    util::{Con"
  },
  {
    "path": "qbase/src/frame/error.rs",
    "chars": 5216,
    "preview": "use nom::error::ErrorKind as NomErrorKind;\nuse thiserror::Error;\n\nuse super::FrameType;\nuse crate::{\n    error::{ErrorKi"
  },
  {
    "path": "qbase/src/frame/handshake_done.rs",
    "chars": 2579,
    "preview": "use super::EncodeSize;\nuse crate::frame::{GetFrameType, io::WriteFrameType};\n/// HandshakeDone frame\n///\n/// ```text\n///"
  },
  {
    "path": "qbase/src/frame/io.rs",
    "chars": 11606,
    "preview": "use std::{\n    pin::Pin,\n    task::{Context, Poll},\n};\n\nuse bytes::Bytes;\n\nuse super::{\n    ack::ack_frame_with_ecn, add"
  },
  {
    "path": "qbase/src/frame/max_data.rs",
    "chars": 3194,
    "preview": "use crate::{\n    frame::{GetFrameType, io::WriteFrameType},\n    varint::{VarInt, WriteVarInt, be_varint},\n};\n\n/// MAX_DA"
  },
  {
    "path": "qbase/src/frame/max_stream_data.rs",
    "chars": 3782,
    "preview": "use crate::{\n    frame::{GetFrameType, io::WriteFrameType},\n    sid::{StreamId, WriteStreamId, be_streamid},\n    varint:"
  },
  {
    "path": "qbase/src/frame/max_streams.rs",
    "chars": 6236,
    "preview": "use crate::{\n    frame::{GetFrameType, io::WriteFrameType},\n    sid::{Dir, MAX_STREAMS_LIMIT},\n    varint::{VarInt, Writ"
  },
  {
    "path": "qbase/src/frame/new_connection_id.rs",
    "chars": 6381,
    "preview": "use crate::{\n    cid::{ConnectionId, WriteConnectionId, be_connection_id},\n    frame::{GetFrameType, io::WriteFrameType}"
  },
  {
    "path": "qbase/src/frame/new_token.rs",
    "chars": 3201,
    "preview": "use derive_more::Deref;\n\nuse crate::{\n    frame::{GetFrameType, io::WriteFrameType},\n    varint::{VarInt, WriteVarInt, b"
  },
  {
    "path": "qbase/src/frame/padding.rs",
    "chars": 2367,
    "preview": "use crate::frame::{GetFrameType, io::WriteFrameType};\n/// PADDING Frame.\n///\n/// ```text\n/// PADDING Frame {\n///   Type "
  },
  {
    "path": "qbase/src/frame/path_challenge.rs",
    "chars": 3800,
    "preview": "use derive_more::Deref;\nuse rand::RngExt;\n\nuse crate::frame::{GetFrameType, io::WriteFrameType};\n/// PATH_CHALLENGE fram"
  },
  {
    "path": "qbase/src/frame/path_response.rs",
    "chars": 3782,
    "preview": "use std::ops::Deref;\n\nuse derive_more::Deref;\n\nuse crate::frame::{GetFrameType, io::WriteFrameType};\n/// PATH_RESPONSE F"
  },
  {
    "path": "qbase/src/frame/ping.rs",
    "chars": 2279,
    "preview": "use crate::frame::{GetFrameType, io::WriteFrameType};\n/// PING Frame.\n///\n/// ```text\n/// PING Frame {\n///   Type (i) = "
  },
  {
    "path": "qbase/src/frame/punch_done.rs",
    "chars": 2450,
    "preview": "use super::{\n    EncodeSize, GetFrameType,\n    io::{WriteFrame, WriteFrameType},\n};\nuse crate::{\n    frame::PunchHelloFr"
  },
  {
    "path": "qbase/src/frame/punch_hello.rs",
    "chars": 2142,
    "preview": "use super::{\n    EncodeSize, GetFrameType,\n    io::{WriteFrame, WriteFrameType},\n};\nuse crate::varint::{VarInt, WriteVar"
  },
  {
    "path": "qbase/src/frame/punch_me_now.rs",
    "chars": 4526,
    "preview": "use std::net::SocketAddr;\n\nuse derive_more::Deref;\n\nuse super::{\n    EncodeSize, GetFrameType,\n    io::{WriteFrame, Writ"
  },
  {
    "path": "qbase/src/frame/remove_address.rs",
    "chars": 1922,
    "preview": "use derive_more::Deref;\n\nuse super::{\n    EncodeSize, GetFrameType,\n    io::{WriteFrame, WriteFrameType},\n};\nuse crate::"
  },
  {
    "path": "qbase/src/frame/reset_stream.rs",
    "chars": 6137,
    "preview": "use thiserror::Error;\n\nuse crate::{\n    frame::{GetFrameType, io::WriteFrameType},\n    sid::{StreamId, WriteStreamId, be"
  },
  {
    "path": "qbase/src/frame/retire_connection_id.rs",
    "chars": 3132,
    "preview": "use crate::{\n    frame::{GetFrameType, io::WriteFrameType},\n    varint::{VarInt, WriteVarInt, be_varint},\n};\n\n/// RETIRE"
  },
  {
    "path": "qbase/src/frame/stop_sending.rs",
    "chars": 4419,
    "preview": "use crate::{\n    frame::{GetFrameType, io::WriteFrameType},\n    sid::{StreamId, WriteStreamId, be_streamid},\n    varint:"
  },
  {
    "path": "qbase/src/frame/stream.rs",
    "chars": 15325,
    "preview": "use std::ops::Range;\n\nuse super::GetFrameType;\nuse crate::{\n    frame::EncodeSize,\n    sid::{StreamId, WriteStreamId, be"
  },
  {
    "path": "qbase/src/frame/stream_data_blocked.rs",
    "chars": 3903,
    "preview": "use crate::{\n    frame::{GetFrameType, io::WriteFrameType},\n    sid::{StreamId, WriteStreamId, be_streamid},\n    varint:"
  },
  {
    "path": "qbase/src/frame/streams_blocked.rs",
    "chars": 5414,
    "preview": "use crate::{\n    frame::{GetFrameType, io::WriteFrameType},\n    sid::Dir,\n    varint::{VarInt, WriteVarInt, be_varint},\n"
  },
  {
    "path": "qbase/src/frame.rs",
    "chars": 38501,
    "preview": "use std::fmt::Debug;\n\nuse bytes::{Buf, BufMut, Bytes};\nuse derive_more::{Deref, DerefMut, From, TryInto};\nuse enum_dispa"
  },
  {
    "path": "qbase/src/handshake.rs",
    "chars": 9513,
    "preview": "use std::sync::{\n    Arc,\n    atomic::{AtomicBool, Ordering},\n};\n\nuse crate::{\n    error::{Error, ErrorKind, QuicError},"
  },
  {
    "path": "qbase/src/lib.rs",
    "chars": 3972,
    "preview": "#![allow(clippy::all)]\n//! # The QUIC base library\n//!\n//! The `qbase` library defines the necessary basic structures in"
  },
  {
    "path": "qbase/src/metric.rs",
    "chars": 5156,
    "preview": "use std::sync::{\n    Arc,\n    atomic::{AtomicU64, Ordering},\n};\n\n/// Metrics for tracking data volumes in a QUIC connect"
  },
  {
    "path": "qbase/src/net/addr.rs",
    "chars": 4281,
    "preview": "use std::{\n    fmt::Display,\n    net::{AddrParseError, SocketAddr},\n    ops::Deref,\n    str::FromStr,\n};\n\nuse bytes::Buf"
  },
  {
    "path": "qbase/src/net/nat.rs",
    "chars": 2015,
    "preview": "use std::io;\n\nuse crate::varint::VarInt;\n\nbitflags::bitflags! {\n    #[derive(Debug, Clone, Copy, PartialEq, Eq)]\n    pub"
  },
  {
    "path": "qbase/src/net/route.rs",
    "chars": 5588,
    "preview": "use std::{fmt::Display, net::SocketAddr};\n\nuse bytes::BufMut;\nuse derive_more::{Deref, DerefMut};\nuse nom::number::strea"
  },
  {
    "path": "qbase/src/net/tx.rs",
    "chars": 11694,
    "preview": "use std::{\n    collections::BTreeMap,\n    future::poll_fn,\n    sync::{Arc, Mutex, MutexGuard},\n    task::{Context, Poll,"
  },
  {
    "path": "qbase/src/net.rs",
    "chars": 3864,
    "preview": "use std::{\n    fmt::Display,\n    net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},\n    str::FromStr,\n};\n\nuse bytes::BufMut;"
  },
  {
    "path": "qbase/src/packet/decrypt.rs",
    "chars": 5178,
    "preview": "use rustls::quic::{HeaderProtectionKey, PacketKey};\n\nuse super::{\n    GetPacketNumberLength, KeyPhaseBit, LongSpecificBi"
  },
  {
    "path": "qbase/src/packet/encrypt.rs",
    "chars": 3235,
    "preview": "use std::ops::Deref;\n\nuse rustls::quic::{HeaderProtectionKey, PacketKey};\n\nuse super::{KeyPhaseBit, LongSpecificBits, Sh"
  },
  {
    "path": "qbase/src/packet/error.rs",
    "chars": 1759,
    "preview": "use nom::error::ErrorKind as NomErrorKind;\nuse thiserror::Error;\n\nuse super::r#type::Type;\n\n/// Parse error of QUIC pack"
  },
  {
    "path": "qbase/src/packet/header/long.rs",
    "chars": 18745,
    "preview": "use derive_more::{Deref, DerefMut};\n\nuse super::*;\nuse crate::{cid::ConnectionId, varint::VarInt};\n\n/// The long header "
  },
  {
    "path": "qbase/src/packet/header/short.rs",
    "chars": 3387,
    "preview": "use super::*;\nuse crate::{cid::ConnectionId, packet::SpinBit};\n\n/// A packet with a short header does not include a leng"
  },
  {
    "path": "qbase/src/packet/header.rs",
    "chars": 12437,
    "preview": "use enum_dispatch::enum_dispatch;\n\nuse crate::cid::ConnectionId;\n\n/// All structure definitions related to long headers."
  },
  {
    "path": "qbase/src/packet/io.rs",
    "chars": 29674,
    "preview": "use std::{any::Any, mem};\n\nuse bytes::BytesMut;\nuse nom::{Parser, multi::length_data};\n\nuse super::{\n    error::Error,\n "
  },
  {
    "path": "qbase/src/packet/keys.rs",
    "chars": 18391,
    "preview": "use std::{\n    future::Future,\n    ops::DerefMut,\n    pin::Pin,\n    sync::{Arc, Mutex, MutexGuard},\n    task::{Context, "
  },
  {
    "path": "qbase/src/packet/number.rs",
    "chars": 7340,
    "preview": "use std::cmp::max;\n\nuse bytes::BufMut;\nuse thiserror::Error;\n\n/// An encoded or undecoded packet number\n///\n/// The actu"
  },
  {
    "path": "qbase/src/packet/signal.rs",
    "chars": 2271,
    "preview": "/// The spin bit in 1-RTT packets\nconst SPIN_BIT: u8 = 0x20;\n/// The key phase bit in 1-RTT packets\nconst KEY_PHASE_BIT:"
  },
  {
    "path": "qbase/src/packet/type/long/v1.rs",
    "chars": 2148,
    "preview": "use crate::packet::{error::Error, r#type::FIXED_BIT};\n\n/// Long packet types. The 3th and 4th bits of the first byte of "
  },
  {
    "path": "qbase/src/packet/type/long.rs",
    "chars": 4992,
    "preview": "use derive_more::Deref;\n\n/// Supports IQuic version 1, if other versions are supported in the future, add them here.\npub"
  },
  {
    "path": "qbase/src/packet/type/short.rs",
    "chars": 1461,
    "preview": "use bytes::BufMut;\nuse derive_more::Deref;\n\nuse crate::packet::SpinBit;\n\nconst SHORT_HEADER_BIT: u8 = 0x00;\n\n/// The typ"
  },
  {
    "path": "qbase/src/packet/type.rs",
    "chars": 8263,
    "preview": "use derive_more::Deref;\n\nuse super::{KeyPhaseBit, PacketNumber, error::Error};\n\n/// Definitions of packet types related "
  },
  {
    "path": "qbase/src/packet.rs",
    "chars": 5972,
    "preview": "use std::{fmt::Debug, ops};\n\nuse bytes::{BufMut, BytesMut, buf::UninitSlice};\nuse derive_more::{Deref, DerefMut};\nuse en"
  },
  {
    "path": "qbase/src/param/core.rs",
    "chars": 9531,
    "preview": "use std::{collections::HashMap, marker::PhantomData, time::Duration};\n\nuse bytes::Bytes;\nuse derive_more::{From, TryInto"
  },
  {
    "path": "qbase/src/param/error.rs",
    "chars": 1486,
    "preview": "use std::ops::RangeInclusive;\n\nuse nom::error::ErrorKind as NomErrorKind;\nuse thiserror::Error;\n\nuse crate::{\n    error:"
  },
  {
    "path": "qbase/src/param/handy.rs",
    "chars": 1532,
    "preview": "use std::time::Duration;\n\nuse crate::param::ParameterId;\n\npub fn client_parameters() -> super::ClientParameters {\n    le"
  },
  {
    "path": "qbase/src/param/io.rs",
    "chars": 8373,
    "preview": "use std::{fmt::Debug, time::Duration};\n\nuse bytes::Bytes;\nuse nom::{Parser, multi::length_data};\n\nuse crate::{\n    cid::"
  },
  {
    "path": "qbase/src/param/preferred_address.rs",
    "chars": 3404,
    "preview": "use std::net::{SocketAddrV4, SocketAddrV6};\n\nuse getset::{CopyGetters, MutGetters, Setters};\nuse nom::Parser;\n\nuse crate"
  },
  {
    "path": "qbase/src/param.rs",
    "chars": 23000,
    "preview": "use std::{\n    fmt::Debug,\n    ops::{Deref, DerefMut},\n    sync::{Arc, Mutex, MutexGuard},\n    task::{Context, Poll, Wak"
  },
  {
    "path": "qbase/src/role.rs",
    "chars": 3149,
    "preview": "use std::{fmt, ops};\n\nuse crate::param::ParameterId;\n\n/// Roles in the QUIC protocol, including client and server.\n///\n/"
  },
  {
    "path": "qbase/src/sid/handy.rs",
    "chars": 1506,
    "preview": "use super::{ControlStreamsConcurrency, Dir};\n\n/// Consistent concurrency strategy increase limits as streams are closed,"
  },
  {
    "path": "qbase/src/sid/local_sid.rs",
    "chars": 10841,
    "preview": "use std::{\n    collections::VecDeque,\n    sync::{Arc, Mutex},\n    task::{Context, Poll, Waker},\n};\n\nuse super::{Dir, Rol"
  },
  {
    "path": "qbase/src/sid/remote_sid.rs",
    "chars": 10939,
    "preview": "use std::sync::{Arc, Mutex};\n\nuse thiserror::Error;\n\nuse super::{ControlStreamsConcurrency, Dir, Role, StreamId};\nuse cr"
  },
  {
    "path": "qbase/src/sid.rs",
    "chars": 10053,
    "preview": "use std::fmt;\n\nuse super::{\n    frame::MaxStreamsFrame,\n    varint::{VarInt, WriteVarInt, be_varint},\n};\nuse crate::{\n  "
  },
  {
    "path": "qbase/src/time.rs",
    "chars": 6736,
    "preview": "use std::sync::{Arc, Mutex, RwLock};\n\nuse thiserror::Error;\nuse tokio::time::{Duration, Instant};\n\nuse crate::{frame::Pi"
  },
  {
    "path": "qbase/src/token.rs",
    "chars": 4583,
    "preview": "use std::{ops::Deref, sync::Arc};\n\nuse bytes::BufMut;\nuse derive_more::Deref;\nuse nom::{IResult, bytes::complete::take};"
  },
  {
    "path": "qbase/src/util/async_deque.rs",
    "chars": 12589,
    "preview": "use std::{\n    collections::VecDeque,\n    future::Future,\n    pin::Pin,\n    sync::{Arc, Mutex, MutexGuard},\n    task::{C"
  },
  {
    "path": "qbase/src/util/bound_queue.rs",
    "chars": 1771,
    "preview": "use std::{\n    self,\n    future::poll_fn,\n    sync::{Arc, Mutex},\n};\n\nuse futures::{SinkExt, StreamExt, channel::mpsc};\n"
  },
  {
    "path": "qbase/src/util/data.rs",
    "chars": 4450,
    "preview": "use bytes::{BufMut, Bytes, BytesMut};\n\npub trait ContinuousData {\n    fn len(&self) -> usize;\n\n    fn is_empty(&self) ->"
  },
  {
    "path": "qbase/src/util/index_deque.rs",
    "chars": 19339,
    "preview": "use std::{\n    collections::VecDeque,\n    ops::{Index, IndexMut},\n};\n\nuse thiserror::Error;\n\n/// The index error type fo"
  },
  {
    "path": "qbase/src/util/unique_id.rs",
    "chars": 3297,
    "preview": "use std::{\n    hash::Hash,\n    sync::atomic::{AtomicUsize, Ordering},\n};\n\nuse derive_more::Into;\n\n/// Opque, hashable, u"
  },
  {
    "path": "qbase/src/util/wakers.rs",
    "chars": 2062,
    "preview": "use std::{\n    mem,\n    sync::{Arc, Mutex, MutexGuard},\n    task::{Context, Poll, Wake, Waker},\n    usize,\n};\n\nuse small"
  },
  {
    "path": "qbase/src/util.rs",
    "chars": 357,
    "preview": "mod async_deque;\npub use async_deque::ArcAsyncDeque;\n\nmod bound_queue;\npub use bound_queue::BoundQueue;\n\nmod data;\npub u"
  },
  {
    "path": "qbase/src/varint.rs",
    "chars": 10157,
    "preview": "use std::{cmp::Ordering, convert::TryFrom, fmt};\n\n/// An integer less than 2^62\n///\n/// Values of this type are suitable"
  },
  {
    "path": "qcongestion/Cargo.toml",
    "chars": 709,
    "preview": "[package]\nname = \"qcongestion\"\nversion = \"0.5.0\"\nedition.workspace = true\ndescription = \"Congestion control in QUIC, a p"
  },
  {
    "path": "qcongestion/src/algorithm/bbr/delivery_rate.rs",
    "chars": 5475,
    "preview": "// https://tools.ietf.org/html/draft-cheng-iccrg-delivery-rate-estimation-01\n\nuse std::time::{Duration, Instant};\n\nuse c"
  },
  {
    "path": "qcongestion/src/algorithm/bbr/min_max.rs",
    "chars": 2996,
    "preview": "use std::fmt::Debug;\n\n#[derive(Copy, Clone, Debug)]\npub(super) struct MinMax {\n    /// round count, not a timestamp\n    "
  },
  {
    "path": "qcongestion/src/algorithm/bbr/model.rs",
    "chars": 1877,
    "preview": "use std::time::Instant;\n\n// 4.1.  Maintaining the Network Path Model\n// This model includes two estimated parameters: se"
  },
  {
    "path": "qcongestion/src/algorithm/bbr/parameters.rs",
    "chars": 6765,
    "preview": "// 4.2.  BBR Control Parameters\n// BBR uses three distinct but interrelated control parameters: pacing rate,\n// send qua"
  },
  {
    "path": "qcongestion/src/algorithm/bbr/state.rs",
    "chars": 9621,
    "preview": "use std::time::Instant;\n\nuse super::{Bbr, BbrStateMachine, HIGH_GAIN, PROBE_RTT_DURATION};\nuse crate::rtt::INITIAL_RTT;\n"
  },
  {
    "path": "qcongestion/src/algorithm/bbr.rs",
    "chars": 12036,
    "preview": "use std::{\n    collections::VecDeque,\n    time::{Duration, Instant},\n};\n\nuse delivery_rate::Rate;\nuse min_max::MinMax;\nu"
  },
  {
    "path": "qcongestion/src/algorithm/new_reno.rs",
    "chars": 11948,
    "preview": "use std::sync::{\n    Arc,\n    atomic::{AtomicU16, Ordering},\n};\n\nuse qbase::{Epoch, frame::AckFrame};\nuse qevent::quic::"
  },
  {
    "path": "qcongestion/src/algorithm.rs",
    "chars": 847,
    "preview": "use qbase::{Epoch, frame::AckFrame};\nuse tokio::time::Instant;\n\nuse crate::packets::SentPacket;\n\n// pub(crate) mod bbr;\n"
  },
  {
    "path": "qcongestion/src/congestion.rs",
    "chars": 22582,
    "preview": "use std::sync::{Arc, Mutex};\n\nuse qbase::{\n    Epoch,\n    frame::AckFrame,\n    net::tx::{ArcSendWaker, Signals},\n};\nuse "
  },
  {
    "path": "qcongestion/src/lib.rs",
    "chars": 3466,
    "preview": "use qbase::{Epoch, frame::AckFrame, net::tx::Signals};\nuse qevent::quic::recovery::PacketLostTrigger;\nuse thiserror::Err"
  },
  {
    "path": "qcongestion/src/pacing.rs",
    "chars": 6651,
    "preview": "use tokio::time::{Duration, Instant};\n\n//  The burst  interval in milliseconds\nconst BURST_INTERVAL: Duration = Duration"
  },
  {
    "path": "qcongestion/src/packets.rs",
    "chars": 13757,
    "preview": "use std::{cmp::Ordering, collections::VecDeque, time::Duration};\n\nuse qbase::{Epoch, frame::AckFrame};\nuse tokio::time::"
  },
  {
    "path": "qcongestion/src/rtt.rs",
    "chars": 4489,
    "preview": "use std::sync::{Arc, Mutex};\n\nuse qevent::quic::recovery::RecoveryMetricsUpdated;\nuse tokio::time::{Duration, Instant};\n"
  },
  {
    "path": "qcongestion/src/status.rs",
    "chars": 2582,
    "preview": "use std::sync::{\n    Arc,\n    atomic::{AtomicBool, AtomicU16, Ordering},\n};\n\n#[derive(Debug)]\npub struct HandshakeStatus"
  },
  {
    "path": "qconnection/Cargo.toml",
    "chars": 1461,
    "preview": "[package]\nname = \"qconnection\"\nversion = \"0.5.0\"\nedition.workspace = true\ndescription = \"Encapsulation of QUIC connectio"
  },
  {
    "path": "qconnection/src/builder.rs",
    "chars": 26840,
    "preview": "use std::{\n    net::SocketAddr,\n    sync::{Arc, atomic::AtomicBool},\n    time::Duration,\n};\n\nuse qbase::{\n    cid::{Conn"
  },
  {
    "path": "qconnection/src/events.rs",
    "chars": 2796,
    "preview": "use std::sync::Arc;\n\nuse qbase::{\n    self,\n    error::{AppError, QuicError},\n    frame::ConnectionCloseFrame,\n};\nuse qe"
  },
  {
    "path": "qconnection/src/handshake.rs",
    "chars": 2655,
    "preview": "use std::{ops::Deref, sync::Arc};\n\nuse qbase::{\n    error::Error,\n    frame::{\n        HandshakeDoneFrame,\n        io::{"
  },
  {
    "path": "qconnection/src/lib.rs",
    "chars": 23708,
    "preview": "pub mod builder;\npub mod events;\npub mod handshake;\npub mod path;\npub mod space;\npub mod state;\npub mod termination;\npub"
  },
  {
    "path": "qconnection/src/path/aa.rs",
    "chars": 5083,
    "preview": "use std::sync::atomic::{AtomicU8, AtomicUsize, Ordering};\n\nuse qbase::net::tx::{ArcSendWaker, Signals};\n\npub const DEFAU"
  },
  {
    "path": "qconnection/src/path/burst.rs",
    "chars": 21455,
    "preview": "use std::{\n    io,\n    ops::Deref,\n    sync::{Arc, atomic::Ordering::Acquire},\n};\n\nuse bytes::BufMut;\nuse derive_more::F"
  },
  {
    "path": "qconnection/src/path/drive.rs",
    "chars": 487,
    "preview": "use qcongestion::Transport;\nuse tokio::time::Duration;\n\nuse crate::{path::PathDeactivated, tls::ArcTlsHandshake};\n\nimpl "
  },
  {
    "path": "qconnection/src/path/error.rs",
    "chars": 817,
    "preview": "use derive_more::From;\nuse qbase::{error::Error as QuicError, time::TimeOut};\nuse qcongestion::TooManyPtos;\nuse qinterfa"
  },
  {
    "path": "qconnection/src/path/paths.rs",
    "chars": 4728,
    "preview": "use std::{\n    future::Future,\n    sync::{Arc, Mutex, Weak},\n    time::Duration,\n};\n\nuse dashmap::DashMap;\nuse derive_mo"
  },
  {
    "path": "qconnection/src/path/util.rs",
    "chars": 6506,
    "preview": "use std::{\n    pin::Pin,\n    sync::Mutex,\n    task::{Context, Poll},\n};\n\nuse bytes::BufMut;\nuse futures::StreamExt;\nuse "
  },
  {
    "path": "qconnection/src/path/validate.rs",
    "chars": 1709,
    "preview": "use std::{sync::atomic::Ordering, time::Duration};\n\nuse qbase::{frame::PathChallengeFrame, net::tx::Signals};\nuse qconge"
  },
  {
    "path": "qconnection/src/path.rs",
    "chars": 9824,
    "preview": "use std::{\n    io,\n    sync::{\n        Arc,\n        atomic::{AtomicBool, AtomicU16, Ordering},\n    },\n};\n\nuse qbase::{\n "
  },
  {
    "path": "qconnection/src/space/data.rs",
    "chars": 21007,
    "preview": "use std::sync::Arc;\n\nuse qbase::{\n    Epoch, GetEpoch,\n    error::{Error, QuicError},\n    frame::{\n        ConnectionClo"
  },
  {
    "path": "qconnection/src/space/handshake.rs",
    "chars": 10090,
    "preview": "use std::sync::Arc;\n\nuse qbase::{\n    Epoch, GetEpoch,\n    error::{Error, QuicError},\n    frame::{ConnectionCloseFrame, "
  },
  {
    "path": "qconnection/src/space/initial.rs",
    "chars": 11610,
    "preview": "use std::{ops::Deref, sync::Arc};\n\nuse qbase::{\n    Epoch, GetEpoch,\n    error::{Error, QuicError},\n    frame::{Connecti"
  },
  {
    "path": "qconnection/src/space.rs",
    "chars": 12021,
    "preview": "pub mod data;\npub mod handshake;\npub mod initial;\n\nuse std::{borrow::Cow, fmt::Debug, sync::Arc};\n\nuse bytes::Bytes;\nuse"
  },
  {
    "path": "qconnection/src/state.rs",
    "chars": 8179,
    "preview": "use std::{\n    future::Future,\n    sync::{\n        Arc,\n        atomic::{AtomicU8, Ordering},\n    },\n};\n\nuse qbase::{err"
  },
  {
    "path": "qconnection/src/termination.rs",
    "chars": 5086,
    "preview": "use std::{\n    io, mem,\n    sync::{\n        Arc, Mutex,\n        atomic::{AtomicUsize, Ordering},\n    },\n    time::Durati"
  },
  {
    "path": "qconnection/src/tls/agent.rs",
    "chars": 4727,
    "preview": "use std::sync::Arc;\n\nuse derive_more::AsRef;\nuse rustls::{\n    SignatureScheme,\n    pki_types::{CertificateDer, SubjectP"
  },
  {
    "path": "qconnection/src/tls/client_auth.rs",
    "chars": 8494,
    "preview": "use std::{\n    ops::{BitAnd, Deref},\n    sync::Arc,\n};\n\nuse tokio::sync::SetOnce;\n\nuse crate::prelude::{LocalAgent, Remo"
  },
  {
    "path": "qconnection/src/tls.rs",
    "chars": 23512,
    "preview": "mod agent;\nmod client_auth;\n\nuse std::{\n    future::Future,\n    sync::{Arc, Mutex, MutexGuard},\n    task::{Context, Poll"
  },
  {
    "path": "qconnection/src/traversal.rs",
    "chars": 7003,
    "preview": "use std::{io, net::SocketAddr};\n\nuse futures::{StreamExt, stream::FuturesUnordered};\nuse qbase::{\n    frame::{PunchHello"
  },
  {
    "path": "qconnection/src/tx.rs",
    "chars": 6590,
    "preview": "use bytes::BufMut;\nuse derive_more::Deref;\nuse qbase::{\n    frame::{ContainSpec, FrameFeature, Spec},\n    net::tx::Signa"
  },
  {
    "path": "qdatagram/Cargo.toml",
    "chars": 530,
    "preview": "[package]\nname = \"qdatagram\"\nversion = \"0.5.0\"\nedition.workspace = true\ndescription = \"Datagram transmission of dquic\"\nr"
  },
  {
    "path": "qdatagram/src/lib.rs",
    "chars": 2864,
    "preview": "mod reader;\nuse bytes::Bytes;\npub use reader::*;\nmod writer;\nuse std::io;\n\nuse qbase::{\n    error::Error,\n    frame::{Da"
  },
  {
    "path": "qdatagram/src/reader.rs",
    "chars": 10700,
    "preview": "use std::{\n    collections::VecDeque,\n    future::Future,\n    io,\n    pin::Pin,\n    sync::{Arc, Mutex},\n    task::{Conte"
  },
  {
    "path": "qdatagram/src/writer.rs",
    "chars": 15259,
    "preview": "use std::{\n    collections::VecDeque,\n    io,\n    ops::DerefMut,\n    sync::{Arc, Mutex},\n};\n\nuse bytes::{BufMut, Bytes};"
  },
  {
    "path": "qevent/Cargo.toml",
    "chars": 1028,
    "preview": "[package]\nname = \"qevent\"\nversion = \"0.5.0\"\nedition.workspace = true\ndescription = \"qlog implementation\"\nreadme.workspac"
  },
  {
    "path": "qevent/src/legacy/exporter.rs",
    "chars": 2904,
    "preview": "use std::io;\n\nuse tokio::{\n    io::{AsyncWrite, AsyncWriteExt},\n    sync::mpsc,\n};\n\nuse super::QlogFileSeq;\nuse crate::{"
  },
  {
    "path": "qevent/src/legacy/quic.rs",
    "chars": 36170,
    "preview": "use std::collections::HashMap;\n\nuse derive_builder::Builder;\nuse derive_more::{From, Into};\nuse serde::{Deserialize, Ser"
  },
  {
    "path": "qevent/src/legacy.rs",
    "chars": 11923,
    "preview": "pub mod exporter;\npub mod quic;\n\nuse std::collections::HashMap;\n\nuse derive_builder::Builder;\nuse derive_more::{From, In"
  },
  {
    "path": "qevent/src/lib.rs",
    "chars": 34657,
    "preview": "pub mod legacy;\npub mod loglevel;\npub mod quic;\npub mod telemetry;\n\n#[doc(hidden)]\npub mod macro_support;\nmod macros;\npu"
  },
  {
    "path": "qevent/src/loglevel.rs",
    "chars": 2596,
    "preview": "use derive_builder::Builder;\nuse serde::{Deserialize, Serialize};\n\n#[serde_with::skip_serializing_none]\n#[derive(Builder"
  },
  {
    "path": "qevent/src/macro_support.rs",
    "chars": 27,
    "preview": "pub use serde_json::Value;\n"
  },
  {
    "path": "qevent/src/macros.rs",
    "chars": 3049,
    "preview": "/// A macro to crate a qlog event struct from a set of fields.\n#[macro_export]\nmacro_rules! build {\n    ($struct:ty { $("
  },
  {
    "path": "qevent/src/packet.rs",
    "chars": 4845,
    "preview": "use bytes::{BufMut, buf::UninitSlice};\nuse derive_more::Deref;\nuse qbase::{\n    net::tx::Signals,\n    packet::{\n        "
  },
  {
    "path": "qevent/src/quic/connectivity.rs",
    "chars": 22671,
    "preview": "use std::net::SocketAddr;\n\nuse derive_builder::Builder;\nuse derive_more::From;\nuse qbase::{\n    error::{AppError, Error,"
  },
  {
    "path": "qevent/src/quic/recovery.rs",
    "chars": 15674,
    "preview": "use std::collections::HashMap;\n\nuse derive_builder::Builder;\nuse serde::{Deserialize, Serialize};\n\nuse super::{PacketHea"
  },
  {
    "path": "qevent/src/quic/security.rs",
    "chars": 4866,
    "preview": "use derive_builder::Builder;\nuse serde::{Deserialize, Serialize};\n\nuse super::KeyType;\nuse crate::HexString;\n\n/// The ke"
  },
  {
    "path": "qevent/src/quic/transport.rs",
    "chars": 54929,
    "preview": "use std::{collections::HashMap, time::Duration};\n\nuse derive_builder::Builder;\nuse derive_more::From;\nuse qbase::param::"
  },
  {
    "path": "qevent/src/quic.rs",
    "chars": 53343,
    "preview": "use std::{\n    collections::HashMap, fmt::Display, marker::PhantomData, net::SocketAddr, time::Duration,\n};\n\nuse bytes::"
  },
  {
    "path": "qevent/src/telemetry/filter.rs",
    "chars": 571,
    "preview": "#[inline]\n#[cfg(feature = \"telemetry\")]\npub fn event(scheme: &'static str) -> bool {\n    super::current_span::CURRENT_SP"
  },
  {
    "path": "qevent/src/telemetry/handy.rs",
    "chars": 6757,
    "preview": "use std::{\n    future::Future,\n    path::{Path, PathBuf},\n    sync::Arc,\n};\n\nuse tokio::{\n    io::{self, AsyncWrite, Asy"
  },
  {
    "path": "qevent/src/telemetry/macro_support.rs",
    "chars": 1613,
    "preview": "use serde::Serialize;\n\nuse super::*;\nuse crate::{BeSpecificEventData, EventBuilder};\n\n#[inline]\npub fn new_span(exporter"
  },
  {
    "path": "qevent/src/telemetry/macros.rs",
    "chars": 5188,
    "preview": "#[macro_export]\n#[cfg(feature = \"telemetry\")]\nmacro_rules! span {\n    () => {{\n        $crate::telemetry::Span::current("
  },
  {
    "path": "qevent/src/telemetry.rs",
    "chars": 6886,
    "preview": "pub(crate) mod filter;\npub mod handy;\n\n#[doc(hidden)]\npub mod macro_support;\nmod macros;\n\nuse std::{\n    collections::Ha"
  },
  {
    "path": "qinterface/Cargo.toml",
    "chars": 1181,
    "preview": "[package]\nname = \"qinterface\"\nversion = \"0.5.0\"\nedition.workspace = true\ndescription = \"dquic's network interface and IO"
  },
  {
    "path": "qinterface/examples/interface-monitor.rs",
    "chars": 389,
    "preview": "use qinterface::device::Devices;\n\n#[tokio::main(flavor = \"current_thread\")]\nasync fn main() {\n    let global = Devices::"
  },
  {
    "path": "qinterface/src/bind_uri.rs",
    "chars": 17433,
    "preview": "use std::{\n    borrow::Cow,\n    fmt::Display,\n    io,\n    net::{AddrParseError, IpAddr, SocketAddr},\n    str::FromStr,\n}"
  },
  {
    "path": "qinterface/src/component/alive.rs",
    "chars": 4907,
    "preview": "use std::{\n    fmt::Debug,\n    io,\n    net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},\n    pin::Pin,\n    sync::{Mutex, Mu"
  },
  {
    "path": "qinterface/src/component/location.rs",
    "chars": 7809,
    "preview": "use std::{\n    any::{Any, TypeId},\n    collections::{HashMap, hash_map},\n    fmt::Debug,\n    ops::Deref,\n    sync::{Arc,"
  }
]

// ... and 100 more files (download for full content)

About this extraction

This page contains the full source code of the genmeta/gm-quic GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 300 files (2.0 MB), approximately 548.7k tokens, and a symbol index with 4373 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!