Skip to content

Commit

Permalink
Don't forward user's RTP header extensions in send_rtp/4
Browse files Browse the repository at this point in the history
  • Loading branch information
mickel8 committed Jan 15, 2025
1 parent d74a937 commit 1a25130
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 6 deletions.
26 changes: 22 additions & 4 deletions lib/ex_webrtc/peer_connection.ex
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,16 @@ defmodule ExWebRTC.PeerConnection do
GenServer.call(peer_connection, {:controlling_process, controlling_process})
end

@doc """
Returns current `peer_connection` configuration.
Note: the configuration may change after applying remote description.
"""
@spec get_configuration(peer_connection()) :: Configuration.t()
def get_configuration(peer_connection) do
GenServer.call(peer_connection, :get_configuration)
end

@doc """
Sends an RTP packet to the remote peer using the track specified by the `track_id`.
Expand Down Expand Up @@ -561,6 +571,11 @@ defmodule ExWebRTC.PeerConnection do
{:reply, :ok, state}
end

@impl true
def handle_call(:get_configuration, _from, state) do
{:reply, state.config, state}
end

@impl true
def handle_call(:get_connection_state, _from, state) do
{:reply, state.conn_state, state}
Expand Down Expand Up @@ -1097,6 +1112,12 @@ defmodule ExWebRTC.PeerConnection do
|> Enum.find(fn {tr, _idx} -> tr.sender.track && tr.sender.track.id == track_id end)
|> case do
{tr, idx} ->
# When RTP packet comes from another peer connection,
# it can already have some extensions, in particular,
# extensions that we didn't negotiate (consider simulcast and rid).
# Remove these extensions and add ours.
packet = ExRTP.Packet.remove_extensions(packet)

{packet, state} =
case state.twcc_extension_id do
nil ->
Expand All @@ -1107,10 +1128,7 @@ defmodule ExWebRTC.PeerConnection do
ExRTP.Packet.Extension.TWCC.new(state.sent_packets)
|> ExRTP.Packet.Extension.TWCC.to_raw(id)

packet =
packet
|> ExRTP.Packet.remove_extension(id)
|> ExRTP.Packet.add_extension(twcc)
packet = ExRTP.Packet.add_extension(packet, twcc)

state = %{state | sent_packets: state.sent_packets + 1 &&& 0xFFFF}
{packet, state}
Expand Down
7 changes: 6 additions & 1 deletion lib/ex_webrtc/peer_connection/configuration.ex
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,12 @@ defmodule ExWebRTC.PeerConnection.Configuration do
rtcp_feedbacks: [rtcp_feedback()]
]

@typedoc false
@typedoc """
`ExWebRTC.PeerConnection` configuration.
It is created from options passed to `ExWebRTC.PeerConnection.start_link/1`.
See `t:options/0` for more.
"""
@type t() :: %__MODULE__{
controlling_process: Process.dest(),
ice_servers: [ice_server()],
Expand Down
8 changes: 7 additions & 1 deletion test/ex_webrtc/peer_connection_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,13 @@ defmodule ExWebRTC.PeerConnectionTest do
:ok = negotiate(pc1, pc2)
:ok = connect(pc1, pc2)

config = PeerConnection.get_configuration(pc1)
negotiated_ext_ids = Enum.map(config.audio_extensions ++ config.video_extensions, & &1.id)
non_negotiated_ext_id = Enum.random(Enum.to_list(1..255) -- negotiated_ext_ids)

payload = <<3, 2, 5>>
packet = ExRTP.Packet.new(payload)
non_negotiated_ext = %ExRTP.Packet.Extension{id: non_negotiated_ext_id, data: "0"}
packet = payload |> ExRTP.Packet.new() |> ExRTP.Packet.add_extension(non_negotiated_ext)

# Try to send data using correct track id.
# Assert that pc2 received this data and send_rtp didn't modify some of the fields.
Expand All @@ -237,6 +242,7 @@ defmodule ExWebRTC.PeerConnectionTest do
assert recv_packet.payload == packet.payload
assert recv_packet.sequence_number == packet.sequence_number
assert recv_packet.timestamp == packet.timestamp
assert non_negotiated_ext not in recv_packet.extensions

# Try to send data using invalid track id.
# Assert that pc1 is still alive and pc2 didn't receive this data.
Expand Down

0 comments on commit 1a25130

Please sign in to comment.