Skip to content

generate_matched_sdp drops rejected m-lines from answer (RFC 8829 §5.3.1 violation) #66

@nightness

Description

@nightness

Summary

In rtc/src/peer_connection/internal.rs, generate_matched_sdp silently drops rejected m-lines (m=video 0 …) from the SDP answer instead of reflecting them as rejected.

Root cause

// internal.rs ~line 243
let kind = RtpCodecKind::from(media.media_name.media.as_str());
let direction = get_peer_direction(media);
if kind == RtpCodecKind::Unspecified
    || direction == RTCRtpTransceiverDirection::Unspecified  // <-- hits here for rejected m-lines
{
    continue;  // m-line is silently skipped
}

A rejected m-line in an offer has port 0 and carries no a=sendrecv/sendonly/recvonly/inactive attribute, so get_peer_direction returns Unspecified. The continue causes the m-line to be omitted from the answer entirely.

Expected behaviour (RFC 8829 §5.3.1)

If the answerer has no media format in common for a given m= section, the answerer MUST reject that m= section by setting the port to zero.

More broadly, the answer MUST contain the same number of m-lines as the offer, in the same order, to preserve m-line indexing. A rejected offer m-line must produce a rejected (port=0) answer m-line.

Impact

  • Any peer that receives an offer containing a rejected video/audio m-line and tries to create an answer will produce a malformed answer (wrong m-line count).
  • Breaks interoperability with browsers, which routinely emit rejected m-lines during renegotiation.

Fix

Detect rejected m-lines (direction == Unspecified AND port == 0) and push a rejected MediaSection instead of skipping:

if kind == RtpCodecKind::Unspecified {
    continue;
}
if direction == RTCRtpTransceiverDirection::Unspecified {
    // Rejected m-line — reflect as rejected in the answer (RFC 8829 §5.3.1)
    media_sections.push(MediaSection {
        mid: mid_value.to_owned(),
        rejected: true,
        ..Default::default()
    });
    continue;
}

This requires adding a rejected: bool field to MediaSection and handling it in the SDP writer (sdp/mod.rs) to emit m=<kind> 0 … with no attributes.

Discovered while investigating webrtc-rs/webrtc#787.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions