Skip to content

Commit

Permalink
[uac_registrant] Match reply Contact with binding_URI by parameter.
Browse files Browse the repository at this point in the history
Added new integer module parameter 'match_contact' to choose, what
parts of URI from Contact header should match binding_URI when
OpenSIPS chooses expiration time for registration.
  • Loading branch information
vasilevalex committed Jun 24, 2021
1 parent 41a3230 commit 229eb20
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 2 deletions.
5 changes: 3 additions & 2 deletions modules/uac_registrant/registrant.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ uac_auth_api_t uac_auth_api;

unsigned int default_expires = 3600;
unsigned int timer_interval = 100;
unsigned int match_contact = URI_MATCH_ALL;

reg_table_t reg_htable = NULL;
unsigned int reg_hsize = 1;
Expand Down Expand Up @@ -139,6 +140,7 @@ static param_export_t params[]= {
{"hash_size", INT_PARAM, &reg_hsize},
{"default_expires", INT_PARAM, &default_expires},
{"timer_interval", INT_PARAM, &timer_interval},
{"match_contact", INT_PARAM, &match_contact},
{"enable_clustering", INT_PARAM, &enable_clustering},
{"db_url", STR_PARAM, &db_url.s},
{"table_name", STR_PARAM, &reg_table_name.s},
Expand Down Expand Up @@ -481,8 +483,7 @@ int run_reg_tm_cback(void *e_data, void *data, void *r_data)
contact = ((contact_body_t*)msg->contact->parsed)->contacts;
while (contact) {
/* Check for binding */
if (contact->uri.len==rec->contact_uri.len &&
strncmp(contact->uri.s,rec->contact_uri.s,contact->uri.len)==0){
if (compare_uris_parts(&contact->uri, &rec->contact_uri, (enum uri_match_flags)match_contact) == 0) {
if (contact->expires && contact->expires->body.len) {
if (str2int(&contact->expires->body, &exp)<0) {
LM_ERR("Unable to extract expires from [%.*s]"
Expand Down
86 changes: 86 additions & 0 deletions parser/parse_uri.c
Original file line number Diff line number Diff line change
Expand Up @@ -1846,3 +1846,89 @@ int compare_uris(str *raw_uri_a,struct sip_uri* parsed_uri_a,
compare_uri_val(headers,strncasecmp);
return 0;
}

/* Compare 2 SIP URIs by parts according to opts
*
* Return value : 0 if URIs match
* 1 if URIs don't match
* -1 if errors have occurred
*/
int compare_uris_parts(str *raw_uri_a, str *raw_uri_b, enum uri_match_flags opts)
{
#define UNESCAPED_BUF_LEN 1024
char unescaped_a[UNESCAPED_BUF_LEN], unescaped_b[UNESCAPED_BUF_LEN];

str unescaped_userA={unescaped_a, UNESCAPED_BUF_LEN};
str unescaped_userB={unescaped_b, UNESCAPED_BUF_LEN};

struct sip_uri first;
struct sip_uri second;

if ( (!raw_uri_a) || (!raw_uri_b) )
{
LM_ERR("Provide either a raw form of a SIP URI\n");
return -1;
}

/* maybe we're lucky and straight-forward comparison succeeds */
if ((opts & URI_MATCH_ALL) && (raw_uri_a->len == raw_uri_b->len))
if (strncasecmp(raw_uri_a->s,raw_uri_b->s,raw_uri_a->len) == 0)
{
LM_DBG("straight-forward URI match\n");
return 0;
}

if (parse_uri(raw_uri_a->s,raw_uri_a->len,&first) < 0)
{
LM_ERR("Failed to parse first URI\n");
return -1;
}

if (parse_uri(raw_uri_b->s,raw_uri_b->len,&second) < 0)
{
LM_ERR("Failed to parse second URI\n");
return -1;
}

if (opts & URI_MATCH_TYPE)
if (first.type != second.type)
{
LM_DBG("Different uri types\n");
return 1;
}

if (unescape_user(&first.user, &unescaped_userA) < 0 ||
unescape_user(&second.user, &unescaped_userB) < 0) {
LM_ERR("Failed to unescape user!\n");
return -1;
}

first.user = unescaped_userA;
second.user = unescaped_userB;

if (opts & URI_MATCH_USER)
compare_uri_val(user,strncmp);
if (opts & URI_MATCH_PASSWD)
compare_uri_val(passwd,strncmp);
if (opts & URI_MATCH_HOST)
compare_uri_val(host,strncasecmp);
if (opts & URI_MATCH_PORT)
compare_uri_val(port,strncmp);

if (opts & URI_MATCH_TRANSPORT)
compare_uri_val(transport_val,strncasecmp);
if (opts & URI_MATCH_TTL)
compare_uri_val(ttl_val,strncasecmp);
if (opts & URI_MATCH_USERPARAM)
compare_uri_val(user_param_val,strncasecmp);
if (opts & URI_MATCH_MADDR)
compare_uri_val(maddr_val,strncasecmp);
if (opts & URI_MATCH_METHOD)
compare_uri_val(method_val,strncasecmp);
if (opts & URI_MATCH_LR)
compare_uri_val(lr_val,strncasecmp);
if (opts & URI_MATCH_R2)
compare_uri_val(r2_val,strncasecmp);

return 0;
}
18 changes: 18 additions & 0 deletions parser/parse_uri.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,23 @@
#define URN_NENA_SERVICE_STR ":nena:service:"
#define URN_NENA_SERVICE_STR_LEN (sizeof(URN_NENA_SERVICE_STR) - 1)

enum uri_match_flags {
URI_MATCH_TYPE = (1<<0),
URI_MATCH_USER = (1<<1),
URI_MATCH_PASSWD = (1<<2),
URI_MATCH_HOST = (1<<3),
URI_MATCH_PORT = (1<<4),
URI_MATCH_TRANSPORT = (1<<5),
URI_MATCH_TTL = (1<<6),
URI_MATCH_USERPARAM = (1<<7),
URI_MATCH_MADDR = (1<<8),
URI_MATCH_METHOD = (1<<9),
URI_MATCH_LR = (1<<10),
URI_MATCH_R2 = (1<<11),
URI_MATCH_ALL = (URI_MATCH_TYPE | URI_MATCH_USER | URI_MATCH_PASSWD | URI_MATCH_HOST | URI_MATCH_PORT | URI_MATCH_TRANSPORT |
URI_MATCH_TTL | URI_MATCH_USERPARAM | URI_MATCH_MADDR | URI_MATCH_METHOD | URI_MATCH_LR | URI_MATCH_R2),
};

/* buf= pointer to beginning of uri (sip:[email protected]:5060;a=b?h=i)
* len= len of uri
* returns: fills uri & returns <0 on error or 0 if ok
Expand Down Expand Up @@ -69,6 +86,7 @@ int parse_sip_msg_uri(struct sip_msg* msg);
int parse_orig_ruri(struct sip_msg* msg);
int compare_uris(str *raw_uri_a,struct sip_uri* parsed_uri_a,
str *raw_uri_b,struct sip_uri *parsed_uri_b);
int compare_uris_parts(str *raw_uri_a, str *raw_uri_b, enum uri_match_flags opts);
static inline int get_uri_param_val(const struct sip_uri *uri,
const str *param, str *val);
static inline int get_uri_param_idx(const str *param,
Expand Down

0 comments on commit 229eb20

Please sign in to comment.