1. Problem Overview
When DataChannel is enabled, libpeer's local SDP always advertises a=max-message-size:262144, but the implementation neither stores the value of this attribute from the remote SDP nor applies the 64 KiB default required by RFC 8841 when the attribute is absent. The send API passes the caller-supplied full len directly to SCTP. As a result, when the remote side declares a smaller non-zero limit, or omits the attribute entirely, and the message exceeds the corresponding bound, libpeer still transmits an oversized SCTP user message.
2. Specification Requirements
RFC 8841 Section 6.1 states that an SCTP endpoint MUST NOT send a SCTP user message whose size is larger than the maximum size indicated by the peer. If the SDP max-message-size attribute is absent, the default value is 64 KiB. The sending function must therefore enforce this size limit before handing the complete user message to SCTP.
“An SCTP endpoint MUST NOT send a SCTP user message with a message size that is larger than the maximum size indicated by the peer, as it cannot be assumed that the peer would accept such a message.”
“If the SDP "max-message-size" attribute is not present, the default value is 64K.”
3. Code Analysis
The remote SDP parsing path never stores max-message-size, and the user-send path only checks whether the SCTP association is connected before passing the full length unchanged to usrsctp.
/* src/peer_connection.c:381-409 — peer_connection_set_remote_description */
while ((line = strstr(start, "\r\n"))) {
...
if (strstr(buf, "a=setup:passive")) {
role = DTLS_SRTP_ROLE_CLIENT;
}
if (strstr(buf, "a=fingerprint")) {
strncpy(pc->dtls_srtp.remote_fingerprint, buf + 22, DTLS_SRTP_FINGERPRINT_LENGTH);
}
...
start = line + 2;
}
/* src/peer_connection.c:220-228 — peer_connection_datachannel_send_sid */
int peer_connection_datachannel_send_sid(PeerConnection* pc, char* message,
size_t len, uint16_t sid) {
if (!sctp_is_connected(&pc->sctp)) {
LOGE("sctp not connected");
return -1;
}
if (pc->config.datachannel == DATA_CHANNEL_STRING)
return sctp_outgoing_data(&pc->sctp, message, len, PPID_STRING, sid);
else
return sctp_outgoing_data(&pc->sctp, message, len, PPID_BINARY, sid);
}
/* src/sctp.c:96-111 — sctp_outgoing_data, CONFIG_USE_USRSCTP */
int sctp_outgoing_data(Sctp* sctp, char* buf, size_t len,
SctpDataPpid ppid, uint16_t sid) {
int res;
struct sctp_sendv_spa spa = {0};
spa.sendv_flags = SCTP_SEND_SNDINFO_VALID;
spa.sendv_sndinfo.snd_sid = sid;
spa.sendv_sndinfo.snd_flags = SCTP_EOR;
spa.sendv_sndinfo.snd_ppid = htonl(ppid);
res = usrsctp_sendv(sctp->sock, buf, len, NULL, 0, &spa,
sizeof(spa), SCTP_SENDV_SPA, 0);
return res;
}
Call path:
peer_connection_set_remote_description (does not store the remote max-message-size)
-> peer_connection_datachannel_send_sid (only checks connected)
-> sctp_outgoing_data (passes the full len unchanged)
-> usrsctp_sendv
4. Impact Analysis
This is a functional bug. When the peer declares a smaller limit or falls back to the 64 KiB default, an oversized message may be rejected by the peer or fail to be reassembled, so DataChannel sending fails. The sender does not return a "message exceeds the negotiated limit" error at the API boundary, so the application may keep generating messages the peer cannot accept. This path has no branch that truncates or rejects based on the negotiated value, and underlying SCTP fragmentation cannot change the RFC size limit that applies to the complete user message.
1. Problem Overview
When DataChannel is enabled, libpeer's local SDP always advertises
a=max-message-size:262144, but the implementation neither stores the value of this attribute from the remote SDP nor applies the 64 KiB default required by RFC 8841 when the attribute is absent. The send API passes the caller-supplied fulllendirectly to SCTP. As a result, when the remote side declares a smaller non-zero limit, or omits the attribute entirely, and the message exceeds the corresponding bound, libpeer still transmits an oversized SCTP user message.2. Specification Requirements
RFC 8841 Section 6.1 states that an SCTP endpoint MUST NOT send a SCTP user message whose size is larger than the maximum size indicated by the peer. If the SDP
max-message-sizeattribute is absent, the default value is 64 KiB. The sending function must therefore enforce this size limit before handing the complete user message to SCTP.3. Code Analysis
The remote SDP parsing path never stores
max-message-size, and the user-send path only checks whether the SCTP association is connected before passing the full length unchanged to usrsctp.Call path:
4. Impact Analysis
This is a functional bug. When the peer declares a smaller limit or falls back to the 64 KiB default, an oversized message may be rejected by the peer or fail to be reassembled, so DataChannel sending fails. The sender does not return a "message exceeds the negotiated limit" error at the API boundary, so the application may keep generating messages the peer cannot accept. This path has no branch that truncates or rejects based on the negotiated value, and underlying SCTP fragmentation cannot change the RFC size limit that applies to the complete user message.