Naut-Peer/interop
ookami125 d8208685a2 Initial commit: multi-peer torrent download engine
Reactor/loop-pool engine with TCP/µTP/MSE transports, per-connection
pipelining, priority-driven piece selection with endgame, and the Python
FFI test harness.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 23:12:32 -04:00
..
clients.json Initial commit: multi-peer torrent download engine 2026-06-21 23:12:32 -04:00
common.py Initial commit: multi-peer torrent download engine 2026-06-21 23:12:32 -04:00
docker-compose.yml Initial commit: multi-peer torrent download engine 2026-06-21 23:12:32 -04:00
Dockerfile Initial commit: multi-peer torrent download engine 2026-06-21 23:12:32 -04:00
make_fixture.py Initial commit: multi-peer torrent download engine 2026-06-21 23:12:32 -04:00
README.md Initial commit: multi-peer torrent download engine 2026-06-21 23:12:32 -04:00
run_matrix.py Initial commit: multi-peer torrent download engine 2026-06-21 23:12:32 -04:00
seed_aria2.py Initial commit: multi-peer torrent download engine 2026-06-21 23:12:32 -04:00
seed_deluge.py Initial commit: multi-peer torrent download engine 2026-06-21 23:12:32 -04:00
seed_libtorrent.py Initial commit: multi-peer torrent download engine 2026-06-21 23:12:32 -04:00
seed_qbittorrent.py Initial commit: multi-peer torrent download engine 2026-06-21 23:12:32 -04:00
seed_rtorrent.py Initial commit: multi-peer torrent download engine 2026-06-21 23:12:32 -04:00
seed_transmission.py Initial commit: multi-peer torrent download engine 2026-06-21 23:12:32 -04:00

Offline Client Interop

This harness starts several seed-only BitTorrent clients on a Docker Compose network with internal: true, generates one private test torrent, mounts the same data into every seeder, and drives this engine against each client independently.

It is meant to catch interoperability failures: bad handshakes, encryption/uTP negotiation mistakes, malformed requests, or behavior that makes common clients reject us. It is not a public-swarm or tracker test.

Clients

Default matrix:

  • libtorrent-plain-tcp
  • libtorrent-mse-tcp with RC4 required
  • libtorrent-utp
  • libtorrent-utp-mse
  • transmission-tcp
  • transmission-utp
  • transmission-mse-tcp with encryption required
  • aria2-tcp
  • qbittorrent-tcp
  • deluge-tcp
  • rtorrent-tcp

All clients run with DHT, PEX, local peer discovery, UPnP, and NAT-PMP disabled. The fixture torrent includes the deterministic dummy announce URL http://fixture:9/announce because rTorrent rejects trackerless torrents, but the runner still injects peers directly. The Compose network is internal-only, so containers cannot route to the internet during the test run.

Run

From the repository root:

docker compose -f interop/docker-compose.yml up --build \
  --abort-on-container-exit --exit-code-from runner

Useful overrides:

FIXTURE_SIZE=128M TEST_TIMEOUT=180 \
docker compose -f interop/docker-compose.yml up --build \
  --abort-on-container-exit --exit-code-from runner

Results are written to interop/results/results.json.

Clean generated containers, networks, and the fixture volume:

docker compose -f interop/docker-compose.yml down -v

Run One Client

The runner supports --only, but Compose still starts all default dependencies. For focused debugging, run a shell after the stack is up:

docker compose -f interop/docker-compose.yml run --rm runner \
  python3 /work/interop/run_matrix.py \
  --fixture /fixture \
  --clients /work/interop/clients.json \
  --results /results/one.json \
  --only transmission-tcp

Adding Clients

Add a seeder service to docker-compose.yml, disable all discovery/tracker/NAT features for that client, expose it only on torrent_lab, then add an entry to clients.json:

{
  "name": "new-client-tcp",
  "host": "seed-new-client",
  "port": 6900,
  "utp": 0,
  "encryption": 0,
  "fallback": 0
}

The engine currently needs a numeric IP, so the runner resolves the Compose DNS name to IPv4 before calling engine_add_peer.