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>
84 lines
2.4 KiB
Python
84 lines
2.4 KiB
Python
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())
|
|
|