OpenSIPS version: 3.6.6 — code is byte-identical in master (4.0.0-beta) for the affected functions
Modules: rtp_relay (rtpengine backend), dialog, proxy setup (no b2b)
Description
In a dialog-based (non-b2b) proxied call where rtp_relay is engaged on the initial INVITE, sequential in-dialog re-INVITEs (hold / unhold) are not re-anchored. The DLGCB_REQ_WITHIN callback (rtp_relay_indlg) fires, but no offer/answer is sent to the RTP backend, and the original SDP is forwarded unchanged. After unhold, audio is dead because the endpoint's real SDP reaches the peer without passing through rtpengine.
Topology
An upstream B2BUA (FreeSWITCH) bridges the call; OpenSIPS proxies the FreeSWITCH↔agent leg. rtp_relay is the sole media handler on that leg.
Config (relevant)
initial INVITE
create_dialog();
rtp_relay_engage("rtpengine");
in-dialog
if (has_totag() && loose_route()) { t_relay(); } # rtp_relay left to manage media automatically
Steps to reproduce
- Establish call — media is correctly anchored (rtp_relay_offer: leg=caller, rtp_relay_answer: leg=callee).
- Agent presses hold → phone sends re-INVITE with SDP (c=0.0.0.0 / a=sendonly).
- Unhold → re-INVITE with active SDP.
Expected: rtp_relay re-runs offer/answer on each in-dialog re-INVITE and rewrites the SDP via rtpengine.
Actual: rtp_relay_indlg runs but emits no offer/answer; SDP forwarded unchanged; media breaks after unhold.
Debug (log_level 4) — on the hold re-INVITE:
DBG:dialog:run_dlg_callbacks: dialog=0x..., type=16 # DLGCB_REQ_WITHIN fires
DBG:rtp_relay:rtp_relay_reqin: reffing ref=2 for ctx=0x...
<-- no rtp_relay_offer / rtp_relay_answer line at all -->
Initial setup, for comparison:
DBG:rtp_relay:rtp_relay_offer: leg=caller ...
DBG:rtp_relay:rtp_relay_answer: leg=callee ttag=[...] ...
OpenSIPS version: 3.6.6 — code is byte-identical in master (4.0.0-beta) for the affected functions
Modules: rtp_relay (rtpengine backend), dialog, proxy setup (no b2b)
Description
In a dialog-based (non-b2b) proxied call where rtp_relay is engaged on the initial INVITE, sequential in-dialog re-INVITEs (hold / unhold) are not re-anchored. The DLGCB_REQ_WITHIN callback (rtp_relay_indlg) fires, but no offer/answer is sent to the RTP backend, and the original SDP is forwarded unchanged. After unhold, audio is dead because the endpoint's real SDP reaches the peer without passing through rtpengine.
Topology
An upstream B2BUA (FreeSWITCH) bridges the call; OpenSIPS proxies the FreeSWITCH↔agent leg. rtp_relay is the sole media handler on that leg.
Config (relevant)
initial INVITE
create_dialog();
rtp_relay_engage("rtpengine");
in-dialog
if (has_totag() && loose_route()) { t_relay(); } # rtp_relay left to manage media automatically
Steps to reproduce
Expected: rtp_relay re-runs offer/answer on each in-dialog re-INVITE and rewrites the SDP via rtpengine.
Actual: rtp_relay_indlg runs but emits no offer/answer; SDP forwarded unchanged; media breaks after unhold.
Debug (log_level 4) — on the hold re-INVITE:
DBG:dialog:run_dlg_callbacks: dialog=0x..., type=16 # DLGCB_REQ_WITHIN fires
DBG:rtp_relay:rtp_relay_reqin: reffing ref=2 for ctx=0x...
<-- no rtp_relay_offer / rtp_relay_answer line at all -->
Initial setup, for comparison:
DBG:rtp_relay:rtp_relay_offer: leg=caller ...
DBG:rtp_relay:rtp_relay_answer: leg=callee ttag=[...] ...