Skip to content

Handle unsupported "paused" announces without closing the WebSocket - #1

Closed
jasminsehic wants to merge 1 commit into
Novage:mainfrom
jasminsehic:handle-paused-announce
Closed

jasminsehic wants to merge 1 commit into
Novage:mainfrom
jasminsehic:handle-paused-announce

Conversation

@jasminsehic

Copy link
Copy Markdown

Summary

Handle WebTorrent event: "paused" messages as an explicit unsupported-event response instead of a protocol parse error that closes the WebSocket.

The Rust parser currently treats paused as an unknown event. The server's protocol-error path closes the connection (code 1008) and disconnects its peers. This change returns an announce failure response while keeping the connection open and leaving tracker membership unchanged. Other unsupported announce events retain their existing behavior.

Why

The paused announce event has an established history in the BitTorrent ecosystem and is sent by WebTorrent-capable clients.

  • BEP 21 - Extension for partial seeds: Defines event=paused for partial seeds. BEP 21
  • libtorrent WebTorrent/WebSocket support: The WebTorrent support commit maps announce events, including paused, to WebSocket JSON messages.
  • WebTorrent's reference tracker: PR #411, merged on 1 June 2022 and shipped in v9.19.0, added handling for the paused client event. The reference implementation treats it as an update, falling back to a start if the peer is not already in the swarm.
  • Corresponding JavaScript tracker change: Novage/wt-tracker PR #98 handles paused without closing the connection.

This change is intentionally limited to connection-safe handling of paused. It does not implement BEP 21 partial-seed tracking or change swarm membership; the tracker returns an explicit unsupported-event response and preserves the connection.

Implementation

  • Parse paused before normal announce-field validation, so missing or invalid announce fields do not turn it into a protocol error.
  • Return {"action":"announce","failure reason":"unsupported announce event: paused"}.
  • Include info_hash only when the original JSON value is a string, preserving its raw token for the response; omit it when missing or non-string.
  • Carry the message through OwnedMessage and count the response separately as announce_error.
  • Do not consume the connection's initial announce-placement opportunity when paused is the first message.
  • Update docs/SPEC.md and CHANGELOG.md.

Tests

  • Parser tests cover paused, escaped event spelling, missing/non-string info_hash, and invalid peer_id.
  • Encoder tests verify the response, optional info_hash, response counters, and no tracker-state mutation.
  • A server integration test verifies that the failure response is followed by a successful valid announce on the same WebSocket connection.

@mrlika

mrlika commented Oct 12, 2026

Copy link
Copy Markdown
Member

Thanks for the report and the detailed references — they were very helpful. We fixed this on main with the reference tracker's semantics instead of a failure reply: BEP 21 partial seeds send event=paused on every announce, so a failure reply would keep them out of the swarm permanently. bittorrent-tracker (PR #411) treats paused as an update (a start for an unknown peer), so paused is now handled as a periodic announce: the peer is added or refreshed, stays incomplete, and its offers are forwarded.

wt-tracker: Novage/wt-tracker@5fdad75 · wt-tracker-rust: 334badd. Closing this in favour of those commits.

@mrlika mrlika closed this Oct 12, 2026
@jasminsehic

Copy link
Copy Markdown
Author

Nice one, thank you

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