gates / gates (push) Successful in 13m1s
Spike: per-app normal levels on three boxes (19-31 days), the off-site push as a line measure (a lower bound), qBittorrent/Transmission/Plex explainers measured on 9202, a tc ceiling measured (not built). Live on 9202 with 0.342.0-rc.1: limit set; real seed explained; CPU burner and the hidden flood alarmed once each and cleared once; the household's limit left alone. Teardown: apps removed, 9202 back on 0.341.0, receiver 9471 destroyed.
22 lines
1.5 KiB
Python
22 lines
1.5 KiB
Python
# Minimal BitTorrent HTTP tracker for a closed scratch test (no internet). Compact peer lists.
|
|
import http.server, urllib.parse, socket, struct, time
|
|
peers = {} # info_hash -> {(ip,port): last_seen}
|
|
def benc(o):
|
|
if isinstance(o, int): return b"i%de" % o
|
|
if isinstance(o, bytes): return b"%d:%s" % (len(o), o)
|
|
if isinstance(o, str): return benc(o.encode())
|
|
if isinstance(o, dict): return b"d" + b"".join(benc(k) + benc(v) for k, v in sorted(o.items())) + b"e"
|
|
class H(http.server.BaseHTTPRequestHandler):
|
|
def do_GET(self):
|
|
q = urllib.parse.parse_qs(urllib.parse.urlsplit(self.path).query.encode('latin-1').decode('latin-1'), encoding='latin-1')
|
|
ih = q.get('info_hash', [''])[0]; port = int(q.get('port', ['0'])[0]); ip = self.client_address[0]
|
|
d = peers.setdefault(ih, {}); now = time.time()
|
|
if q.get('event', [''])[0] == 'stopped': d.pop((ip, port), None)
|
|
else: d[(ip, port)] = now
|
|
lst = b"".join(socket.inet_aton(i) + struct.pack(">H", p) for (i, p), t in d.items() if now - t < 600 and (i, p) != (ip, port))
|
|
body = benc({"interval": 30, "peers": lst})
|
|
print(time.strftime('%H:%M:%S'), 'announce', ip, port, q.get('event', [''])[0], 'peers', len(lst) // 6, flush=True)
|
|
self.send_response(200); self.send_header('Content-Length', str(len(body))); self.end_headers(); self.wfile.write(body)
|
|
def log_message(self, *a): pass
|
|
http.server.ThreadingHTTPServer(('0.0.0.0', 6969), H).serve_forever()
|