Skip to content

fix(datachannel): send DataChannelOpen for pre-negotiated channels (closes #61)#70

Open
nightness wants to merge 1 commit intowebrtc-rs:masterfrom
Brainwires:fix/negotiated-datachannel
Open

fix(datachannel): send DataChannelOpen for pre-negotiated channels (closes #61)#70
nightness wants to merge 1 commit intowebrtc-rs:masterfrom
Brainwires:fix/negotiated-datachannel

Conversation

@nightness
Copy link
Copy Markdown

Summary

Fixes #61 — negotiated DataChannels open but cannot send messages.

Root cause: DataChannel::dial() skipped the DataChannelOpen DCEP message when config.negotiated == true. The SctpHandler only calls conn.open_stream() when processing a DataChannelOpen write, so no stream entry was ever created in the SCTP association. Every subsequent write failed with "Stream not existed".

Fix:

  • Always queue DataChannelOpen in dial(), for both negotiated and non-negotiated channels. The DCEP exchange registers the SCTP stream on both sides.
  • Handle ErrStreamAlreadyExist gracefully in the DataChannelOpen write path: when both pre-negotiated peers race to send DataChannelOpen simultaneously, the remote's packet may auto-create the stream via get_or_create_stream before the local outbound write is processed. Treat that as non-fatal and continue to set reliability parameters.

Test plan

  • cargo test -p rtc-datachannel passes
  • cargo test -p rtc passes
  • Manual: create a negotiated DataChannel (negotiated: Some(5)) on both peers — both sides can exchange messages after connection

🤖 Generated with Claude Code

Fixes webrtc-rs#61 — negotiated DataChannels could open but not send.

Root cause: DataChannel::dial() skipped queuing the DataChannelOpen DCEP
message for pre-negotiated channels (negotiated=true).  The SctpHandler
calls conn.open_stream() only when it processes a DataChannelOpen write,
so no stream was ever registered in the SCTP association.  Any subsequent
write failed with "Stream not existed".

Fix: always queue DataChannelOpen in dial(), for both negotiated and
non-negotiated channels.  The DCEP exchange opens the SCTP stream on
both sides.  Also handle ErrStreamAlreadyExist in the DataChannelOpen
write path: when both pre-negotiated peers race to send DataChannelOpen
simultaneously the remote's message may auto-create the stream first
via get_or_create_stream; treat that as non-fatal.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@nightness nightness force-pushed the fix/negotiated-datachannel branch from 09db64c to 1dea4fa Compare April 1, 2026 18:43
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.

Can't send message on negotiated DataChannel

1 participant