Skip to content

fix(registrar): ensure onDisconnect is not called when onConnect was skipped for limited connections#3375

Closed
paschal533 wants to merge 1 commit intolibp2p:mainfrom
paschal533:fix/sdp
Closed

fix(registrar): ensure onDisconnect is not called when onConnect was skipped for limited connections#3375
paschal533 wants to merge 1 commit intolibp2p:mainfrom
paschal533:fix/sdp

Conversation

@paschal533
Copy link

What

Fixed an inconsistency in topology notification where onDisconnect could fire for connections that never triggered onConnect.

Problem

When a topology has notifyOnLimitedConnection unset (default false), connections with limits (like circuit relay connections used for WebRTC SDP signaling) correctly skip onConnect. However, when these connections close, onDisconnect was still being called.

The root cause was a logic error in _onDisconnect:

// Before: when topology.filter is undefined, this evaluates to
// undefined === false → false, so the early return never triggers
if (topology.filter?.has(remotePeer) === false) { return }

// After: explicitly checks filter exists before checking membership  
if (topology.filter != null && topology.filter.has(remotePeer) !== true) { return }

This caused spurious disconnect events in protocol handlers like GossipSub when WebRTC browser-to-browser connections use temporary relay connections for SDP exchange.

Testing

  • Extended existing limited connection test to verify disconnect behavior
  • Added test for notifyOnLimitedConnection: true covering both connect and disconnect
  • Added test for filter-based topology disconnect logic

Fixes #2647
Fixes #2369

Fixes the inconsistency where topologies with notifyOnLimitedConnection: false
would not receive onConnect events for limited connections, but would still
receive onDisconnect events when those connections closed.

This issue was particularly problematic for WebRTC browser-to-browser connections,
where a temporary circuit relay connection is established just for SDP signaling.
When this connection closes, protocols like GossipSub would receive spurious
disconnect events even though they never received a connect event.

The root cause was in the _onDisconnect handler's filter check:
  if (topology.filter?.has(remotePeer) === false)

When topology.filter is undefined, this evaluates to false, allowing onDisconnect
to be called even when the peer was never added to the filter during onConnect.

Fixed by changing the condition to:
  if (topology.filter != null && topology.filter.has(remotePeer) !== true)

Now the logic is:
- If a topology has a filter AND the peer is not in it, skip onDisconnect
- If a topology has no filter, call onDisconnect (can't track individual peers)

Added comprehensive tests to verify:
1. Limited connections don't trigger onConnect or onDisconnect by default
2. Limited connections DO trigger both when notifyOnLimitedConnection: true
3. Topologies with filters only receive onDisconnect for peers in the filter

Fixes libp2p#2647
Fixes libp2p#2369

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@paschal533 paschal533 requested a review from a team as a code owner February 5, 2026 14:04
@paschal533 paschal533 closed this Feb 5, 2026
@paschal533 paschal533 deleted the fix/sdp branch February 5, 2026 14:06
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.

WebRTC SDP handshake connection transient? notifyOnTransient also ignore disconnection events?

1 participant