Skip to content

Commit

Permalink
tsilo: Add support of a lookup and branch creating by contact
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
zenichev authored and linuxmaniac committed Nov 19, 2021
1 parent e85f33d commit 7265f1c
Show file tree
Hide file tree
Showing 5 changed files with 445 additions and 1 deletion.
5 changes: 5 additions & 0 deletions src/modules/tsilo/doc/tsilo.xml
Expand Up @@ -23,6 +23,11 @@
<surname>Cabiddu</surname>
<email>federico.cabiddu@gmail.com</email>
</editor>
<editor>
<firstname>Donat</firstname>
<surname>Zenichev</surname>
<email>dzenichev@sipwise.com</email>
</editor>
</authorgroup>
<copyright>
<year>2015</year>
Expand Down
54 changes: 54 additions & 0 deletions src/modules/tsilo/doc/tsilo_admin.xml
Expand Up @@ -181,6 +181,60 @@ if (is_method("REGISTER")) {
ts_append("location", "$tu");
}
...
</programlisting>
</example>
</section>
<section id="tsilo.f.ts_append_by_contact">
<title><function moreinfo="none">ts_append_by_contact(domain, ruri [, contact])</function></title>
<para>
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.
</para>
<para>Meaning of the parameters is as follows:</para>
<itemizedlist>
<listitem>
<para>
<emphasis>domain</emphasis> - Name of table that should be used for looking
up new contacts for r-uri.
</para>
</listitem>
<listitem>
<para>
<emphasis>ruri</emphasis> - 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.
</para>
</listitem>
<listitem>
<para>
<emphasis>contact</emphasis> - 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.
</para>
</listitem>
</itemizedlist>
<para>
This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
</para>
<example>
<title><function>ts_append_by_contact</function> usage</title>
<programlisting format="linespecific">
...
if (is_method("REGISTER")) {
$var(formated_ct) = $(x_hdr(Contact){nameaddr.uri});
ts_append_by_contact("location", "$tu", "$var(formated_ct)");
}
...
</programlisting>
</example>
</section>
Expand Down
116 changes: 116 additions & 0 deletions src/modules/tsilo/ts_append.c
Expand Up @@ -139,3 +139,119 @@ int ts_append_to(struct sip_msg* msg, int tindex, int tlabel, char *table, str *

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;
}
2 changes: 2 additions & 0 deletions src/modules/tsilo/ts_append.h
Expand Up @@ -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

0 comments on commit 7265f1c

Please sign in to comment.