netsleuth/pyproject.toml
Andrew Pimenov 66dcd6f5bc measure QUIC/HTTP3 handshake RTT to catch UDP/443 blocking (--quic)
The only feature in this batch adding a real dependency, approved up front
and landed the same way tcptrace/ndt7 already do: an optional extra
(uv sync --extra quic), imported lazily inside measure_quic() so a missing
install degrades to a clear skip warning instead of a crash.

Verified the actually-installed aioquic 1.3.0 API directly rather than
assuming. connect() takes local_port but no local_host/source-address
parameter at all, so --quic structurally cannot honor --interface -
_quic_section() says so explicitly rather than silently measuring the
OS-default path under a report claiming a forced adapter. Its context
manager doesn't yield until the handshake finishes, so unlike the TLS RTT
probe's two-connection subtraction trick, handshake time here is timed
directly. HandshakeCompleted's fields matched what was expected; dropped
a planned quic_version field since aioquic has no clean public API for
it rather than reach into a private attribute.

quic_verdict(quic_ok, tcp_ok) is the actual payoff: QUIC failing while
plain TCP to the same host succeeds means the network specifically
drops or throttles UDP/443, silently degrading Chrome/YouTube's HTTP/3
preference in a way no TCP-based diagnostic would ever catch. Both
failing is ordinary unreachability already covered elsewhere, so it
stays silent rather than duplicating that finding.

Opt-in --quic, excluded from --full - an optionally-installed extra must
never become a silent requirement. Added the quic extra to the release
workflow's wheel-install verification.

Live-tested against real cloudflare.com/google.com: real handshakes,
ALPN h3 negotiated, correct end-to-end timing.

This completes the 16-feature extension batch from
plans/zesty-zooming-wilkinson.md (gitignored, local planning doc).
2026-08-13 01:56:21 +03:00

47 lines
1.1 KiB
TOML

[project]
name = "netsleuth"
version = "0.1.0"
description = "Cross-platform CLI for deep network diagnostics: ISP/VPN/ASN identity, latency, path and bandwidth"
readme = "README.md"
license = "PolyForm-Noncommercial-1.0.0"
requires-python = ">=3.14"
authors = [{ name = "netsleuth contributors" }]
keywords = ["network", "diagnostics", "traceroute", "bgp", "vpn", "speedtest"]
dependencies = [
"typer>=0.12",
"rich>=13.7",
"httpx[http2]>=0.28",
"pydantic>=2.7",
"pydantic-settings>=2.3",
"pyyaml>=6.0",
"dnspython>=2.6",
"psutil>=5.9",
"icmplib>=3.0",
]
[project.optional-dependencies]
tcptrace = ["scapy>=2.5"]
ndt7 = ["websockets>=12"]
quic = ["aioquic>=1.2"]
[project.scripts]
netsleuth = "netsleuth.cli:main"
[dependency-groups]
dev = [
"pytest>=8",
"pytest-asyncio>=0.23",
"pytest-httpx>=0.30",
]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["src/netsleuth"]
[tool.pytest.ini_options]
testpaths = ["tests"]
asyncio_mode = "auto"
filterwarnings = ["error::DeprecationWarning:netsleuth.*"]