Skip to content

fix(peer_connection): implement SCTP/DataChannel close on PeerConnection shutdown#76

Open
nightness wants to merge 3 commits into
webrtc-rs:masterfrom
Brainwires:fix/peerconnection-close
Open

fix(peer_connection): implement SCTP/DataChannel close on PeerConnection shutdown#76
nightness wants to merge 3 commits into
webrtc-rs:masterfrom
Brainwires:fix/peerconnection-close

Conversation

@nightness
Copy link
Copy Markdown

@nightness nightness commented Apr 1, 2026

Summary

  • SctpHandler::close(): was a no-op (Ok(())). Now iterates all SCTP associations, calls assoc.close(AssociationError::LocallyClosed) on each, clears the associations map, and drops the endpoint.
  • DataChannelHandler::close(): was a no-op. Now calls dc.close() on each RTCDataChannelInternal (transitions state to Closed, closes the underlying SCTP stream). Does not clear the data_channels map to avoid panics in public RTCDataChannel accessors that unwrap() map lookups.
  • handler/mod.rs: removes the stale ~40-line async-era /* TODO: */ comment block that used .await syntax incompatible with this synchronous sans-IO handler. Replaced with a concise comment mapping each W3C close step to the handler that implements it.
  • Close order: handlers are now closed in reverse order (Endpoint→Interceptor→SRTP→DataChannel→SCTP→DTLS→ICE→Demuxer) so higher-level protocols shut down before their transport dependencies. Errors are collected rather than short-circuiting.

ICE (IceHandler::close()agent.close()), DTLS (DtlsHandler::close()dtls_transport.stop()), and interceptor (InterceptorHandler::close()interceptor.close()) were already correctly implemented.

Test plan

  • cargo test -p rtc — all 246 tests pass (167 unit + 79 doc)
  • Unit tests for close: state transitions, idempotency, data channel map preservation, post-close accessor safety
  • Integration: open a DataChannel, close the PeerConnection, verify the channel transitions to Closed state and no SCTP timers remain running

🤖 Generated with Claude Code

@nightness nightness force-pushed the fix/peerconnection-close branch from d7d5a8b to 58c9cf4 Compare April 1, 2026 18:43
@rainliu rainliu requested a review from Copilot April 4, 2026 14:07
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Implements proper shutdown behavior for SCTP/DataChannels when a PeerConnection closes, and updates handler close documentation to match the current synchronous design.

Changes:

  • Implemented SctpHandler::close() to close all SCTP associations, clear transport state, and drop the SCTP endpoint.
  • Implemented DataChannelHandler::close() to close all RTCDataChannelInternal instances and clear the channel map.
  • Replaced an outdated async-era /* TODO */ block with a concise comment describing which handlers implement W3C close steps.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
rtc/src/peer_connection/handler/sctp.rs Adds real SCTP shutdown by closing associations and dropping the endpoint, aggregating close errors.
rtc/src/peer_connection/handler/datachannel.rs Adds DataChannel shutdown that closes all channels and aggregates close errors.
rtc/src/peer_connection/handler/mod.rs Replaces stale async TODO with a brief mapping from W3C close steps to handler close() methods.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread rtc/src/peer_connection/handler/sctp.rs Outdated
Comment thread rtc/src/peer_connection/handler/mod.rs Outdated
Comment thread rtc/src/peer_connection/handler/sctp.rs Outdated
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 4, 2026

Codecov Report

❌ Patch coverage is 87.50000% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.17%. Comparing base (9feb4a3) to head (58c9cf4).

Files with missing lines Patch % Lines
rtc/src/peer_connection/handler/datachannel.rs 85.71% 1 Missing ⚠️
rtc/src/peer_connection/handler/sctp.rs 88.88% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##           master      #76   +/-   ##
=======================================
  Coverage   71.17%   71.17%           
=======================================
  Files         442      442           
  Lines       67330    67344   +14     
=======================================
+ Hits        47922    47934   +12     
- Misses      19408    19410    +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread rtc/src/peer_connection/handler/mod.rs Outdated
Comment thread rtc/src/peer_connection/handler/mod.rs Outdated
Comment thread rtc/src/peer_connection/handler/datachannel.rs Outdated
nightness added a commit to Brainwires/webrtc-rs-rtc that referenced this pull request Apr 8, 2026
Address Copilot review comments on PR webrtc-rs#76:
- Close handlers in reverse order (Endpoint->DataChannel->SCTP->DTLS->ICE->Demuxer)
  so higher-level protocols shut down before their transport dependencies.
- Collect all close errors instead of short-circuiting on the first failure,
  ensuring every handler gets a chance to clean up.
- Remove data_channels.clear() from DataChannelHandler::close() to prevent
  panics in public RTCDataChannel methods (label(), ready_state(), etc.)
  that unwrap() map lookups.
- Update comment to accurately describe reverse shutdown order.
- Add 4 unit tests covering close state transitions, idempotency,
  data channel map preservation, and post-close accessor safety.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
nightness and others added 3 commits April 10, 2026 00:15
…ion shutdown

SctpHandler::close() and DataChannelHandler::close() both returned Ok(()) without
actually closing anything. On PeerConnection close, SCTP associations were left in
a running state and data channels were never transitioned to Closed.

- SctpHandler::close(): close all SCTP associations with LocallyClosed reason,
  then clear the associations map and drop the endpoint.
- DataChannelHandler::close(): close each RTCDataChannelInternal instance
  (sets ready_state → Closed, closes underlying data channel stream), then
  clear the data channels map.
- handler/mod.rs: remove stale async-era TODO comment block that cannot compile
  in this synchronous sans-IO handler; replace with a comment documenting which
  handler handles which W3C close step.

ICE, DTLS, and interceptor close were already correctly implemented in their
respective handlers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Use values_mut() instead of iter_mut() to avoid unused key
- Fix comment: "drop the endpoint" instead of "drain the endpoint"
- Update W3C close steps comment to avoid misleading step range reference

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Address Copilot review comments on PR webrtc-rs#76:
- Close handlers in reverse order (Endpoint->DataChannel->SCTP->DTLS->ICE->Demuxer)
  so higher-level protocols shut down before their transport dependencies.
- Collect all close errors instead of short-circuiting on the first failure,
  ensuring every handler gets a chance to clean up.
- Remove data_channels.clear() from DataChannelHandler::close() to prevent
  panics in public RTCDataChannel methods (label(), ready_state(), etc.)
  that unwrap() map lookups.
- Update comment to accurately describe reverse shutdown order.
- Add 4 unit tests covering close state transitions, idempotency,
  data channel map preservation, and post-close accessor safety.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@nightness nightness force-pushed the fix/peerconnection-close branch from 4160151 to bf36bbe Compare April 10, 2026 05:16
@nightness
Copy link
Copy Markdown
Author

Rebased onto upstream/master so this PR contains only its own changes. Previous branch structure caused merge conflicts when PRs were merged in sequence. Each PR is now independently mergeable.

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