Hi all,
I'm seeing a brief burst of noise on the outgoing (TX) RTP stream at the exact moment rtpengine processes a re-offer, and I'd appreciate help understanding whether this is expected behavior or a misuse of the offer options on my side.
Setup
• rtpengine acts as a media relay (B2BUA controlled by our signaling server) between a WebRTC leg (A) and a SIP/PBX leg (B).
• The call is established as plain RTP end-to-end. B answered with RTP/AVP only (it does not support SRTP), so media flows unencrypted.
• We use OSRTP / legacy offer so the initial offer toward B contains two m-lines sharing the same port and SSRC: one RTP/SAVP (with a=crypto) and one RTP/AVP (no crypto). B picks RTP/AVP.
What triggers the issue :
When A puts the call on hold, our server sends a re-offer to rtpengine.
The offer request uses these options (rtpengine ng protocol):
transport protocol: RTP/SAVP
OSRTP: offer-legacy
flags: SDES-only-AES_CM_128_HMAC_SHA1_80, codec-strip-all,
codec-offer-PCMA, codec-offer-PCMU, codec-offer-H264,
port latching
DTLS: off
ICE: remove
rtcp-mux: demux
ptime: 20
direction: (hold, a=sendonly on the WebRTC side)
The resulting SDP that rtpengine produces toward B again contains both an RTP/SAVP m-line (with a=crypto) and an RTP/AVP m-line, same port/SSRC:
m=audio 55342 RTP/SAVP 8 0
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:+sLivjldL6zDn83KL0URaTemu8qOmp2BkUPrsAis
...
m=audio 55342 RTP/AVP 8 0
...
The problem
At the moment this re-offer is applied by rtpengine — and before B sends its 200 OK (i.e. before the answer is processed) — a short burst of noise appears on the RTP stream that rtpengine sends toward B. Capturing/playing the TX packets confirms the noise is in the media rtpengine emits.
If the exact same call is set up without the SRTP m-line (plain RTP/AVP only, no crypto in any offer/re-offer), the noise does not occur on hold.
My questions
1. When a re-offer contains both RTP/SAVP (with crypto) and RTP/AVP m-lines for the same stream/port/SSRC, how does rtpengine treat the outgoing media at the offer stage, before the answer selects a profile? Since the peer hasn't chosen yet, I'd expect the TX side to stay unchanged until the answer — is that correct?
2. Could applying such a dual-profile re-offer cause rtpengine to re-initialize or re-key the SRTP/crypto context (or otherwise rebuild the media flow) in a way that briefly corrupts the TX stream, even though the active call is plain RTP?
3.Is OSRTP: offer-legacy + transport protocol: RTP/SAVP the correct way to re-offer on a call that was originally negotiated down to plain RTP/AVP? Or should we detect that the established call is plain RTP and re-offer with RTP/AVP only (no crypto) to avoid touching the crypto context?
4. Does port latching combined with a protocol change (RTP/AVP active → RTP/SAVP re-offered on the same port) play any role here?
Environment
• rtpengine version: 13.4
• OS / kernel : Ubuntu 5.15.0-143-generic, Forwarding: Kernel module
Any guidance on whether this is expected and how to re-offer correctly on a plain-RTP call would be very helpful. I can share full offer/answer ng payloads and a pcap if useful.
Thanks!