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>
This commit is contained in:
commit
d8208685a2
55 changed files with 9989 additions and 0 deletions
84
interop/seed_libtorrent.py
Normal file
84
interop/seed_libtorrent.py
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import signal
|
||||
import time
|
||||
|
||||
import libtorrent as lt
|
||||
|
||||
from common import touch_ready
|
||||
|
||||
|
||||
def settings_for(mode: str, port: int) -> dict:
|
||||
tcp = mode in ("plain", "mse")
|
||||
utp = mode in ("utp", "utp-mse")
|
||||
encrypted = mode in ("mse", "utp-mse")
|
||||
settings = {
|
||||
"listen_interfaces": f"0.0.0.0:{port}",
|
||||
"enable_dht": False,
|
||||
"enable_lsd": False,
|
||||
"enable_upnp": False,
|
||||
"enable_natpmp": False,
|
||||
"enable_outgoing_tcp": tcp,
|
||||
"enable_incoming_tcp": tcp,
|
||||
"enable_outgoing_utp": utp,
|
||||
"enable_incoming_utp": utp,
|
||||
"announce_to_all_trackers": False,
|
||||
"announce_to_all_tiers": False,
|
||||
"alert_mask": 0,
|
||||
}
|
||||
if encrypted:
|
||||
settings.update({
|
||||
"in_enc_policy": int(lt.enc_policy.forced),
|
||||
"out_enc_policy": int(lt.enc_policy.forced),
|
||||
"allowed_enc_level": int(lt.enc_level.rc4),
|
||||
"prefer_rc4": True,
|
||||
})
|
||||
else:
|
||||
settings.update({
|
||||
"in_enc_policy": int(lt.enc_policy.disabled),
|
||||
"out_enc_policy": int(lt.enc_policy.disabled),
|
||||
})
|
||||
return settings
|
||||
|
||||
|
||||
def main() -> int:
|
||||
ap = argparse.ArgumentParser(description="Seed a fixture with libtorrent.")
|
||||
ap.add_argument("--torrent", required=True)
|
||||
ap.add_argument("--data", required=True)
|
||||
ap.add_argument("--port", required=True, type=int)
|
||||
ap.add_argument("--mode", required=True, choices=["plain", "mse", "utp", "utp-mse"])
|
||||
args = ap.parse_args()
|
||||
|
||||
stop = False
|
||||
|
||||
def _stop(signum, frame):
|
||||
nonlocal stop
|
||||
stop = True
|
||||
|
||||
signal.signal(signal.SIGTERM, _stop)
|
||||
signal.signal(signal.SIGINT, _stop)
|
||||
|
||||
ses = lt.session(settings_for(args.mode, args.port))
|
||||
h = ses.add_torrent({
|
||||
"ti": lt.torrent_info(args.torrent),
|
||||
"save_path": args.data,
|
||||
"flags": lt.torrent_flags.seed_mode,
|
||||
})
|
||||
deadline = time.time() + 60
|
||||
while time.time() < deadline and not h.status().is_seeding:
|
||||
time.sleep(0.25)
|
||||
if not h.status().is_seeding:
|
||||
raise TimeoutError(f"libtorrent {args.mode} did not enter seed mode")
|
||||
touch_ready()
|
||||
print(f"libtorrent {args.mode} seeding on {args.port}", flush=True)
|
||||
while not stop:
|
||||
time.sleep(1)
|
||||
ses.remove_torrent(h)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue