diff --git a/debian/patches/series b/debian/patches/series index d5ec8ce6a..768268149 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -43,6 +43,8 @@ upstream/lcr-source-port-check-for-from_any_gw-and-from_gw.patch upstream/lcr-remove-excessive-checks-for-the-src_port-accurac.patch upstream/lcr-improve-binary-search-to-support-match-including-src-port.patch upstream/nathelper-fix_nated_sdp-added-ignoring-RFC3605-param.patch +upstream/tm_api_improvement_t_append_branches_with_contact.patch +upstream/tsilo_append_by_contact.patch ### relevant for upstream sipwise/pua_dialoginfo-refresh_pubruri_avps_flag.patch sipwise/pua_dialoginfo-local_identity_dlg_var.patch @@ -62,8 +64,6 @@ sipwise/kamctl-TMPDIR-config.patch sipwise/lcr-stopper_mode-parameter.patch sipwise/lcr_improve_comparison_based_on_gws_port.patch # -sipwise/tm_t_append_branch_by_contact.patch -sipwise/tsilo_add_ts_append_by_contact.patch sipwise/pv-headers-clone-branch-ignore-skip-header.patch upstream/permissions-don-t-remove-old-data-at-the-end-of-the-.patch upstream/permissions-trusted_cleanup_interval.patch diff --git a/debian/patches/sipwise/tm_t_append_branch_by_contact.patch b/debian/patches/sipwise/tm_t_append_branch_by_contact.patch deleted file mode 100644 index e340d9758..000000000 --- a/debian/patches/sipwise/tm_t_append_branch_by_contact.patch +++ /dev/null @@ -1,244 +0,0 @@ ---- a/src/modules/tm/t_append_branches.c -+++ b/src/modules/tm/t_append_branches.c -@@ -237,3 +237,209 @@ done: - } - return ret; - } -+ -+/* append a new transaction based on desired Contact hf value -+ * contact parameter must be of syntax (no hf parameters): -+ * sip:@: */ -+int t_append_branch_by_contact(str * contact) { -+ struct cell *t = NULL; -+ struct sip_msg *orig_msg = NULL; -+ struct sip_msg *faked_req; -+ int faked_req_len = 0; -+ -+ short outgoings; -+ -+ int success_branch; -+ -+ str current_uri; -+ str dst_uri, path, instance, ruid, location_ua; -+ struct socket_info* si; -+ int q, i, found, append; -+ flag_t backup_bflags = 0; -+ flag_t bflags = 0; -+ int new_branch, branch_ret, lowest_ret; -+ branch_bm_t added_branches; -+ int replies_locked = 0; -+ int ret = 0; -+ -+ t = get_t(); -+ if(t == NULL) -+ { -+ LM_ERR("cannot get transaction\n"); -+ return -1; -+ } -+ -+ LM_DBG("transaction %u:%u in status %d\n", t->hash_index, t->label, t->uas.status); -+ -+ /* test if transaction has already been canceled */ -+ if (t->flags & T_CANCELED) { -+ ser_error=E_CANCELED; -+ return -1; -+ } -+ -+ if ((t->uas.status >= 200 && t->uas.status<=399) -+ || ((t->uas.status >= 600 && t->uas.status) -+ && !(t->flags & (T_6xx | T_DISABLE_6xx))) ) { -+ LM_DBG("transaction %u:%u in status %d: cannot append new branch\n", -+ t->hash_index, t->label, t->uas.status); -+ return -1; -+ } -+ -+ /* set the lock on the transaction here */ -+ LOCK_REPLIES(t); -+ replies_locked = 1; -+ outgoings = t->nr_of_outgoings; -+ orig_msg = t->uas.request; -+ -+ LM_DBG("Call %.*s: %d (%d) outgoing branches\n",orig_msg->callid->body.len, -+ orig_msg->callid->body.s,outgoings, nr_branches); -+ -+ lowest_ret=E_UNSPEC; -+ added_branches=0; -+ -+ /* it's a "late" branch so the on_branch variable has already been -+ reset by previous execution of t_forward_nonack: we use the saved -+ value */ -+ if (t->on_branch_delayed) { -+ /* tell add_uac that it should run branch route actions */ -+ set_branch_route(t->on_branch_delayed); -+ } -+ faked_req = fake_req(orig_msg, 0, NULL, &faked_req_len); -+ if (faked_req==NULL) { -+ LM_ERR("fake_req failed\n"); -+ return -1; -+ } -+ -+ /* fake also the env. conforming to the fake msg */ -+ faked_env( t, faked_req, 0); -+ -+ /* DONE with faking ;-) -> run the failure handlers */ -+ init_branch_iterator(); -+ -+ while((current_uri.s=next_branch( ¤t_uri.len, &q, &dst_uri, &path, -+ &bflags, &si, &ruid, &instance, &location_ua))) { -+ LM_DBG("Current uri %.*s\n",current_uri.len, current_uri.s); -+ -+ append = 1; -+ if (strstr(current_uri.s, contact->s) == NULL) { -+ append = 0; -+ } -+ -+ /* do not append the branch if a contact does not match */ -+ if (!append) -+ continue; -+ -+ LM_DBG("Branch will be appended for contact <%.*s>\n", contact->len, contact->s); -+ -+ found = 0; -+ for (i=0; iuac[i].ruid.len == ruid.len -+ && !memcmp(t->uac[i].ruid.s, ruid.s, ruid.len) -+ && t->uac[i].uri.len == current_uri.len -+ && !memcmp(t->uac[i].uri.s, current_uri.s, current_uri.len)) { -+ LM_DBG("branch already added [%.*s]\n", ruid.len, ruid.s); -+ found = 1; -+ break; -+ } -+ } -+ if (found) -+ continue; -+ -+ setbflagsval(0, bflags); -+ new_branch=add_uac( t, faked_req, ¤t_uri, -+ (dst_uri.len) ? (&dst_uri) : ¤t_uri, -+ &path, 0, si, faked_req->fwd_send_flags, -+ PROTO_NONE, (dst_uri.len)?0:UAC_SKIP_BR_DST_F, &instance, -+ &ruid, &location_ua); -+ -+ LM_DBG("added branch [%.*s] with ruid [%.*s]\n", -+ current_uri.len, current_uri.s, ruid.len, ruid.s); -+ -+ /* test if cancel was received meanwhile */ -+ if (t->flags & T_CANCELED) goto canceled; -+ -+ if (new_branch>=0) -+ added_branches |= 1<callid->body.len, orig_msg->callid->body.s,outgoings, nr_branches); -+ setbflagsval(0, backup_bflags); -+ -+ /* update message flags, if changed in branch route */ -+ t->uas.request->flags = faked_req->flags; -+ -+ if (added_branches==0) { -+ if(lowest_ret!=E_CFG) -+ LM_ERR("failure to add branches (%d)\n", lowest_ret); -+ ser_error=lowest_ret; -+ ret = lowest_ret; -+ goto done; -+ } -+ -+ ser_error=0; /* clear branch adding errors */ -+ /* send them out now */ -+ success_branch=0; -+ /* since t_append_branch can only be called from REQUEST_ROUTE, always lock replies */ -+ -+ for (i=outgoings; inr_of_outgoings; i++) { -+ if (added_branches & (1<=0){ /* some kind of success */ -+ if (branch_ret==i) { /* success */ -+ success_branch++; -+ if (unlikely(has_tran_tmcbs(t, TMCB_REQUEST_OUT))) -+ run_trans_callbacks_with_buf( TMCB_REQUEST_OUT, -+ &t->uac[nr_branches].request, -+ faked_req, 0, TMCB_NONE_F); -+ } -+ else /* new branch added */ -+ added_branches |= 1<uas.request->flags = faked_req->flags; -+ /* if needed unlock transaction's replies */ -+ /* restore the number of outgoing branches -+ * since new branches have not been completed */ -+ t->nr_of_outgoings = outgoings; -+ ser_error=E_CANCELED; -+ ret = -1; -+done: -+ /* restore original environment and free the fake msg */ -+ faked_env( t, 0, 0); -+ free_faked_req(faked_req, faked_req_len); -+ -+ if (likely(replies_locked)) { -+ replies_locked = 0; -+ UNLOCK_REPLIES(t); -+ } -+ return ret; -+} -\ No newline at end of file ---- a/src/modules/tm/t_append_branches.h -+++ b/src/modules/tm/t_append_branches.h -@@ -34,4 +34,8 @@ - int t_append_branches(void); - typedef int (*t_append_branches_f)(void); - -+/* append a new transaction based on desired Contact hf value */ -+int t_append_branch_by_contact(str * contact); -+typedef int (*t_append_branch_by_contact_f)(str * contact); -+ - #endif ---- a/src/modules/tm/tm_load.c -+++ b/src/modules/tm/tm_load.c -@@ -134,6 +134,7 @@ int load_tm( struct tm_binds *tmb) - tmb->tm_ctx_get = tm_ctx_get; - #endif - tmb->t_append_branches = t_append_branches; -+ tmb->t_append_branch_by_contact = t_append_branch_by_contact; - tmb->t_load_contacts = t_load_contacts; - tmb->t_next_contacts = t_next_contacts; - tmb->set_fr = t_set_fr; ---- a/src/modules/tm/tm_load.h -+++ b/src/modules/tm/tm_load.h -@@ -118,6 +118,7 @@ struct tm_binds { - void* reserved5; - #endif - t_append_branches_f t_append_branches; -+ t_append_branch_by_contact_f t_append_branch_by_contact; - cmd_function t_load_contacts; - cmd_function t_next_contacts; - tset_fr_f set_fr; diff --git a/debian/patches/sipwise/tsilo_add_ts_append_by_contact.patch b/debian/patches/sipwise/tsilo_add_ts_append_by_contact.patch deleted file mode 100644 index 459af9525..000000000 --- a/debian/patches/sipwise/tsilo_add_ts_append_by_contact.patch +++ /dev/null @@ -1,461 +0,0 @@ -From: Sipwise Development Team -Date: Tue, 2 Nov 2021 11:14:23 +0100 -Subject: tsilo_add_ts_append_by_contact - ---- - src/modules/tsilo/ts_append.c | 116 ++++++++++++++++++ - src/modules/tsilo/ts_append.h | 2 + - src/modules/tsilo/tsilo.c | 269 +++++++++++++++++++++++++++++++++++++++++- - 3 files changed, 386 insertions(+), 1 deletion(-) - -diff --git a/src/modules/tsilo/ts_append.c b/src/modules/tsilo/ts_append.c -index 7d95186..1847ac1 100644 ---- a/src/modules/tsilo/ts_append.c -+++ b/src/modules/tsilo/ts_append.c -@@ -139,3 +139,119 @@ done: - - return ret; - } -+ -+int ts_append_by_contact(struct sip_msg* msg, str *ruri, str *contact, char *table) { -+ ts_urecord_t* _r; -+ ts_transaction_t* ptr; -+ -+ struct sip_uri p_uri; -+ struct sip_uri c_uri; -+ str *t_uri; -+ -+ int res; -+ int appended; -+ -+ /* parse R-URI */ -+ if (use_domain) { -+ t_uri = ruri; -+ } else { -+ if (parse_uri(ruri->s, ruri->len, &p_uri) < 0) { -+ LM_ERR("tsilo: failed to parse uri %.*s\n", ruri->len, ruri->s); -+ return -1; -+ } -+ t_uri = &p_uri.user; -+ } -+ -+ /* parse contact */ -+ if (parse_uri(contact->s, contact->len, &c_uri) < 0) { -+ LM_ERR("tsilo: failed to parse contact %.*s\n", ruri->len, ruri->s); -+ return -1; -+ } -+ -+ /* find urecord in TSILO cache */ -+ lock_entry_by_ruri(t_uri); -+ res = get_ts_urecord(t_uri, &_r); -+ -+ if (res != 0) { -+ LM_ERR("tsilo: failed to retrieve record for %.*s\n", t_uri->len, t_uri->s); -+ unlock_entry_by_ruri(t_uri); -+ return -1; -+ } -+ -+ /* cycle through existing transactions */ -+ ptr = _r->transactions; -+ while(ptr) { -+ LM_DBG("tsilo: transaction %u:%u found for %.*s, going to append branches\n", -+ ptr->tindex, ptr->tlabel, t_uri->len, t_uri->s); -+ /* append only if the desired contact has been found in locations */ -+ appended = ts_append_by_contact_to(msg, ptr->tindex, ptr->tlabel, table, ruri, contact); -+ if (appended > 0) -+ update_stat(added_branches, appended); -+ ptr = ptr->next; -+ } -+ -+ unlock_entry_by_ruri(t_uri); -+ -+ return 1; -+} -+ -+int ts_append_by_contact_to(struct sip_msg* msg, int tindex, int tlabel, char *table, str *uri, str *contact) { -+ struct cell *t=0; -+ struct cell *orig_t; /* a pointer to an existing transaction or 0 if lookup fails*/ -+ struct sip_msg *orig_msg; -+ int ret; -+ str stable; -+ -+ LM_DBG("tsilo: trying to append based on contact <%.*s>\n", contact->len, contact->s); -+ -+ /* lookup a transaction based on its identifier (hash_index:label) */ -+ orig_t = _tmb.t_gett(); -+ if(_tmb.t_lookup_ident(&t, tindex, tlabel) < 0) -+ { -+ LM_ERR("tsilo: transaction [%u:%u] not found\n", tindex, tlabel); -+ ret = -1; -+ goto done; -+ } -+ -+ /* check if the dialog is still in the early stage */ -+ if (t->flags & T_CANCELED) { -+ LM_DBG("tsilo: trasaction [%u:%u] was cancelled\n", tindex, tlabel); -+ ret = -2; -+ goto done; -+ } -+ if (t->uas.status >= 200) { -+ LM_DBG("tsilo: trasaction [%u:%u] sent out a final response already - %d\n", -+ tindex, tlabel, t->uas.status); -+ ret = -3; -+ goto done; -+ } -+ -+ /* get original (very first) request of the transaction */ -+ orig_msg = t->uas.request; -+ stable.s = table; -+ stable.len = strlen(stable.s); -+ -+ if(uri==NULL || uri->s==NULL || uri->len<=0) { -+ ret = _regapi.lookup_to_dset(orig_msg, &stable, NULL); -+ } else { -+ ret = _regapi.lookup_to_dset(orig_msg, &stable, uri); -+ } -+ -+ if(ret != 1) { -+ LM_ERR("tsilo: transaction %u:%u: error updating dset (%d)\n", tindex, tlabel, ret); -+ ret = -4; -+ goto done; -+ } -+ -+ /* start the transaction only for the desired contact -+ contact must be of syntax: sip:@: with no parameters list*/ -+ ret = _tmb.t_append_branch_by_contact(contact); -+ -+done: -+ /* unref the transaction which had been referred by t_lookup_ident() call. -+ * Restore the original transaction (if any) */ -+ if(t) _tmb.unref_cell(t); -+ _tmb.t_sett(orig_t, T_BR_UNDEFINED); -+ -+ return ret; -+} -diff --git a/src/modules/tsilo/ts_append.h b/src/modules/tsilo/ts_append.h -index 56f9120..461f888 100644 ---- a/src/modules/tsilo/ts_append.h -+++ b/src/modules/tsilo/ts_append.h -@@ -24,5 +24,7 @@ - - int ts_append(struct sip_msg* msg, str *ruri, char *table); - int ts_append_to(struct sip_msg* msg, int tindex, int tlabel, char *table, str *uri); -+int ts_append_by_contact(struct sip_msg* msg, str *ruri, str *contact, char *table); -+int ts_append_by_contact_to(struct sip_msg* msg, int tindex, int tlabel, char *table, str *uri, str *contact); - - #endif -diff --git a/src/modules/tsilo/tsilo.c b/src/modules/tsilo/tsilo.c -index 0c531ac..2eefb2f 100644 ---- a/src/modules/tsilo/tsilo.c -+++ b/src/modules/tsilo/tsilo.c -@@ -34,6 +34,8 @@ - #include "../../core/rpc_lookup.h" - #include "../../core/kemi.h" - -+#include "../../core/parser/contact/parse_contact.h" -+ - #include "ts_hash.h" - #include "ts_handlers.h" - #include "ts_append.h" -@@ -61,7 +63,9 @@ static int w_ts_append_to2(struct sip_msg* msg, char *idx, char *lbl, char *d, c - static int fixup_ts_append_to(void** param, int param_no); - static int w_ts_append(struct sip_msg* _msg, char *_table, char *_ruri); - static int fixup_ts_append(void** param, int param_no); -- -+static int w_ts_append_by_contact2(struct sip_msg* _msg, char *_table, char *_ruri); -+static int w_ts_append_by_contact3(struct sip_msg* _msg, char *_table, char *_ruri, char *_contact); -+static int fixup_ts_append_by_contact(void** param, int param_no); - static int w_ts_store(struct sip_msg* msg, char *p1, char *p2); - static int w_ts_store1(struct sip_msg* msg, char *_ruri, char *p2); - -@@ -78,6 +82,10 @@ static cmd_export_t cmds[]={ - fixup_ts_append_to, 0, REQUEST_ROUTE | FAILURE_ROUTE }, - {"ts_append", (cmd_function)w_ts_append, 2, - fixup_ts_append, 0, REQUEST_ROUTE | FAILURE_ROUTE }, -+ {"ts_append_by_contact", (cmd_function)w_ts_append_by_contact2, 2, /* for two parameters */ -+ fixup_ts_append_by_contact, 0, REQUEST_ROUTE | FAILURE_ROUTE }, -+ {"ts_append_by_contact", (cmd_function)w_ts_append_by_contact3, 3, /* for three parameters */ -+ fixup_ts_append_by_contact, 0, REQUEST_ROUTE | FAILURE_ROUTE }, - {"ts_store", (cmd_function)w_ts_store, 0, - 0 , 0, REQUEST_ROUTE | FAILURE_ROUTE }, - {"ts_store", (cmd_function)w_ts_store1, 1, -@@ -241,6 +249,23 @@ static int fixup_ts_append(void** param, int param_no) - return 0; - } - -+static int fixup_ts_append_by_contact(void** param, int param_no) -+{ -+ if (param_no==1) { -+ if(strlen((char*)*param)<=1 && (*(char*)(*param)==0 || *(char*)(*param)=='0')) { -+ *param = (void*)0; -+ LM_ERR("empty table name\n"); -+ return -1; -+ } -+ } -+ -+ if (param_no==2 || param_no==3) { -+ return fixup_spve_null(param, 1); -+ } -+ -+ return 0; -+} -+ - /** - * - */ -@@ -357,6 +382,238 @@ static int ki_ts_append_to_uri(sip_msg_t* _msg, int tindex, int tlabel, - _table->s, _uri); - } - -+/** -+ * -+ */ -+static int w_ts_append_by_contact2(struct sip_msg* _msg, char *_table, char *_ruri) { -+ str ruri = STR_NULL; -+ str ruri_fixed = STR_NULL; -+ -+ str contact = STR_NULL; -+ str tmp_contact = STR_NULL; -+ struct sip_uri curi; -+ -+ int rc; -+ -+ /* parse R-URI */ -+ if (fixup_get_svalue(_msg, (gparam_t*)_ruri, &ruri_fixed)!=0) { -+ LM_ERR("failed to convert r-uri parameter\n"); -+ return -1; -+ } -+ -+ if (_ruri==NULL || strlen(_ruri) <= 0 || ruri_fixed.len <= 0) { -+ LM_ERR("tsilo: invalid ruri parameter (empty or zero length).\n"); -+ return -1; -+ } -+ -+ if (pkg_str_dup(&ruri, &ruri_fixed) < 0) { -+ LM_ERR("failed to copy r-uri parameter\n"); -+ return -1; -+ } -+ -+ if (ts_check_uri(&ruri) < 0) { -+ LM_ERR("tsilo: failed to parse R-URI.\n"); -+ return -1; -+ } -+ -+ /* parse Contact header */ -+ if ((!_msg->contact && parse_headers(_msg, HDR_CONTACT_F, 0) != 0) -+ || !_msg->contact) { -+ LM_WARN("tsilo: missing contact header or the value is empty/malformed.\n"); -+ return -1; -+ } -+ if (_msg->contact) { -+ if (parse_contact(_msg->contact) < 0) { -+ LM_WARN("tsilo: failed to parse Contact header.\n"); -+ return -1; -+ } -+ if (parse_uri( -+ ((struct contact_body*)_msg->contact->parsed)->contacts->uri.s, -+ ((struct contact_body*)_msg->contact->parsed)->contacts->uri.len, -+ &curi) != 0 ) { -+ if (ts_check_uri(&_msg->contact->body) < 0) { /* one more attempt */ -+ LM_WARN("tsilo: failed to parse Contact header.\n"); -+ return -1; -+ } -+ } -+ -+ tmp_contact.len = ((struct contact_body*)_msg->contact->parsed)->contacts->uri.len; -+ tmp_contact.s = (char*)pkg_malloc(tmp_contact.len+1); -+ if (tmp_contact.s == NULL) { -+ PKG_MEM_ERROR; -+ return -1; -+ } -+ memcpy(tmp_contact.s, ((struct contact_body*)_msg->contact->parsed)->contacts->uri.s, tmp_contact.len); -+ tmp_contact.s[tmp_contact.len] = '\0'; -+ -+ if (pkg_str_dup(&contact, &tmp_contact) < 0) { -+ if (pkg_str_dup(&contact, &_msg->contact->body) < 0) { /* one more attempt */ -+ LM_ERR("tsilo: problems when calling ts_append_contact(), cannot copy Contact parameter.\n"); -+ return -1; -+ } -+ } -+ } -+ -+ /* contact must be of syntax: sip:@: with no parameters list */ -+ rc = ts_append_by_contact(_msg, &ruri, &contact, _table); -+ -+ /* free previously used memory */ -+ pkg_free(ruri.s); -+ pkg_free(contact.s); -+ pkg_free(tmp_contact.s); -+ -+ return rc; -+} -+ -+/** -+ * -+ */ -+static int ki_ts_append_by_contact(sip_msg_t* _msg, str *_table, str *_ruri) { -+ str ruri = STR_NULL; -+ str contact = STR_NULL; -+ str tmp_contact = STR_NULL; -+ struct sip_uri curi; -+ int rc; -+ -+ /* parse R-URI */ -+ if (ts_check_uri(_ruri) < 0) -+ return -1; -+ if (pkg_str_dup(&ruri, _ruri) < 0) -+ return -1; -+ -+ /* parse Contact header */ -+ if ((!_msg->contact && parse_headers(_msg, HDR_CONTACT_F, 0) != 0) || !_msg->contact) -+ return -1; -+ -+ if (_msg->contact) { -+ if (parse_contact(_msg->contact) < 0) -+ return -1; -+ if (parse_uri( -+ ((struct contact_body*)_msg->contact->parsed)->contacts->uri.s, -+ ((struct contact_body*)_msg->contact->parsed)->contacts->uri.len, -+ &curi) != 0 ) { -+ if (ts_check_uri(&_msg->contact->body) < 0) /* one more attempt */ -+ return -1; -+ } -+ -+ tmp_contact.len = ((struct contact_body*)_msg->contact->parsed)->contacts->uri.len; -+ tmp_contact.s = (char*)pkg_malloc(tmp_contact.len+1); -+ if (tmp_contact.s == NULL) { -+ PKG_MEM_ERROR; -+ return -1; -+ } -+ memcpy(tmp_contact.s, ((struct contact_body*)_msg->contact->parsed)->contacts->uri.s, tmp_contact.len); -+ tmp_contact.s[tmp_contact.len] = '\0'; -+ -+ if (pkg_str_dup(&contact, &tmp_contact) < 0) { -+ if (pkg_str_dup(&contact, &_msg->contact->body) < 0) /* one more attempt */ -+ return -1; -+ } -+ } -+ -+ /* contact must be of syntax: sip:@: with no parameters list */ -+ rc = ts_append_by_contact(_msg, &ruri, &contact, _table->s); -+ -+ pkg_free(ruri.s); -+ pkg_free(contact.s); -+ pkg_free(tmp_contact.s); -+ -+ return rc; -+} -+ -+/** -+ * -+ */ -+static int w_ts_append_by_contact3(struct sip_msg* _msg, char *_table, char *_ruri, char *_contact) { -+ str ruri = STR_NULL; -+ str ruri_fixed = STR_NULL; -+ -+ str contact = STR_NULL; -+ str contact_fixed = STR_NULL; -+ -+ int rc; -+ -+ /* parse R-URI */ -+ if (fixup_get_svalue(_msg, (gparam_t*)_ruri, &ruri_fixed)!=0) { -+ LM_ERR("failed to convert r-uri parameter\n"); -+ return -1; -+ } -+ -+ if (_ruri==NULL || strlen(_ruri) <= 0 || ruri_fixed.len <= 0) { -+ LM_ERR("tsilo: invalid ruri parameter.\n"); -+ return -1; -+ } -+ -+ if (pkg_str_dup(&ruri, &ruri_fixed) < 0) { -+ LM_ERR("failed to copy r-uri parameter\n"); -+ return -1; -+ } -+ -+ if (ts_check_uri(&ruri) < 0) { -+ LM_ERR("tsilo: failed to parse R-URI.\n"); -+ return -1; -+ } -+ -+ /* parse Contact header */ -+ if (fixup_get_svalue(_msg, (gparam_t*)_contact, &contact_fixed)!=0) { -+ LM_ERR("failed to convert contact parameter\n"); -+ return -1; -+ } -+ -+ if (_contact==NULL || strlen(_contact) <= 0 || contact_fixed.len <= 0) { -+ LM_ERR("tsilo: invalid contact parameter.\n"); -+ return -1; -+ } -+ -+ if (pkg_str_dup(&contact, &contact_fixed) < 0) { -+ LM_ERR("failed to copy r-uri parameter\n"); -+ return -1; -+ } -+ -+ if (ts_check_uri(&contact) < 0) { -+ LM_ERR("tsilo: failed to parse Contact parameter.\n"); -+ return -1; -+ } -+ -+ /* contact must be of syntax: sip:@: with no parameters list */ -+ rc = ts_append_by_contact(_msg, &ruri, &contact, _table); -+ -+ pkg_free(ruri.s); -+ pkg_free(contact.s); -+ -+ return rc; -+} -+ -+/** -+ * -+ */ -+static int ki_ts_append_by_contact_uri(sip_msg_t* _msg, str *_table, str *_ruri, str *_contact) { -+ str ruri = STR_NULL; -+ str contact = STR_NULL; -+ -+ int rc; -+ -+ /* parse R-URI */ -+ if(ts_check_uri(_ruri) < 0) -+ return -1; -+ if (pkg_str_dup(&ruri, _ruri) < 0) -+ return -1; -+ -+ /* parse Contact header */ -+ if (ts_check_uri(_contact) < 0) -+ return -1; -+ if (pkg_str_dup(&contact, _contact) < 0) -+ return -1; -+ -+ /* contact must be of syntax: sip:@: with no parameters list */ -+ rc = ts_append_by_contact(_msg, &ruri, &contact, _table->s); -+ -+ pkg_free(ruri.s); -+ pkg_free(contact.s); -+ -+ return rc; -+} -+ - /** - * - */ -@@ -417,6 +674,16 @@ static sr_kemi_t sr_kemi_tsilo_exports[] = { - { SR_KEMIP_INT, SR_KEMIP_INT, SR_KEMIP_STR, - SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE } - }, -+ { str_init("tsilo"), str_init("ts_append_by_contact"), -+ SR_KEMIP_INT, ki_ts_append_by_contact, -+ { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, -+ SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } -+ }, -+ { str_init("tsilo"), str_init("ts_append_by_contact_uri"), -+ SR_KEMIP_INT, ki_ts_append_by_contact_uri, -+ { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR, -+ SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } -+ }, - - { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } } - }; diff --git a/debian/patches/upstream/tm_api_improvement_t_append_branches_with_contact.patch b/debian/patches/upstream/tm_api_improvement_t_append_branches_with_contact.patch new file mode 100644 index 000000000..503526edf --- /dev/null +++ b/debian/patches/upstream/tm_api_improvement_t_append_branches_with_contact.patch @@ -0,0 +1,617 @@ +From f564c0d33974eeaa1833abeb7972f5d207c5663f Mon Sep 17 00:00:00 2001 +From: Donat Zenichev +Date: Fri, 12 Nov 2021 17:16:37 +0200 +Subject: [PATCH 1/2] tm: API improvement, new function introduced: + t_append_branch_by_contact() + +New module functions introduced: +- t_append_branch_by_contact() + +This commit introduces a possibility of TM's API to append a branch +based on specific location (Contact's URI). + +Indeed the 't_append_branch_by_contact()' is a corrected copy of +the 't_append_branches()', which instead takes Contact as a parameter +of str type. + +The separate function has been introduced, in order to save full +back-compatibility, and not affect existing implementation. +--- + src/modules/tm/t_append_branches.c | 206 +++++++++++++++++++++++++++++ + src/modules/tm/t_append_branches.h | 4 + + src/modules/tm/tm_load.c | 1 + + src/modules/tm/tm_load.h | 1 + + 4 files changed, 212 insertions(+) + +diff --git a/src/modules/tm/t_append_branches.c b/src/modules/tm/t_append_branches.c +index c754a90823..2daca1a593 100644 +--- a/src/modules/tm/t_append_branches.c ++++ b/src/modules/tm/t_append_branches.c +@@ -237,3 +237,209 @@ done: + } + return ret; + } ++ ++/* append a new transaction based on desired Contact hf value ++ * contact parameter must be of syntax (no hf parameters): ++ * sip:@: */ ++int t_append_branch_by_contact(str * contact) { ++ struct cell *t = NULL; ++ struct sip_msg *orig_msg = NULL; ++ struct sip_msg *faked_req; ++ int faked_req_len = 0; ++ ++ short outgoings; ++ ++ int success_branch; ++ ++ str current_uri; ++ str dst_uri, path, instance, ruid, location_ua; ++ struct socket_info* si; ++ int q, i, found, append; ++ flag_t backup_bflags = 0; ++ flag_t bflags = 0; ++ int new_branch, branch_ret, lowest_ret; ++ branch_bm_t added_branches; ++ int replies_locked = 0; ++ int ret = 0; ++ ++ t = get_t(); ++ if(t == NULL) ++ { ++ LM_ERR("cannot get transaction\n"); ++ return -1; ++ } ++ ++ LM_DBG("transaction %u:%u in status %d\n", t->hash_index, t->label, t->uas.status); ++ ++ /* test if transaction has already been canceled */ ++ if (t->flags & T_CANCELED) { ++ ser_error=E_CANCELED; ++ return -1; ++ } ++ ++ if ((t->uas.status >= 200 && t->uas.status<=399) ++ || ((t->uas.status >= 600 && t->uas.status) ++ && !(t->flags & (T_6xx | T_DISABLE_6xx))) ) { ++ LM_DBG("transaction %u:%u in status %d: cannot append new branch\n", ++ t->hash_index, t->label, t->uas.status); ++ return -1; ++ } ++ ++ /* set the lock on the transaction here */ ++ LOCK_REPLIES(t); ++ replies_locked = 1; ++ outgoings = t->nr_of_outgoings; ++ orig_msg = t->uas.request; ++ ++ LM_DBG("Call %.*s: %d (%d) outgoing branches\n",orig_msg->callid->body.len, ++ orig_msg->callid->body.s,outgoings, nr_branches); ++ ++ lowest_ret=E_UNSPEC; ++ added_branches=0; ++ ++ /* it's a "late" branch so the on_branch variable has already been ++ reset by previous execution of t_forward_nonack: we use the saved ++ value */ ++ if (t->on_branch_delayed) { ++ /* tell add_uac that it should run branch route actions */ ++ set_branch_route(t->on_branch_delayed); ++ } ++ faked_req = fake_req(orig_msg, 0, NULL, &faked_req_len); ++ if (faked_req==NULL) { ++ LM_ERR("fake_req failed\n"); ++ return -1; ++ } ++ ++ /* fake also the env. conforming to the fake msg */ ++ faked_env( t, faked_req, 0); ++ ++ /* DONE with faking ;-) -> run the failure handlers */ ++ init_branch_iterator(); ++ ++ while((current_uri.s=next_branch( ¤t_uri.len, &q, &dst_uri, &path, ++ &bflags, &si, &ruid, &instance, &location_ua))) { ++ LM_DBG("Current uri %.*s\n",current_uri.len, current_uri.s); ++ ++ append = 1; ++ if (strstr(current_uri.s, contact->s) == NULL) { ++ append = 0; ++ } ++ ++ /* do not append the branch if a contact does not match */ ++ if (!append) ++ continue; ++ ++ LM_DBG("Branch will be appended for contact <%.*s>\n", contact->len, contact->s); ++ ++ found = 0; ++ for (i=0; iuac[i].ruid.len == ruid.len ++ && !memcmp(t->uac[i].ruid.s, ruid.s, ruid.len) ++ && t->uac[i].uri.len == current_uri.len ++ && !memcmp(t->uac[i].uri.s, current_uri.s, current_uri.len)) { ++ LM_DBG("branch already added [%.*s]\n", ruid.len, ruid.s); ++ found = 1; ++ break; ++ } ++ } ++ if (found) ++ continue; ++ ++ setbflagsval(0, bflags); ++ new_branch=add_uac( t, faked_req, ¤t_uri, ++ (dst_uri.len) ? (&dst_uri) : ¤t_uri, ++ &path, 0, si, faked_req->fwd_send_flags, ++ PROTO_NONE, (dst_uri.len)?0:UAC_SKIP_BR_DST_F, &instance, ++ &ruid, &location_ua); ++ ++ LM_DBG("added branch [%.*s] with ruid [%.*s]\n", ++ current_uri.len, current_uri.s, ruid.len, ruid.s); ++ ++ /* test if cancel was received meanwhile */ ++ if (t->flags & T_CANCELED) goto canceled; ++ ++ if (new_branch>=0) ++ added_branches |= 1<callid->body.len, orig_msg->callid->body.s,outgoings, nr_branches); ++ setbflagsval(0, backup_bflags); ++ ++ /* update message flags, if changed in branch route */ ++ t->uas.request->flags = faked_req->flags; ++ ++ if (added_branches==0) { ++ if(lowest_ret!=E_CFG) ++ LM_ERR("failure to add branches (%d)\n", lowest_ret); ++ ser_error=lowest_ret; ++ ret = lowest_ret; ++ goto done; ++ } ++ ++ ser_error=0; /* clear branch adding errors */ ++ /* send them out now */ ++ success_branch=0; ++ /* since t_append_branch can only be called from REQUEST_ROUTE, always lock replies */ ++ ++ for (i=outgoings; inr_of_outgoings; i++) { ++ if (added_branches & (1<=0){ /* some kind of success */ ++ if (branch_ret==i) { /* success */ ++ success_branch++; ++ if (unlikely(has_tran_tmcbs(t, TMCB_REQUEST_OUT))) ++ run_trans_callbacks_with_buf( TMCB_REQUEST_OUT, ++ &t->uac[nr_branches].request, ++ faked_req, 0, TMCB_NONE_F); ++ } ++ else /* new branch added */ ++ added_branches |= 1<uas.request->flags = faked_req->flags; ++ /* if needed unlock transaction's replies */ ++ /* restore the number of outgoing branches ++ * since new branches have not been completed */ ++ t->nr_of_outgoings = outgoings; ++ ser_error=E_CANCELED; ++ ret = -1; ++done: ++ /* restore original environment and free the fake msg */ ++ faked_env( t, 0, 0); ++ free_faked_req(faked_req, faked_req_len); ++ ++ if (likely(replies_locked)) { ++ replies_locked = 0; ++ UNLOCK_REPLIES(t); ++ } ++ return ret; ++} +\ No newline at end of file +diff --git a/src/modules/tm/t_append_branches.h b/src/modules/tm/t_append_branches.h +index 2e1cbfb38a..a502909fbf 100644 +--- a/src/modules/tm/t_append_branches.h ++++ b/src/modules/tm/t_append_branches.h +@@ -34,4 +34,8 @@ + int t_append_branches(void); + typedef int (*t_append_branches_f)(void); + ++/* append a new transaction based on desired Contact hf value */ ++int t_append_branch_by_contact(str * contact); ++typedef int (*t_append_branch_by_contact_f)(str * contact); ++ + #endif +diff --git a/src/modules/tm/tm_load.c b/src/modules/tm/tm_load.c +index 911be5d917..c6fd305655 100644 +--- a/src/modules/tm/tm_load.c ++++ b/src/modules/tm/tm_load.c +@@ -134,6 +134,7 @@ int load_tm( struct tm_binds *tmb) + tmb->tm_ctx_get = tm_ctx_get; + #endif + tmb->t_append_branches = t_append_branches; ++ tmb->t_append_branch_by_contact = t_append_branch_by_contact; + tmb->t_load_contacts = t_load_contacts; + tmb->t_next_contacts = t_next_contacts; + tmb->set_fr = t_set_fr; +diff --git a/src/modules/tm/tm_load.h b/src/modules/tm/tm_load.h +index a0f3afde00..7ecfd1b5f3 100644 +--- a/src/modules/tm/tm_load.h ++++ b/src/modules/tm/tm_load.h +@@ -117,6 +117,7 @@ struct tm_binds { + void* reserved5; + #endif + t_append_branches_f t_append_branches; ++ t_append_branch_by_contact_f t_append_branch_by_contact; + cmd_function t_load_contacts; + cmd_function t_next_contacts; + tset_fr_f set_fr; +-- +2.25.1 + + +From cb1b78e7bc8d61261e429664c6deb8bb1b4b53d0 Mon Sep 17 00:00:00 2001 +From: Donat Zenichev +Date: Sun, 14 Nov 2021 22:59:58 +0200 +Subject: [PATCH 2/2] tm: merge t_append_branches() and + t_append_branch_by_contact() + +Because the implementation of the functions +'t_append_branches()' and 't_append_branch_by_contact()' is pretty +much the same, it's proposed to merge them into one: +'t_append_branches()' + +The way how the function acts now depends on if the contact +parameter of str type is given or not (empty or not). +If the contact parameter is given, then only a desired location +is meant for appending. If not found in the location table, +an append will not happen for this AOR. + +Otherwise create branches for all existing location records +of this particular AOR. Search for locations is done in the location table. +--- + src/modules/tm/t_append_branches.c | 228 ++++------------------------- + src/modules/tm/t_append_branches.h | 8 +- + src/modules/tm/tm_load.c | 1 - + src/modules/tm/tm_load.h | 1 - + 4 files changed, 28 insertions(+), 210 deletions(-) + +diff --git a/src/modules/tm/t_append_branches.c b/src/modules/tm/t_append_branches.c +index 2daca1a593..203f67a36a 100644 +--- a/src/modules/tm/t_append_branches.c ++++ b/src/modules/tm/t_append_branches.c +@@ -46,7 +46,18 @@ + #include "t_reply.h" + #include "t_append_branches.h" + +-int t_append_branches(void) { ++/* this function can act in two ways: ++ * - first way, create branches for all existing location records ++ * of this particular AOR. Search for locations is done in ++ * the location table. ++ * - second way, if the contact parameter is given, ++ * then only a desired location is meant for appending, ++ * if not found in the location table, an append will not happen ++ * for this AOR. ++ * ++ * If the contact parameter is given, it must be of syntax: ++ * sip:@: (without parameters) */ ++int t_append_branches(str * contact) { + struct cell *t = NULL; + struct sip_msg *orig_msg = NULL; + struct sip_msg *faked_req; +@@ -59,7 +70,7 @@ int t_append_branches(void) { + str current_uri; + str dst_uri, path, instance, ruid, location_ua; + struct socket_info* si; +- int q, i, found; ++ int q, i, found, append; + flag_t backup_bflags = 0; + flag_t bflags = 0; + int new_branch, branch_ret, lowest_ret; +@@ -125,212 +136,25 @@ int t_append_branches(void) { + &bflags, &si, &ruid, &instance, &location_ua))) { + LM_DBG("Current uri %.*s\n",current_uri.len, current_uri.s); + +- found = 0; +- for (i=0; iuac[i].ruid.len == ruid.len +- && !memcmp(t->uac[i].ruid.s, ruid.s, ruid.len) +- && t->uac[i].uri.len == current_uri.len +- && !memcmp(t->uac[i].uri.s, current_uri.s, current_uri.len)) { +- LM_DBG("branch already added [%.*s]\n", ruid.len, ruid.s); +- found = 1; +- break; +- } +- } +- if (found) +- continue; +- +- setbflagsval(0, bflags); +- new_branch=add_uac( t, faked_req, ¤t_uri, +- (dst_uri.len) ? (&dst_uri) : ¤t_uri, +- &path, 0, si, faked_req->fwd_send_flags, +- PROTO_NONE, (dst_uri.len)?0:UAC_SKIP_BR_DST_F, &instance, +- &ruid, &location_ua); +- +- LM_DBG("added branch [%.*s] with ruid [%.*s]\n", +- current_uri.len, current_uri.s, ruid.len, ruid.s); +- +- /* test if cancel was received meanwhile */ +- if (t->flags & T_CANCELED) goto canceled; +- +- if (new_branch>=0) +- added_branches |= 1<callid->body.len, orig_msg->callid->body.s,outgoings, nr_branches); +- setbflagsval(0, backup_bflags); +- +- /* update message flags, if changed in branch route */ +- t->uas.request->flags = faked_req->flags; +- +- if (added_branches==0) { +- if(lowest_ret!=E_CFG) +- LM_ERR("failure to add branches (%d)\n", lowest_ret); +- ser_error=lowest_ret; +- ret = lowest_ret; +- goto done; +- } ++ /* if the contact parameter is given, then append by ++ an exact location that has been requested for this function call */ ++ if (contact->s != NULL && contact->len != 0) { + +- ser_error=0; /* clear branch adding errors */ +- /* send them out now */ +- success_branch=0; +- /* since t_append_branch can only be called from REQUEST_ROUTE, always lock replies */ ++ LM_DBG("Comparing requested contact <%.*s> against location <%.*s>\n", ++ contact->len, contact->s, current_uri.len, current_uri.s); + +- for (i=outgoings; inr_of_outgoings; i++) { +- if (added_branches & (1<=0){ /* some kind of success */ +- if (branch_ret==i) { /* success */ +- success_branch++; +- if (unlikely(has_tran_tmcbs(t, TMCB_REQUEST_OUT))) +- run_trans_callbacks_with_buf( TMCB_REQUEST_OUT, +- &t->uac[nr_branches].request, +- faked_req, 0, TMCB_NONE_F); +- } +- else /* new branch added */ +- added_branches |= 1<s) == NULL) { ++ append = 0; /* this while cycle will be stopped */ + } +- } +- } +- if (success_branch<=0) { +- /* return always E_SEND for now +- * (the real reason could be: denied by onsend routes, blocklisted, +- * send failed or any of the errors listed before + dns failed +- * when attempting dns failover) */ +- ser_error=E_SEND; +- /* else return the last error (?) */ +- ret = -1; +- goto done; +- } +- +- ser_error=0; /* clear branch send errors, we have overall success */ +- set_kr(REQ_FWDED); +- ret = success_branch; +- goto done; +- +-canceled: +- LM_DBG("cannot append branches to a canceled transaction\n"); +- /* reset processed branches */ +- clear_branches(); +- /* restore backup flags from initial env */ +- setbflagsval(0, backup_bflags); +- /* update message flags, if changed in branch route */ +- t->uas.request->flags = faked_req->flags; +- /* if needed unlock transaction's replies */ +- /* restore the number of outgoing branches +- * since new branches have not been completed */ +- t->nr_of_outgoings = outgoings; +- ser_error=E_CANCELED; +- ret = -1; +-done: +- /* restore original environment and free the fake msg */ +- faked_env( t, 0, 0); +- free_faked_req(faked_req, faked_req_len); +- +- if (likely(replies_locked)) { +- replies_locked = 0; +- UNLOCK_REPLIES(t); +- } +- return ret; +-} +- +-/* append a new transaction based on desired Contact hf value +- * contact parameter must be of syntax (no hf parameters): +- * sip:@: */ +-int t_append_branch_by_contact(str * contact) { +- struct cell *t = NULL; +- struct sip_msg *orig_msg = NULL; +- struct sip_msg *faked_req; +- int faked_req_len = 0; +- +- short outgoings; +- +- int success_branch; +- +- str current_uri; +- str dst_uri, path, instance, ruid, location_ua; +- struct socket_info* si; +- int q, i, found, append; +- flag_t backup_bflags = 0; +- flag_t bflags = 0; +- int new_branch, branch_ret, lowest_ret; +- branch_bm_t added_branches; +- int replies_locked = 0; +- int ret = 0; +- +- t = get_t(); +- if(t == NULL) +- { +- LM_ERR("cannot get transaction\n"); +- return -1; +- } +- +- LM_DBG("transaction %u:%u in status %d\n", t->hash_index, t->label, t->uas.status); +- +- /* test if transaction has already been canceled */ +- if (t->flags & T_CANCELED) { +- ser_error=E_CANCELED; +- return -1; +- } +- +- if ((t->uas.status >= 200 && t->uas.status<=399) +- || ((t->uas.status >= 600 && t->uas.status) +- && !(t->flags & (T_6xx | T_DISABLE_6xx))) ) { +- LM_DBG("transaction %u:%u in status %d: cannot append new branch\n", +- t->hash_index, t->label, t->uas.status); +- return -1; +- } +- +- /* set the lock on the transaction here */ +- LOCK_REPLIES(t); +- replies_locked = 1; +- outgoings = t->nr_of_outgoings; +- orig_msg = t->uas.request; +- +- LM_DBG("Call %.*s: %d (%d) outgoing branches\n",orig_msg->callid->body.len, +- orig_msg->callid->body.s,outgoings, nr_branches); +- +- lowest_ret=E_UNSPEC; +- added_branches=0; +- +- /* it's a "late" branch so the on_branch variable has already been +- reset by previous execution of t_forward_nonack: we use the saved +- value */ +- if (t->on_branch_delayed) { +- /* tell add_uac that it should run branch route actions */ +- set_branch_route(t->on_branch_delayed); +- } +- faked_req = fake_req(orig_msg, 0, NULL, &faked_req_len); +- if (faked_req==NULL) { +- LM_ERR("fake_req failed\n"); +- return -1; +- } +- +- /* fake also the env. conforming to the fake msg */ +- faked_env( t, faked_req, 0); +- +- /* DONE with faking ;-) -> run the failure handlers */ +- init_branch_iterator(); + +- while((current_uri.s=next_branch( ¤t_uri.len, &q, &dst_uri, &path, +- &bflags, &si, &ruid, &instance, &location_ua))) { +- LM_DBG("Current uri %.*s\n",current_uri.len, current_uri.s); ++ /* do not append the branch if a contact does not match */ ++ if (!append) ++ continue; + +- append = 1; +- if (strstr(current_uri.s, contact->s) == NULL) { +- append = 0; ++ LM_DBG("Branch will be appended for contact <%.*s>\n", contact->len, contact->s); + } + +- /* do not append the branch if a contact does not match */ +- if (!append) +- continue; +- +- LM_DBG("Branch will be appended for contact <%.*s>\n", contact->len, contact->s); +- + found = 0; + for (i=0; iuac[i].ruid.len == ruid.len +@@ -442,4 +266,4 @@ done: + UNLOCK_REPLIES(t); + } + return ret; +-} +\ No newline at end of file ++} +diff --git a/src/modules/tm/t_append_branches.h b/src/modules/tm/t_append_branches.h +index a502909fbf..1baec4acd0 100644 +--- a/src/modules/tm/t_append_branches.h ++++ b/src/modules/tm/t_append_branches.h +@@ -31,11 +31,7 @@ + #include "../../core/proxy.h" + #include "h_table.h" + +-int t_append_branches(void); +-typedef int (*t_append_branches_f)(void); +- +-/* append a new transaction based on desired Contact hf value */ +-int t_append_branch_by_contact(str * contact); +-typedef int (*t_append_branch_by_contact_f)(str * contact); ++int t_append_branches(str * contact); ++typedef int (*t_append_branches_f)(str * contact); + + #endif +diff --git a/src/modules/tm/tm_load.c b/src/modules/tm/tm_load.c +index c6fd305655..911be5d917 100644 +--- a/src/modules/tm/tm_load.c ++++ b/src/modules/tm/tm_load.c +@@ -134,7 +134,6 @@ int load_tm( struct tm_binds *tmb) + tmb->tm_ctx_get = tm_ctx_get; + #endif + tmb->t_append_branches = t_append_branches; +- tmb->t_append_branch_by_contact = t_append_branch_by_contact; + tmb->t_load_contacts = t_load_contacts; + tmb->t_next_contacts = t_next_contacts; + tmb->set_fr = t_set_fr; +diff --git a/src/modules/tm/tm_load.h b/src/modules/tm/tm_load.h +index 7ecfd1b5f3..a0f3afde00 100644 +--- a/src/modules/tm/tm_load.h ++++ b/src/modules/tm/tm_load.h +@@ -117,7 +117,6 @@ struct tm_binds { + void* reserved5; + #endif + t_append_branches_f t_append_branches; +- t_append_branch_by_contact_f t_append_branch_by_contact; + cmd_function t_load_contacts; + cmd_function t_next_contacts; + tset_fr_f set_fr; +-- +2.25.1 + diff --git a/debian/patches/upstream/tsilo_append_by_contact.patch b/debian/patches/upstream/tsilo_append_by_contact.patch new file mode 100644 index 000000000..eb962b1a3 --- /dev/null +++ b/debian/patches/upstream/tsilo_append_by_contact.patch @@ -0,0 +1,1051 @@ +From 7265f1cf7c57d258538119bc0d41146a04183eec Mon Sep 17 00:00:00 2001 +From: Donat Zenichev +Date: Fri, 12 Nov 2021 15:30:44 +0200 +Subject: [PATCH] tsilo: Add support of a lookup and branch creating by contact + +Improvement of the TSILO module, which allows to run a lookup using the provided RURI, +but only to create a new branch for the Contact, which is set in the currently processed REGISTER. +Or optionally a Contact URI value given as a parameter to the function. +If the Contact URI for a lookup, is given as a parameter, +it is possible to provide it as a pseudo-variable. + +Hence it is now possible to append new branch(es) for only UAC(s) +getting REGISTERED at the moment of calling 'ts_append_by_contact()'. + +Previously it was only possible to call 'ts_append()' and create new branches +for all previously present location records (for this specific URI), which was in some circumstsances undersired. + +New script functions introduced: +- ts_append_by_contact(table, ruri [, contact]) + +New module functions introduced: +- w_ts_append_by_contact2() / ki_ts_append_by_contact() +- w_ts_append_by_contact3 / ki_ts_append_by_contact_uri() +- ts_append_by_contact() / ts_append_by_contact_to() + +Backwards compatibility is saved, the new functionality is not overlapping with +the previously existing implementation, hence it only acts when the new script function +ts_append_by_contact() is used. + +The documentation has been updated accordingly. +--- + src/modules/tsilo/doc/tsilo.xml | 5 + + src/modules/tsilo/doc/tsilo_admin.xml | 54 ++++++ + src/modules/tsilo/ts_append.c | 116 +++++++++++ + src/modules/tsilo/ts_append.h | 2 + + src/modules/tsilo/tsilo.c | 269 +++++++++++++++++++++++++- + 5 files changed, 445 insertions(+), 1 deletion(-) + +diff --git a/src/modules/tsilo/doc/tsilo.xml b/src/modules/tsilo/doc/tsilo.xml +index 6a2be7b0e7..1ad967ae64 100644 +--- a/src/modules/tsilo/doc/tsilo.xml ++++ b/src/modules/tsilo/doc/tsilo.xml +@@ -23,6 +23,11 @@ + Cabiddu + federico.cabiddu@gmail.com + ++ ++ Donat ++ Zenichev ++ dzenichev@sipwise.com ++ + + + 2015 +diff --git a/src/modules/tsilo/doc/tsilo_admin.xml b/src/modules/tsilo/doc/tsilo_admin.xml +index c294e7c282..965c339156 100644 +--- a/src/modules/tsilo/doc/tsilo_admin.xml ++++ b/src/modules/tsilo/doc/tsilo_admin.xml +@@ -181,6 +181,60 @@ if (is_method("REGISTER")) { + ts_append("location", "$tu"); + } + ... ++ ++ ++ ++
++ <function moreinfo="none">ts_append_by_contact(domain, ruri [, contact])</function> ++ ++ Has almost the same intention as the ts_append(), ++ but gives a possibility to append branches ++ only for a specific location record (Contact URI). ++ The contact's URI value can be either taken from the currently processed REGISTER ++ or (optionally) given as a third parameter. ++ If the Contact URI for a lookup is given as the parameter, ++ it is possible to provide it as a pseudo-variable. ++ ++ The contact lookup is performed on the table specified by the domain parameter. ++ The method should be called when a REGISTER request is received. ++ ++ Meaning of the parameters is as follows: ++ ++ ++ ++ domain - Name of table that should be used for looking ++ up new contacts for r-uri. ++ ++ ++ ++ ++ ruri - The r-uri for which we want to check existing ++ transactions and add them new branches. Can be a static string value or a ++ dynamic string with pseudo-variables. ++ ++ ++ ++ ++ contact - Optional, a value of the location record ++ (contact URI) based on which to perform the branch appending. ++ If not given, the value will be taken from the currently processed REGISTER. ++ If a location lookup based on this Contact URI fails (no location record found), ++ then the branch append will not happen. ++ ++ ++ ++ ++ This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. ++ ++ ++ <function>ts_append_by_contact</function> usage ++ ++... ++if (is_method("REGISTER")) { ++ $var(formated_ct) = $(x_hdr(Contact){nameaddr.uri}); ++ ts_append_by_contact("location", "$tu", "$var(formated_ct)"); ++} ++... + + +
+diff --git a/src/modules/tsilo/ts_append.c b/src/modules/tsilo/ts_append.c +index 7d951865f0..1847ac1c1b 100644 +--- a/src/modules/tsilo/ts_append.c ++++ b/src/modules/tsilo/ts_append.c +@@ -139,3 +139,119 @@ done: + + return ret; + } ++ ++int ts_append_by_contact(struct sip_msg* msg, str *ruri, str *contact, char *table) { ++ ts_urecord_t* _r; ++ ts_transaction_t* ptr; ++ ++ struct sip_uri p_uri; ++ struct sip_uri c_uri; ++ str *t_uri; ++ ++ int res; ++ int appended; ++ ++ /* parse R-URI */ ++ if (use_domain) { ++ t_uri = ruri; ++ } else { ++ if (parse_uri(ruri->s, ruri->len, &p_uri) < 0) { ++ LM_ERR("tsilo: failed to parse uri %.*s\n", ruri->len, ruri->s); ++ return -1; ++ } ++ t_uri = &p_uri.user; ++ } ++ ++ /* parse contact */ ++ if (parse_uri(contact->s, contact->len, &c_uri) < 0) { ++ LM_ERR("tsilo: failed to parse contact %.*s\n", ruri->len, ruri->s); ++ return -1; ++ } ++ ++ /* find urecord in TSILO cache */ ++ lock_entry_by_ruri(t_uri); ++ res = get_ts_urecord(t_uri, &_r); ++ ++ if (res != 0) { ++ LM_ERR("tsilo: failed to retrieve record for %.*s\n", t_uri->len, t_uri->s); ++ unlock_entry_by_ruri(t_uri); ++ return -1; ++ } ++ ++ /* cycle through existing transactions */ ++ ptr = _r->transactions; ++ while(ptr) { ++ LM_DBG("tsilo: transaction %u:%u found for %.*s, going to append branches\n", ++ ptr->tindex, ptr->tlabel, t_uri->len, t_uri->s); ++ /* append only if the desired contact has been found in locations */ ++ appended = ts_append_by_contact_to(msg, ptr->tindex, ptr->tlabel, table, ruri, contact); ++ if (appended > 0) ++ update_stat(added_branches, appended); ++ ptr = ptr->next; ++ } ++ ++ unlock_entry_by_ruri(t_uri); ++ ++ return 1; ++} ++ ++int ts_append_by_contact_to(struct sip_msg* msg, int tindex, int tlabel, char *table, str *uri, str *contact) { ++ struct cell *t=0; ++ struct cell *orig_t; /* a pointer to an existing transaction or 0 if lookup fails*/ ++ struct sip_msg *orig_msg; ++ int ret; ++ str stable; ++ ++ LM_DBG("tsilo: trying to append based on contact <%.*s>\n", contact->len, contact->s); ++ ++ /* lookup a transaction based on its identifier (hash_index:label) */ ++ orig_t = _tmb.t_gett(); ++ if(_tmb.t_lookup_ident(&t, tindex, tlabel) < 0) ++ { ++ LM_ERR("tsilo: transaction [%u:%u] not found\n", tindex, tlabel); ++ ret = -1; ++ goto done; ++ } ++ ++ /* check if the dialog is still in the early stage */ ++ if (t->flags & T_CANCELED) { ++ LM_DBG("tsilo: trasaction [%u:%u] was cancelled\n", tindex, tlabel); ++ ret = -2; ++ goto done; ++ } ++ if (t->uas.status >= 200) { ++ LM_DBG("tsilo: trasaction [%u:%u] sent out a final response already - %d\n", ++ tindex, tlabel, t->uas.status); ++ ret = -3; ++ goto done; ++ } ++ ++ /* get original (very first) request of the transaction */ ++ orig_msg = t->uas.request; ++ stable.s = table; ++ stable.len = strlen(stable.s); ++ ++ if(uri==NULL || uri->s==NULL || uri->len<=0) { ++ ret = _regapi.lookup_to_dset(orig_msg, &stable, NULL); ++ } else { ++ ret = _regapi.lookup_to_dset(orig_msg, &stable, uri); ++ } ++ ++ if(ret != 1) { ++ LM_ERR("tsilo: transaction %u:%u: error updating dset (%d)\n", tindex, tlabel, ret); ++ ret = -4; ++ goto done; ++ } ++ ++ /* start the transaction only for the desired contact ++ contact must be of syntax: sip:@: with no parameters list*/ ++ ret = _tmb.t_append_branch_by_contact(contact); ++ ++done: ++ /* unref the transaction which had been referred by t_lookup_ident() call. ++ * Restore the original transaction (if any) */ ++ if(t) _tmb.unref_cell(t); ++ _tmb.t_sett(orig_t, T_BR_UNDEFINED); ++ ++ return ret; ++} +diff --git a/src/modules/tsilo/ts_append.h b/src/modules/tsilo/ts_append.h +index 56f91204df..461f8881f3 100644 +--- a/src/modules/tsilo/ts_append.h ++++ b/src/modules/tsilo/ts_append.h +@@ -24,5 +24,7 @@ + + int ts_append(struct sip_msg* msg, str *ruri, char *table); + int ts_append_to(struct sip_msg* msg, int tindex, int tlabel, char *table, str *uri); ++int ts_append_by_contact(struct sip_msg* msg, str *ruri, str *contact, char *table); ++int ts_append_by_contact_to(struct sip_msg* msg, int tindex, int tlabel, char *table, str *uri, str *contact); + + #endif +diff --git a/src/modules/tsilo/tsilo.c b/src/modules/tsilo/tsilo.c +index 0c531acc74..2eefb2fe2d 100644 +--- a/src/modules/tsilo/tsilo.c ++++ b/src/modules/tsilo/tsilo.c +@@ -34,6 +34,8 @@ + #include "../../core/rpc_lookup.h" + #include "../../core/kemi.h" + ++#include "../../core/parser/contact/parse_contact.h" ++ + #include "ts_hash.h" + #include "ts_handlers.h" + #include "ts_append.h" +@@ -61,7 +63,9 @@ static int w_ts_append_to2(struct sip_msg* msg, char *idx, char *lbl, char *d, c + static int fixup_ts_append_to(void** param, int param_no); + static int w_ts_append(struct sip_msg* _msg, char *_table, char *_ruri); + static int fixup_ts_append(void** param, int param_no); +- ++static int w_ts_append_by_contact2(struct sip_msg* _msg, char *_table, char *_ruri); ++static int w_ts_append_by_contact3(struct sip_msg* _msg, char *_table, char *_ruri, char *_contact); ++static int fixup_ts_append_by_contact(void** param, int param_no); + static int w_ts_store(struct sip_msg* msg, char *p1, char *p2); + static int w_ts_store1(struct sip_msg* msg, char *_ruri, char *p2); + +@@ -78,6 +82,10 @@ static cmd_export_t cmds[]={ + fixup_ts_append_to, 0, REQUEST_ROUTE | FAILURE_ROUTE }, + {"ts_append", (cmd_function)w_ts_append, 2, + fixup_ts_append, 0, REQUEST_ROUTE | FAILURE_ROUTE }, ++ {"ts_append_by_contact", (cmd_function)w_ts_append_by_contact2, 2, /* for two parameters */ ++ fixup_ts_append_by_contact, 0, REQUEST_ROUTE | FAILURE_ROUTE }, ++ {"ts_append_by_contact", (cmd_function)w_ts_append_by_contact3, 3, /* for three parameters */ ++ fixup_ts_append_by_contact, 0, REQUEST_ROUTE | FAILURE_ROUTE }, + {"ts_store", (cmd_function)w_ts_store, 0, + 0 , 0, REQUEST_ROUTE | FAILURE_ROUTE }, + {"ts_store", (cmd_function)w_ts_store1, 1, +@@ -241,6 +249,23 @@ static int fixup_ts_append(void** param, int param_no) + return 0; + } + ++static int fixup_ts_append_by_contact(void** param, int param_no) ++{ ++ if (param_no==1) { ++ if(strlen((char*)*param)<=1 && (*(char*)(*param)==0 || *(char*)(*param)=='0')) { ++ *param = (void*)0; ++ LM_ERR("empty table name\n"); ++ return -1; ++ } ++ } ++ ++ if (param_no==2 || param_no==3) { ++ return fixup_spve_null(param, 1); ++ } ++ ++ return 0; ++} ++ + /** + * + */ +@@ -357,6 +382,238 @@ static int ki_ts_append_to_uri(sip_msg_t* _msg, int tindex, int tlabel, + _table->s, _uri); + } + ++/** ++ * ++ */ ++static int w_ts_append_by_contact2(struct sip_msg* _msg, char *_table, char *_ruri) { ++ str ruri = STR_NULL; ++ str ruri_fixed = STR_NULL; ++ ++ str contact = STR_NULL; ++ str tmp_contact = STR_NULL; ++ struct sip_uri curi; ++ ++ int rc; ++ ++ /* parse R-URI */ ++ if (fixup_get_svalue(_msg, (gparam_t*)_ruri, &ruri_fixed)!=0) { ++ LM_ERR("failed to convert r-uri parameter\n"); ++ return -1; ++ } ++ ++ if (_ruri==NULL || strlen(_ruri) <= 0 || ruri_fixed.len <= 0) { ++ LM_ERR("tsilo: invalid ruri parameter (empty or zero length).\n"); ++ return -1; ++ } ++ ++ if (pkg_str_dup(&ruri, &ruri_fixed) < 0) { ++ LM_ERR("failed to copy r-uri parameter\n"); ++ return -1; ++ } ++ ++ if (ts_check_uri(&ruri) < 0) { ++ LM_ERR("tsilo: failed to parse R-URI.\n"); ++ return -1; ++ } ++ ++ /* parse Contact header */ ++ if ((!_msg->contact && parse_headers(_msg, HDR_CONTACT_F, 0) != 0) ++ || !_msg->contact) { ++ LM_WARN("tsilo: missing contact header or the value is empty/malformed.\n"); ++ return -1; ++ } ++ if (_msg->contact) { ++ if (parse_contact(_msg->contact) < 0) { ++ LM_WARN("tsilo: failed to parse Contact header.\n"); ++ return -1; ++ } ++ if (parse_uri( ++ ((struct contact_body*)_msg->contact->parsed)->contacts->uri.s, ++ ((struct contact_body*)_msg->contact->parsed)->contacts->uri.len, ++ &curi) != 0 ) { ++ if (ts_check_uri(&_msg->contact->body) < 0) { /* one more attempt */ ++ LM_WARN("tsilo: failed to parse Contact header.\n"); ++ return -1; ++ } ++ } ++ ++ tmp_contact.len = ((struct contact_body*)_msg->contact->parsed)->contacts->uri.len; ++ tmp_contact.s = (char*)pkg_malloc(tmp_contact.len+1); ++ if (tmp_contact.s == NULL) { ++ PKG_MEM_ERROR; ++ return -1; ++ } ++ memcpy(tmp_contact.s, ((struct contact_body*)_msg->contact->parsed)->contacts->uri.s, tmp_contact.len); ++ tmp_contact.s[tmp_contact.len] = '\0'; ++ ++ if (pkg_str_dup(&contact, &tmp_contact) < 0) { ++ if (pkg_str_dup(&contact, &_msg->contact->body) < 0) { /* one more attempt */ ++ LM_ERR("tsilo: problems when calling ts_append_contact(), cannot copy Contact parameter.\n"); ++ return -1; ++ } ++ } ++ } ++ ++ /* contact must be of syntax: sip:@: with no parameters list */ ++ rc = ts_append_by_contact(_msg, &ruri, &contact, _table); ++ ++ /* free previously used memory */ ++ pkg_free(ruri.s); ++ pkg_free(contact.s); ++ pkg_free(tmp_contact.s); ++ ++ return rc; ++} ++ ++/** ++ * ++ */ ++static int ki_ts_append_by_contact(sip_msg_t* _msg, str *_table, str *_ruri) { ++ str ruri = STR_NULL; ++ str contact = STR_NULL; ++ str tmp_contact = STR_NULL; ++ struct sip_uri curi; ++ int rc; ++ ++ /* parse R-URI */ ++ if (ts_check_uri(_ruri) < 0) ++ return -1; ++ if (pkg_str_dup(&ruri, _ruri) < 0) ++ return -1; ++ ++ /* parse Contact header */ ++ if ((!_msg->contact && parse_headers(_msg, HDR_CONTACT_F, 0) != 0) || !_msg->contact) ++ return -1; ++ ++ if (_msg->contact) { ++ if (parse_contact(_msg->contact) < 0) ++ return -1; ++ if (parse_uri( ++ ((struct contact_body*)_msg->contact->parsed)->contacts->uri.s, ++ ((struct contact_body*)_msg->contact->parsed)->contacts->uri.len, ++ &curi) != 0 ) { ++ if (ts_check_uri(&_msg->contact->body) < 0) /* one more attempt */ ++ return -1; ++ } ++ ++ tmp_contact.len = ((struct contact_body*)_msg->contact->parsed)->contacts->uri.len; ++ tmp_contact.s = (char*)pkg_malloc(tmp_contact.len+1); ++ if (tmp_contact.s == NULL) { ++ PKG_MEM_ERROR; ++ return -1; ++ } ++ memcpy(tmp_contact.s, ((struct contact_body*)_msg->contact->parsed)->contacts->uri.s, tmp_contact.len); ++ tmp_contact.s[tmp_contact.len] = '\0'; ++ ++ if (pkg_str_dup(&contact, &tmp_contact) < 0) { ++ if (pkg_str_dup(&contact, &_msg->contact->body) < 0) /* one more attempt */ ++ return -1; ++ } ++ } ++ ++ /* contact must be of syntax: sip:@: with no parameters list */ ++ rc = ts_append_by_contact(_msg, &ruri, &contact, _table->s); ++ ++ pkg_free(ruri.s); ++ pkg_free(contact.s); ++ pkg_free(tmp_contact.s); ++ ++ return rc; ++} ++ ++/** ++ * ++ */ ++static int w_ts_append_by_contact3(struct sip_msg* _msg, char *_table, char *_ruri, char *_contact) { ++ str ruri = STR_NULL; ++ str ruri_fixed = STR_NULL; ++ ++ str contact = STR_NULL; ++ str contact_fixed = STR_NULL; ++ ++ int rc; ++ ++ /* parse R-URI */ ++ if (fixup_get_svalue(_msg, (gparam_t*)_ruri, &ruri_fixed)!=0) { ++ LM_ERR("failed to convert r-uri parameter\n"); ++ return -1; ++ } ++ ++ if (_ruri==NULL || strlen(_ruri) <= 0 || ruri_fixed.len <= 0) { ++ LM_ERR("tsilo: invalid ruri parameter.\n"); ++ return -1; ++ } ++ ++ if (pkg_str_dup(&ruri, &ruri_fixed) < 0) { ++ LM_ERR("failed to copy r-uri parameter\n"); ++ return -1; ++ } ++ ++ if (ts_check_uri(&ruri) < 0) { ++ LM_ERR("tsilo: failed to parse R-URI.\n"); ++ return -1; ++ } ++ ++ /* parse Contact header */ ++ if (fixup_get_svalue(_msg, (gparam_t*)_contact, &contact_fixed)!=0) { ++ LM_ERR("failed to convert contact parameter\n"); ++ return -1; ++ } ++ ++ if (_contact==NULL || strlen(_contact) <= 0 || contact_fixed.len <= 0) { ++ LM_ERR("tsilo: invalid contact parameter.\n"); ++ return -1; ++ } ++ ++ if (pkg_str_dup(&contact, &contact_fixed) < 0) { ++ LM_ERR("failed to copy r-uri parameter\n"); ++ return -1; ++ } ++ ++ if (ts_check_uri(&contact) < 0) { ++ LM_ERR("tsilo: failed to parse Contact parameter.\n"); ++ return -1; ++ } ++ ++ /* contact must be of syntax: sip:@: with no parameters list */ ++ rc = ts_append_by_contact(_msg, &ruri, &contact, _table); ++ ++ pkg_free(ruri.s); ++ pkg_free(contact.s); ++ ++ return rc; ++} ++ ++/** ++ * ++ */ ++static int ki_ts_append_by_contact_uri(sip_msg_t* _msg, str *_table, str *_ruri, str *_contact) { ++ str ruri = STR_NULL; ++ str contact = STR_NULL; ++ ++ int rc; ++ ++ /* parse R-URI */ ++ if(ts_check_uri(_ruri) < 0) ++ return -1; ++ if (pkg_str_dup(&ruri, _ruri) < 0) ++ return -1; ++ ++ /* parse Contact header */ ++ if (ts_check_uri(_contact) < 0) ++ return -1; ++ if (pkg_str_dup(&contact, _contact) < 0) ++ return -1; ++ ++ /* contact must be of syntax: sip:@: with no parameters list */ ++ rc = ts_append_by_contact(_msg, &ruri, &contact, _table->s); ++ ++ pkg_free(ruri.s); ++ pkg_free(contact.s); ++ ++ return rc; ++} ++ + /** + * + */ +@@ -417,6 +674,16 @@ static sr_kemi_t sr_kemi_tsilo_exports[] = { + { SR_KEMIP_INT, SR_KEMIP_INT, SR_KEMIP_STR, + SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, ++ { str_init("tsilo"), str_init("ts_append_by_contact"), ++ SR_KEMIP_INT, ki_ts_append_by_contact, ++ { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, ++ SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } ++ }, ++ { str_init("tsilo"), str_init("ts_append_by_contact_uri"), ++ SR_KEMIP_INT, ki_ts_append_by_contact_uri, ++ { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR, ++ SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } ++ }, + + { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } } + }; +-- +2.25.1 + +From 474649171d3c269e2fcfb00c7b1dbd318a952f51 Mon Sep 17 00:00:00 2001 +From: Donat Zenichev +Date: Sun, 14 Nov 2021 23:13:15 +0200 +Subject: [PATCH] tsilo: Be compliant with changes in TM, now only + t_append_branches() + +Since of changes in TM's module, where 't_append_branches()' and +'t_append_branch_by_contact()' have been merged into one function, +we need to edit all the occurences where TM's API is called +in TSILO. + +No logic changes. +--- + src/modules/tsilo/ts_append.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/modules/tsilo/ts_append.c b/src/modules/tsilo/ts_append.c +index 1847ac1c1b..e4967f8167 100644 +--- a/src/modules/tsilo/ts_append.c ++++ b/src/modules/tsilo/ts_append.c +@@ -89,6 +89,10 @@ int ts_append_to(struct sip_msg* msg, int tindex, int tlabel, char *table, str * + int ret; + str stable; + ++ str contact; /* needed for usage of TM's API, t_append_branches() */ ++ contact.s = NULL; /* must be emptied */ ++ contact.len = 0; ++ + orig_t = _tmb.t_gett(); + + if(_tmb.t_lookup_ident(&t, tindex, tlabel) < 0) +@@ -129,7 +133,7 @@ int ts_append_to(struct sip_msg* msg, int tindex, int tlabel, char *table, str * + goto done; + } + +- ret = _tmb.t_append_branches(); ++ ret = _tmb.t_append_branches(&contact); + + done: + /* unref the transaction which had been referred by t_lookup_ident() call. +@@ -245,7 +249,7 @@ int ts_append_by_contact_to(struct sip_msg* msg, int tindex, int tlabel, char *t + + /* start the transaction only for the desired contact + contact must be of syntax: sip:@: with no parameters list*/ +- ret = _tmb.t_append_branch_by_contact(contact); ++ ret = _tmb.t_append_branches(contact); + + done: + /* unref the transaction which had been referred by t_lookup_ident() call. +-- +2.25.1 + +From c1fd9ebaa0fe0eb7457ea74e8a22444b855af9cd Mon Sep 17 00:00:00 2001 +From: Donat Zenichev +Date: Wed, 17 Nov 2021 16:27:37 +0200 +Subject: [PATCH] tsilo: Merge similar functions in ts_append.c + +We need to merge similar functions in ts_append.c implementation +to give less work for maintaining similar code. +Furthermore the purpose of them is quite the same, +but differes just in some details (usage of TM's API). + +Merged functions are: +- ts_append() and ts_append_by_contact() +- ts_append_to() and ts_append_by_contact_to() + +Now all appending in TSILO happens only through ts_append() / ts_append_to() +An implementation in tsilo.c has been updated accordingly. + +Usage. +In case we do not want to append based on specific Contact (location), +the contact parameter being passed to either ts_append() or ts_append_to() +must be set to zero. +In case we do want to append by a specific Contact, then we must +set the Contact parameter of str type beforehand calling ts_append() / ts_append_to(). +--- + src/modules/tsilo/ts_append.c | 154 ++++++---------------------------- + src/modules/tsilo/ts_append.h | 6 +- + src/modules/tsilo/tsilo.c | 42 +++++++--- + 3 files changed, 61 insertions(+), 141 deletions(-) + +diff --git a/src/modules/tsilo/ts_append.c b/src/modules/tsilo/ts_append.c +index e4967f8167..2781deffc4 100644 +--- a/src/modules/tsilo/ts_append.c ++++ b/src/modules/tsilo/ts_append.c +@@ -36,26 +36,37 @@ + #include "ts_hash.h" + #include "ts_append.h" + +-int ts_append(struct sip_msg* msg, str *ruri, char *table) { ++int ts_append(struct sip_msg* msg, str *ruri, str *contact, char *table) { + ts_urecord_t* _r; + ts_transaction_t* ptr; + + struct sip_uri p_uri; ++ struct sip_uri c_uri; + str *t_uri; + + int res; + int appended; +- ++ ++ /* parse R-URI */ + if (use_domain) { + t_uri = ruri; + } else { +- if(parse_uri(ruri->s, ruri->len, &p_uri)<0) { ++ if(parse_uri(ruri->s, ruri->len, &p_uri) < 0) { + LM_ERR("failed to parse uri %.*s\n", ruri->len, ruri->s); + return -1; + } + t_uri = &p_uri.user; + } + ++ /* parse contact if given */ ++ if(contact->s != NULL && contact->len != 0) { ++ if (parse_uri(contact->s, contact->len, &c_uri) < 0) { ++ LM_ERR("failed to parse contact %.*s\n", ruri->len, ruri->s); ++ return -1; ++ } ++ } ++ ++ /* find urecord in TSILO cache */ + lock_entry_by_ruri(t_uri); + + res = get_ts_urecord(t_uri, &_r); +@@ -66,12 +77,13 @@ int ts_append(struct sip_msg* msg, str *ruri, char *table) { + return -1; + } + ++ /* cycle through existing transactions */ + ptr = _r->transactions; + + while(ptr) { + LM_DBG("transaction %u:%u found for %.*s, going to append branches\n",ptr->tindex, ptr->tlabel, t_uri->len, t_uri->s); + +- appended = ts_append_to(msg, ptr->tindex, ptr->tlabel, table, ruri); ++ appended = ts_append_to(msg, ptr->tindex, ptr->tlabel, table, ruri, contact); + if (appended > 0) + update_stat(added_branches, appended); + ptr = ptr->next; +@@ -82,27 +94,28 @@ int ts_append(struct sip_msg* msg, str *ruri, char *table) { + return 1; + } + +-int ts_append_to(struct sip_msg* msg, int tindex, int tlabel, char *table, str *uri) { ++int ts_append_to(struct sip_msg* msg, int tindex, int tlabel, char *table, str *uri, str *contact) { + struct cell *t=0; +- struct cell *orig_t; ++ struct cell *orig_t; /* a pointer to an existing transaction or 0 if lookup fails */ + struct sip_msg *orig_msg; + int ret; + str stable; + +- str contact; /* needed for usage of TM's API, t_append_branches() */ +- contact.s = NULL; /* must be emptied */ +- contact.len = 0; ++ if(contact->s!=NULL && contact->len > 0) { ++ LM_DBG("trying to append based on specific contact <%.*s>\n", contact->len, contact->s); ++ } + ++ /* lookup a transaction based on its identifier (hash_index:label) */ + orig_t = _tmb.t_gett(); + + if(_tmb.t_lookup_ident(&t, tindex, tlabel) < 0) + { +- LM_ERR("transaction [%u:%u] not found\n", +- tindex, tlabel); ++ LM_ERR("transaction [%u:%u] not found\n", tindex, tlabel); + ret = -1; + goto done; + } + ++ /* check if the dialog is still in the early stage */ + if (t->flags & T_CANCELED) { + LM_DBG("trasaction [%u:%u] was cancelled\n", + tindex, tlabel); +@@ -117,119 +130,6 @@ int ts_append_to(struct sip_msg* msg, int tindex, int tlabel, char *table, str * + goto done; + } + +- orig_msg = t->uas.request; +- +- stable.s = table; +- stable.len = strlen(stable.s); +- if(uri==NULL || uri->s==NULL || uri->len<=0) { +- ret = _regapi.lookup_to_dset(orig_msg, &stable, NULL); +- } else { +- ret = _regapi.lookup_to_dset(orig_msg, &stable, uri); +- } +- +- if(ret != 1) { +- LM_DBG("transaction %u:%u: error updating dset (%d)\n", tindex, tlabel, ret); +- ret = -4; +- goto done; +- } +- +- ret = _tmb.t_append_branches(&contact); +- +-done: +- /* unref the transaction which had been referred by t_lookup_ident() call. +- * Restore the original transaction (if any) */ +- if(t) _tmb.unref_cell(t); +- _tmb.t_sett(orig_t, T_BR_UNDEFINED); +- +- return ret; +-} +- +-int ts_append_by_contact(struct sip_msg* msg, str *ruri, str *contact, char *table) { +- ts_urecord_t* _r; +- ts_transaction_t* ptr; +- +- struct sip_uri p_uri; +- struct sip_uri c_uri; +- str *t_uri; +- +- int res; +- int appended; +- +- /* parse R-URI */ +- if (use_domain) { +- t_uri = ruri; +- } else { +- if (parse_uri(ruri->s, ruri->len, &p_uri) < 0) { +- LM_ERR("tsilo: failed to parse uri %.*s\n", ruri->len, ruri->s); +- return -1; +- } +- t_uri = &p_uri.user; +- } +- +- /* parse contact */ +- if (parse_uri(contact->s, contact->len, &c_uri) < 0) { +- LM_ERR("tsilo: failed to parse contact %.*s\n", ruri->len, ruri->s); +- return -1; +- } +- +- /* find urecord in TSILO cache */ +- lock_entry_by_ruri(t_uri); +- res = get_ts_urecord(t_uri, &_r); +- +- if (res != 0) { +- LM_ERR("tsilo: failed to retrieve record for %.*s\n", t_uri->len, t_uri->s); +- unlock_entry_by_ruri(t_uri); +- return -1; +- } +- +- /* cycle through existing transactions */ +- ptr = _r->transactions; +- while(ptr) { +- LM_DBG("tsilo: transaction %u:%u found for %.*s, going to append branches\n", +- ptr->tindex, ptr->tlabel, t_uri->len, t_uri->s); +- /* append only if the desired contact has been found in locations */ +- appended = ts_append_by_contact_to(msg, ptr->tindex, ptr->tlabel, table, ruri, contact); +- if (appended > 0) +- update_stat(added_branches, appended); +- ptr = ptr->next; +- } +- +- unlock_entry_by_ruri(t_uri); +- +- return 1; +-} +- +-int ts_append_by_contact_to(struct sip_msg* msg, int tindex, int tlabel, char *table, str *uri, str *contact) { +- struct cell *t=0; +- struct cell *orig_t; /* a pointer to an existing transaction or 0 if lookup fails*/ +- struct sip_msg *orig_msg; +- int ret; +- str stable; +- +- LM_DBG("tsilo: trying to append based on contact <%.*s>\n", contact->len, contact->s); +- +- /* lookup a transaction based on its identifier (hash_index:label) */ +- orig_t = _tmb.t_gett(); +- if(_tmb.t_lookup_ident(&t, tindex, tlabel) < 0) +- { +- LM_ERR("tsilo: transaction [%u:%u] not found\n", tindex, tlabel); +- ret = -1; +- goto done; +- } +- +- /* check if the dialog is still in the early stage */ +- if (t->flags & T_CANCELED) { +- LM_DBG("tsilo: trasaction [%u:%u] was cancelled\n", tindex, tlabel); +- ret = -2; +- goto done; +- } +- if (t->uas.status >= 200) { +- LM_DBG("tsilo: trasaction [%u:%u] sent out a final response already - %d\n", +- tindex, tlabel, t->uas.status); +- ret = -3; +- goto done; +- } +- + /* get original (very first) request of the transaction */ + orig_msg = t->uas.request; + stable.s = table; +@@ -242,13 +142,13 @@ int ts_append_by_contact_to(struct sip_msg* msg, int tindex, int tlabel, char *t + } + + if(ret != 1) { +- LM_ERR("tsilo: transaction %u:%u: error updating dset (%d)\n", tindex, tlabel, ret); ++ LM_ERR("transaction %u:%u: error updating dset (%d)\n", tindex, tlabel, ret); + ret = -4; + goto done; + } + +- /* start the transaction only for the desired contact +- contact must be of syntax: sip:@: with no parameters list*/ ++ /* if the contact has been given previously ++ then do a new append only for the desired location */ + ret = _tmb.t_append_branches(contact); + + done: +diff --git a/src/modules/tsilo/ts_append.h b/src/modules/tsilo/ts_append.h +index 461f8881f3..02f3244b27 100644 +--- a/src/modules/tsilo/ts_append.h ++++ b/src/modules/tsilo/ts_append.h +@@ -22,9 +22,7 @@ + #ifndef _TS_APPEND_H + #define _TS_APPEND_H + +-int ts_append(struct sip_msg* msg, str *ruri, char *table); +-int ts_append_to(struct sip_msg* msg, int tindex, int tlabel, char *table, str *uri); +-int ts_append_by_contact(struct sip_msg* msg, str *ruri, str *contact, char *table); +-int ts_append_by_contact_to(struct sip_msg* msg, int tindex, int tlabel, char *table, str *uri, str *contact); ++int ts_append(struct sip_msg* msg, str *ruri, str *contact, char *table); ++int ts_append_to(struct sip_msg* msg, int tindex, int tlabel, char *table, str *uri, str *contact); + + #endif +diff --git a/src/modules/tsilo/tsilo.c b/src/modules/tsilo/tsilo.c +index 2eefb2fe2d..9769a3c7d8 100644 +--- a/src/modules/tsilo/tsilo.c ++++ b/src/modules/tsilo/tsilo.c +@@ -275,6 +275,9 @@ static int w_ts_append(struct sip_msg* _msg, char *_table, char *_ruri) + str ruri = STR_NULL; + int rc; + ++ /* we do not want to do append by particular location */ ++ str contact = STR_NULL; ++ + if(_ruri==NULL || (fixup_get_svalue(_msg, (gparam_p)_ruri, &tmp)!=0 || tmp.len<=0)) { + LM_ERR("invalid ruri parameter\n"); + return -1; +@@ -285,7 +288,7 @@ static int w_ts_append(struct sip_msg* _msg, char *_table, char *_ruri) + if (pkg_str_dup(&ruri, &tmp) < 0) + return -1; + +- rc = ts_append(_msg, &ruri, _table); ++ rc = ts_append(_msg, &ruri, &contact, _table); + + pkg_free(ruri.s); + +@@ -300,13 +303,16 @@ static int ki_ts_append(sip_msg_t* _msg, str *_table, str *_ruri) + str ruri = STR_NULL; + int rc; + ++ /* we do not want to do append by particular location */ ++ str contact = STR_NULL; ++ + if(ts_check_uri(_ruri)<0) + return -1; + + if (pkg_str_dup(&ruri, _ruri) < 0) + return -1; + +- rc = ts_append(_msg, &ruri, _table->s); ++ rc = ts_append(_msg, &ruri, &contact, _table->s); + + pkg_free(ruri.s); + +@@ -321,6 +327,9 @@ static int w_ts_append_to(struct sip_msg* msg, char *idx, char *lbl, char *table + unsigned int tindex; + unsigned int tlabel; + ++ /* we do not want to do append by particular location */ ++ str contact = STR_NULL; ++ + if(fixup_get_ivalue(msg, (gparam_p)idx, (int*)&tindex)<0) { + LM_ERR("cannot get transaction index\n"); + return -1; +@@ -331,7 +340,8 @@ static int w_ts_append_to(struct sip_msg* msg, char *idx, char *lbl, char *table + return -1; + } + +- return ts_append_to(msg, tindex, tlabel, table, 0); ++ /* we do not want to do append by particular location here */ ++ return ts_append_to(msg, tindex, tlabel, table, 0, &contact); + } + + /** +@@ -339,8 +349,12 @@ static int w_ts_append_to(struct sip_msg* msg, char *idx, char *lbl, char *table + */ + static int ki_ts_append_to(sip_msg_t* _msg, int tindex, int tlabel, str *_table) + { ++ /* we do not want to do append by particular location */ ++ str contact = STR_NULL; ++ ++ /* we do not want to do append by particular location here */ + return ts_append_to(_msg, (unsigned int)tindex, (unsigned int)tlabel, +- _table->s, 0); ++ _table->s, 0, &contact); + } + + /** +@@ -352,6 +366,9 @@ static int w_ts_append_to2(struct sip_msg* msg, char *idx, char *lbl, char *tabl + unsigned int tlabel; + str suri; + ++ /* we do not want to do append by particular location */ ++ str contact = STR_NULL; ++ + if(fixup_get_ivalue(msg, (gparam_p)idx, (int*)&tindex)<0) { + LM_ERR("cannot get transaction index\n"); + return -1; +@@ -369,7 +386,8 @@ static int w_ts_append_to2(struct sip_msg* msg, char *idx, char *lbl, char *tabl + if(ts_check_uri(&suri)<0) + return -1; + +- return ts_append_to(msg, tindex, tlabel, table, &suri); ++ /* we do not want to do append by particular location here */ ++ return ts_append_to(msg, tindex, tlabel, table, &suri, &contact); + } + + /** +@@ -378,8 +396,12 @@ static int w_ts_append_to2(struct sip_msg* msg, char *idx, char *lbl, char *tabl + static int ki_ts_append_to_uri(sip_msg_t* _msg, int tindex, int tlabel, + str *_table, str *_uri) + { ++ /* we do not want to do append by particular location */ ++ str contact = STR_NULL; ++ ++ /* we do not want to do append by particular location here */ + return ts_append_to(_msg, (unsigned int)tindex, (unsigned int)tlabel, +- _table->s, _uri); ++ _table->s, _uri, &contact); + } + + /** +@@ -455,7 +477,7 @@ static int w_ts_append_by_contact2(struct sip_msg* _msg, char *_table, char *_ru + } + + /* contact must be of syntax: sip:@: with no parameters list */ +- rc = ts_append_by_contact(_msg, &ruri, &contact, _table); ++ rc = ts_append(_msg, &ruri, &contact, _table); + + /* free previously used memory */ + pkg_free(ruri.s); +@@ -512,7 +534,7 @@ static int ki_ts_append_by_contact(sip_msg_t* _msg, str *_table, str *_ruri) { + } + + /* contact must be of syntax: sip:@: with no parameters list */ +- rc = ts_append_by_contact(_msg, &ruri, &contact, _table->s); ++ rc = ts_append(_msg, &ruri, &contact, _table->s); + + pkg_free(ruri.s); + pkg_free(contact.s); +@@ -576,7 +598,7 @@ static int w_ts_append_by_contact3(struct sip_msg* _msg, char *_table, char *_ru + } + + /* contact must be of syntax: sip:@: with no parameters list */ +- rc = ts_append_by_contact(_msg, &ruri, &contact, _table); ++ rc = ts_append(_msg, &ruri, &contact, _table); + + pkg_free(ruri.s); + pkg_free(contact.s); +@@ -606,7 +628,7 @@ static int ki_ts_append_by_contact_uri(sip_msg_t* _msg, str *_table, str *_ruri, + return -1; + + /* contact must be of syntax: sip:@: with no parameters list */ +- rc = ts_append_by_contact(_msg, &ruri, &contact, _table->s); ++ rc = ts_append(_msg, &ruri, &contact, _table->s); + + pkg_free(ruri.s); + pkg_free(contact.s); +-- +2.25.1 +