Skip to content

Conversation

@lucamuscat
Copy link
Contributor

@lucamuscat lucamuscat commented Aug 25, 2025

Currently, webrtc-rs does not react to the max-message-size attribute that may be attached to an SDP.

RFC8841 introduces the max-message-size SDP attribute:

The attribute can be associated with an "m=" line to indicate the maximum SCTP user message size (indicated in bytes) that an SCTP endpoint is willing to receive on the SCTP association associated with the "m=" line. Different attribute values can be used in each direction Source.

Browsers such as chrome typically advertise a max message size of 256KiB. Some user agents may also request a max-message-size smaller than the default 64KiB.

…ize is fed to the underlying association during the call to `start_sctp`
…`, as the only consumer of this method expects `u32`
…annel's config

Given that we are no longer fixed to the 64KB max size for message
sizes, the user needs a way to know the actual max message size a
datachannel may send before returning an error. This information is
particularly useful for applications where large messages are chunked
and framed in the application itself.
pub struct Association {
name: String,
state: Arc<AtomicU8>,
// TODO: Convert into `u32`, as there is no reason why the `max_message_size` should need to be
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am trying to keep refactors to the minimum in order to keep this PR as small as possible. If you do agree with this comment, I can tackle it in another PR, otherwise, I will remove said comment.

}

#[derive(Clone)]
pub enum SctpMaxMessageSize {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am personally not a huge fan of how the crate makes use of 0 as a sentinel value for some configuration being unset, so I decided to make use of an enum to give the user a clear distiction between having a bounded SctpMaxMessageSize, or an unbounded one (which is typically represented as a zero in this code base).

}

#[tokio::test]
async fn test_given_remote_max_message_size_is_none_when_data_channel_can_send_max_message_size_respected_on_send(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I like using the given, when, then naming pattern for certain tests. If you're not a fan of this, feel free to suggest alternative test names.

}

#[tokio::test]
async fn test_given_remote_max_message_size_is_none_when_data_channel_can_send_max_message_size_respected_on_send(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The following tests whether the max-message-size attribute, or the sctp_max_message_size_can_send attribute in the SettingsEngine is actually respected (in an end to end manner).

if let Some(local_port) = get_application_media_section_sctp_port(parsed_local)
{
self.start_sctp(local_port, remote_port).await;
// TODO: Reuse the MediaDescription retrieved when looking for the message size.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

A small nitpick of the code from my end, if you agree with the proposal, which is retrieving the MediaDescription once, and reusing it, I can implement this in another PR.

// so we need a dedicated field
is_started: AtomicBool,

// max_message_size represents the maximum size of data that can be passed to
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is not actually use anywhere, and cannot be properly initialized since the true max-message-size is only known once you receive the other peer's SDP.

}

fn calc_message_size(remote_max_message_size: usize, can_send_size: usize) -> usize {
fn calc_message_size(remote_max_message_size: u32, can_send_size: u32) -> u32 {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I decided to use u32 instead of usize here, since the method is only called by the code added in this PR. It feels pretty pointless to convert all u32s into usizes and then convert the resulting usize back into a u32.

/// have_data_channel return MediaDescription with MediaName equal application
pub(crate) fn have_data_channel(
desc: &session_description::RTCSessionDescription,
) -> Option<&MediaDescription> {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've rewritten this function in particular to use get_application_media, but I did not refactor the other functions in this file which could also make use of get_application_media in order to keep this PR to a minimum.

If you agree with the refactor, I can do it in another PR.

@lucamuscat
Copy link
Contributor Author

I'm also not sure what to do with RTCSctpTransport, as it is only ever used in examples. Let me know if and how you want me to refactor RTCSctpTransport::get_capabilities

@lucamuscat
Copy link
Contributor Author

Hi @rainliu ,

I would appreciate if you could take a look at the PR 😁

@rainliu rainliu merged commit 536ea96 into webrtc-rs:master Sep 4, 2025
4 of 5 checks passed
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