mirror of https://github.com/sipwise/kamailio.git
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: Id321a261b137c83bfa38a150c6ff67ca312ae61dmr10.2
parent
a456f2dbcc
commit
ce9c81c7b6
@ -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( ¤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; 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, ¤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<<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…
Reference in new issue