TT#144053 TSILO: / TM: Add support of a lookup and branch creating by contact

We need to rewrok TSILO module and partially TM's API,
so that it is able to run a lookup using the provided RURI,
but only create a new branch for the Contact,
which is set in the currently processed REGISTER.

Optionally add a possibility to provide a contact as a pseudo-variable.

Hence we will be able to append new branches for only UAC(s) comming
online now (being REGISTERED).

New script functions introduced, tsilo:
- ts_append_by_contact(table, ruri [, contact])

New functions introduced, tsilo:
- 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()

New functions introduced, TM:
- t_append_branch_by_contact()

Change-Id: Id321a261b137c83bfa38a150c6ff67ca312ae61d
mr10.2
Donat Zenichev 5 years ago
parent a456f2dbcc
commit ce9c81c7b6

@ -58,6 +58,9 @@ 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
#
### Don't just put stuff in any order
### use gbp pq import/export tooling to help maintain patches
###

@ -0,0 +1,244 @@
--- 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:<user>@<host>:<port> */
+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( &current_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; i<outgoings; i++) {
+ if (t->uac[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, &current_uri,
+ (dst_uri.len) ? (&dst_uri) : &current_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<<new_branch;
+ else
+ lowest_ret=MIN_int(lowest_ret, new_branch);
+ }
+
+ clear_branches();
+
+ LM_DBG("Call %.*s: %d (%d) outgoing branches after clear_branches()\n",
+ orig_msg->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; i<t->nr_of_outgoings; i++) {
+ if (added_branches & (1<<i)) {
+ branch_ret=t_send_branch(t, i, faked_req , 0, 0 /* replies are already locked */ );
+ if (branch_ret>=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<<branch_ret;
+ }
+ }
+ }
+ 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;
+}
\ 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;

@ -0,0 +1,445 @@
--- 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:<user>@<host>:<port> 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;
+}
--- 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
--- 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_ms
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,
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;
+}
+
/**
*
*/
@@ -360,6 +385,238 @@ static int ki_ts_append_to_uri(sip_msg_t
/**
*
*/
+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:<user>@<host>:<port> 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:<user>@<host>:<port> with no parameters list */
+ rc = ts_append_by_contact(_msg, &ruri, &contact, _table);
+
+ 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:<user>@<host>:<port> 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:<user>@<host>:<port> 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 w_ts_store(struct sip_msg* msg, char *p1, char *p2)
{
return ts_store(msg, 0);
@@ -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 } }
};
Loading…
Cancel
Save