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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions