From 670e6e019ba28372aa3c54b252eeacb1c237d6dd Mon Sep 17 00:00:00 2001 From: Matthias van der Vlies <674985+killdashnine@users.noreply.github.com> Date: Fri, 2 Oct 2026 14:20:25 +0200 Subject: [PATCH] [rtp_relay] keep the all-branches session across a failed branch --- modules/rtp_relay/rtp_relay_ctx.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/modules/rtp_relay/rtp_relay_ctx.c b/modules/rtp_relay/rtp_relay_ctx.c index e2c15151916..f0bd5a6ef23 100644 --- a/modules/rtp_relay/rtp_relay_ctx.c +++ b/modules/rtp_relay/rtp_relay_ctx.c @@ -1875,6 +1875,26 @@ static int rtp_relay_ctx_leg_reply(struct rtp_relay_ctx *ctx, struct sip_msg *ms return ret; } +/* a session engaged for all the branches also covers the ones the failure + * route may still create (digest retry, failover), so a failed branch must + * not destroy it: release the media of the failed attempt and forget its + * callee, and the next branch that is forwarded makes a fresh offer */ +static void rtp_relay_sess_failed_branch(struct rtp_relay_ctx *ctx, + struct rtp_relay_sess *sess, struct sip_msg *rpl, struct sip_msg *req) +{ + struct rtp_relay_session info; + + if (!rtp_sess_late(sess)) { + memset(&info, 0, sizeof info); + info.msg = (rpl == FAKED_REPLY ? req : rpl); + rtp_relay_delete(&info, ctx, sess, RTP_RELAY_CALLEE); + rtp_sess_reset_ongoing(sess); + } + /* the tag belongs to the branch that failed */ + if (sess->legs[RTP_RELAY_CALLEE]) + shm_str_clean(&sess->legs[RTP_RELAY_CALLEE]->tag); +} + static void rtp_relay_ctx_initial_cb(struct cell* t, int type, struct tmcb_params *p) { struct rtp_relay_session info; @@ -1902,6 +1922,11 @@ static void rtp_relay_ctx_initial_cb(struct cell* t, int type, struct tmcb_param rtp_sess_disabled(sess), rtp_sess_pending(sess)); goto end; } + if (type == TMCB_ON_FAILURE && + sess->index == RTP_RELAY_ALL_BRANCHES) { + rtp_relay_sess_failed_branch(ctx, sess, p->rpl, p->req); + break; + } rtp_relay_fill_sess_leg(ctx, sess, RTP_RELAY_CALLEE, NULL, rtp_relay_ctx_branch()); switch (handle_rtp_relay_ctx_leg_reply(ctx, p->rpl, p->req, sess, RTP_RELAY_CALLEE)) {