diff --git a/daemon/call.c b/daemon/call.c index 11208e523..f9f2bafe5 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -4690,6 +4690,7 @@ new_branch: __C_DBG("create new \"other side\" monologue for viabranch "STR_FORMAT, STR_FMT0(viabranch)); os = __monologue_create(call); __monologue_viabranch(os, viabranch); + goto finish; have_dialogue: for (unsigned int i = 0; i < ret->medias->len; i++) @@ -4805,8 +4806,15 @@ static int call_get_dialogue(struct call_monologue *monologues[2], call_t *call, * if the offer monologue belongs to an unanswered call (empty tag), * hence `ft->tag` has to be empty at this stage. */ - if (!ft || ft->tag.s) + if (!ft) ft = __monologue_create(call); + else if (ft->tag.s) { + // Allow an updated/changed to-tag in answers unless the flag to + // suppress this feature is set. A changed to-tag will be stored + // as a tag alias. + if (!flags || flags->opmode != OP_ANSWER || flags->new_branch) + ft = __monologue_create(call); + } tag_setup: if (ft == tt) diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index ab661d656..cad093241 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -1104,6 +1104,9 @@ void call_ng_flags_flags(str *s, unsigned int idx, helper_arg arg) { case CSH_LOOKUP("nat-wait"): out->nat_wait = 1; break; + case CSH_LOOKUP("new-branch"): + out->new_branch = 1; + break; case CSH_LOOKUP("no-codec-renegotiation"): case CSH_LOOKUP("reuse-codecs"): out->reuse_codec = 1; diff --git a/docs/ng_control_protocol.md b/docs/ng_control_protocol.md index c2bd76c8d..639c73b7a 100644 --- a/docs/ng_control_protocol.md +++ b/docs/ng_control_protocol.md @@ -1028,6 +1028,24 @@ Spaces in each string may be replaced by hyphens. direction before sending packets out, which could result in an automated firewall block. +* `new branch` + + If *rtpengine* receives an answer from a to-tag that hasn't previously seen + and no corresponding call party is known (created from a previous offer), + previously it would treat this is a separate new call branch, create a + brand new internal call party, and dissociate the previous one. This may + lead to unexpected results as this new call party has been created without + the same initialisation as was done for the original one, and so may be + left with incorrect or incomplete data (e.g. SRTP keys, codec information, + interface bindings, etc). + + Improve this by treating an unexpected and unseen to-tag as an alias to the + already existing to-tag. Going forward both tags can then be used + interchangeably to refer to the same monologue. + + This flag suppresses this new behaviour, in case some situation is made + worse by it. + * `no port latching` Port latching is enabled by default for endpoints which speak diff --git a/include/call_interfaces.h b/include/call_interfaces.h index 736d13436..a2cbc3822 100644 --- a/include/call_interfaces.h +++ b/include/call_interfaces.h @@ -236,6 +236,7 @@ struct sdp_ng_flags { pierce_nat:1, directional:1, fatal:1, + new_branch:1, /* to_tag is used especially by delete handling */ to_tag_flag:1; };