Skip to content

Implement BEP 27 (private torrents)#1053

Open
guangtoutong wants to merge 1 commit into
anacrolix:masterfrom
guangtoutong:feat/bep27-private-torrent
Open

Implement BEP 27 (private torrents)#1053
guangtoutong wants to merge 1 commit into
anacrolix:masterfrom
guangtoutong:feat/bep27-private-torrent

Conversation

@guangtoutong
Copy link
Copy Markdown

Honors the `private=1` flag in torrent metainfo per BEP 27. Previously `metainfo.Info.Private` was parsed but never checked at runtime, so private trackers' workflow was silently leaking peers via DHT, PEX, and LSD.

What changed

Adds a single helper `Torrent.isPrivate()` and consults it at every existing decentralized-discovery gate:

Gate File Behavior for private
DHT announce loop `torrent.go:dhtAnnouncer` Skipped per iteration
PEX startup `pexconn.go:pexConnState.Init` PEX not enabled
LPD outbound announce `client.go:TorrentInfohashesAndPort` Excluded from list
LPD inbound peer add `client.go:OnLPDAnnouncement` Both targeted and fallback paths skip
Post-add LPD kick `client.go:AddTorrentOpt` `lpdPeers`/`lpdForce` skipped

Magnet edge case

`isPrivate()` returns false when info has not yet been loaded (e.g. a magnet still fetching metadata). The downstream loops re-check each iteration, so the moment metadata arrives the flag takes effect. This is the only safe behaviour — we physically cannot honour a private flag we don't yet have. In practice private trackers distribute `.torrent` files (not magnets) because of this race.

Tests

`bep27_private_test.go` covers the four meaningful states of the helper: no info, `Private==nil`, `Private==&false`, `Private==&true`.

Per-gate behaviour is exercised by the existing integration suite (`./test/...`), which still passes on every public-torrent path. `storage/possum` fails locally on Windows due to missing native `libpossum` — unrelated to this change.

Spec reference

If true, the client MUST publish its presence to get other peers ONLY via the trackers explicitly described in the metainfo file. If false or is not present, the client may obtain peer from other means, i.e. PEX peer exchange, DHT.

— BEP 27

Honors the `private=1` flag in torrent metainfo per BEP 27. Private
torrents must not be advertised on, or receive peers from, any
decentralized discovery mechanism — only the trackers explicitly
listed in the metainfo. Previously the field was parsed into
metainfo.Info.Private but never checked at runtime, so private
trackers' workflow was silently leaking peers via DHT/PEX/LSD.

This change adds a single helper, Torrent.isPrivate(), and consults
it at every existing discovery gate:

  torrent.go
    isPrivate() — returns true iff info is loaded and Private==true.
    Returns false when info is not yet loaded (magnet still fetching
    metadata). The downstream loops re-check each iteration so the
    flag takes effect as soon as metadata arrives.

  torrent.go: dhtAnnouncer
    Skips DHT announce when private. Re-checked per loop so a magnet
    that turns out to be private stops announcing immediately after
    info loads.

  pexconn.go: pexConnState.Init
    PEX is not enabled for private torrents — the connection still
    works, just doesn't share peer lists.

  client.go: TorrentInfohashesAndPort
    Excludes private torrents from the Local Peer Discovery (BEP 14)
    multicast announce.

  client.go: OnLPDAnnouncement
    Inbound LPD peers are not added to private torrents, including
    via the "add to all other torrents" fallback path.

  client.go: AddTorrentOpt
    Skips the post-add lpdPeers / lpdForce kick when the torrent is
    private.

bep27_private_test.go
  Covers the helper's behaviour for the four meaningful input states:
  no info, Private==nil, Private==&false, Private==&true. The
  per-gate behaviour is exercised by the existing integration tests
  (./test/...) which still pass on every public-torrent path.

All existing tests pass (storage/possum fails locally due to a
missing native libpossum on Windows — unrelated to this change).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants