Branch: refs/heads/4.0
Home: https://github.com/OpenSIPS/opensips
Commit: 5fa4e627187f23544e702db0a47dbe877a407117
https://github.com/OpenSIPS/opensips/commit/5fa4e627187f23544e702db0a47dbe877a407117
Author: Andrii Pogrebennyk <[email protected]>
Date: 2026-09-21 (Mon, 21 Sep 2026)
Changed paths:
M modules/b2b_entities/b2b_entities.c
M modules/b2b_entities/b2be_load.h
M modules/b2b_entities/dlg.c
M modules/b2b_entities/dlg.h
M modules/b2b_logic/logic.c
Log Message:
-----------
b2b_entities: give each early dialog its own UPDATE transaction
With pass-legs-upstream, every downstream leg is advertised to the caller
as a distinct early dialog, so the caller runs preconditions on each one
and can have two UPDATE transactions open at once. b2b_entities had room
for one: dlg->update_tran, shared by every leg. PRACK was moved to per-leg
storage when the distinct to-tags landed; UPDATE was not.
On an NW-RBT call the ringback dialog's UPDATE therefore evicted the first
one's transaction, and when the terminating UE finally answered its UPDATE
the reply found a NULL field and a dialog-wide last_reply_code already
holding 200 - so it was filed as a retransmission and dropped at DBG level,
with no error line anywhere. The caller retransmitted unanswered and gave
up: CANCEL -> 487. Three captures prove it, and the UE's own answer time is
the only variable that decides the outcome: 86 ms completes, 261-264 ms
against a ~200 ms budget fails.
* b2b_entities: update_tran and last_reply_code move into dlg_leg_t
beside prack_tran, resolved by the leg index b2b_logic already passes
in rpl_data. Overwrites unref the evicted cell, teardown 408s every
pending leg, and a reply whose index does not resolve falls back to the
single pending UPDATE rather than to a field that is now always empty.
* b2b_logic: an indexed PRACK or UPDATE is relayed only to the peer that
owns that leg, not to every peer in the chain. One upstream UPDATE used
to produce two downstream transactions racing for one upstream
transaction, so a downstream 200 was discarded on every RBT call -
harmlessly on those that completed. PRACK was already single-target,
but only because _b2b_send_request failed on the non-owning peer and
logged an error.
* b2b_entities: new has_leg_idx(), so leg ownership is asked of the
module that allocates the indices rather than tracked in parallel.
Verification signature: "No leg found for index [2]" should disappear
entirely - 47 of them in two days of logs, one per RBT call - and a failing
call should show one 200 UPDATE relayed per leg instead of two orphaned.
Also adds the diagnostics this bug hid behind: the UPDATE store and fetch
are each logged with their leg index, the retransmission verdict says which
leg it judged, leg-index allocation and the routing decision are traceable,
and a reply whose leg index resolves to no pending transaction raises a
WARN. That last one cannot fire without pass-legs-upstream, so it is an
anomaly signal rather than noise.
(cherry picked from commit 032ba34bfe361c475cc9dcdb081408a6676a7194)
To unsubscribe from these emails, change your notification settings at
https://github.com/OpenSIPS/opensips/settings/notifications
_______________________________________________
Devel mailing list
[email protected]
http://lists.opensips.org/cgi-bin/mailman/listinfo/devel