Module: sip-router Branch: master Commit: 2ac602d3de1330705ecfdede660d43c02e4b4334 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=2ac602d3...
Author: Daniel-Constantin Mierla miconda@gmail.com Committer: Daniel-Constantin Mierla miconda@gmail.com Date: Tue Sep 11 12:52:45 2012 +0200
registrar(k): new function lookup_branches(domain)
- lookup the contacts for r-uri and additional branches - only branches that are clean (i.e., have only r-uri set) are used - useful for group dialing, to lookup all AoR in the group, without a need to loop back
---
modules_k/registrar/lookup.c | 132 +++++++++++++++++++++++++++++++++++++++++ modules_k/registrar/lookup.h | 5 ++ modules_k/registrar/reg_mod.c | 12 ++++ 3 files changed, 149 insertions(+), 0 deletions(-)
diff --git a/modules_k/registrar/lookup.c b/modules_k/registrar/lookup.c index 0f75eec..865224a 100644 --- a/modules_k/registrar/lookup.c +++ b/modules_k/registrar/lookup.c @@ -309,6 +309,138 @@ done: }
+int reset_ruri_branch(sip_msg_t *msg) +{ + if(msg==NULL) + return -1; + + reset_dst_uri(msg); + reset_path_vector(msg); + set_ruri_q(Q_UNSPECIFIED); + reset_force_socket(msg); + setbflagsval(0, 0); + return 0; +} + +/*! \brief + * Lookup contacts in the database for all branches, including R-URI + * \return: -1 : not found + * -2 : found but method not allowed (for r-uri) + * -3 : error + */ +int lookup_branches(sip_msg_t *msg, udomain_t *d) +{ + unsigned int nr_branches_start; + unsigned int i; + int ret; + int found; + str new_uri; + str ruri_b_uri = {0}; + str ruri_b_dst_uri = {0}; + str ruri_b_path = {0}; + int ruri_b_q = Q_UNSPECIFIED; + struct socket_info *ruri_b_socket = 0; + flag_t ruri_b_flags = 0; + branch_t *crt = NULL; + + ret = 1; + found = 0; + nr_branches_start = nr_branches; + /* first lookup the r-uri */ + ret = lookup(msg, d, NULL); + + /* if no other branches -- all done */ + if(nr_branches_start==0) + return ret; + + /* backup r-uri branch */ + ruri_b_uri = msg->new_uri; + ruri_b_dst_uri = msg->dst_uri; + ruri_b_path = msg->path_vec; + ruri_b_q = get_ruri_q(); + ruri_b_socket = msg->force_send_socket; + getbflagsval(0, &ruri_b_flags); + reset_ruri_branch(msg); + + for(i=0; i<nr_branches; i++) { + crt = get_sip_branch(i); + /* it has to be a clean branch to do lookup for it */ + if(crt->len <= 0 || crt->dst_uri_len > 0 + || crt->path_len > 0 || crt->force_send_socket!=NULL + || crt->flags !=0) + continue; + /* set the new uri from branch and lookup */ + new_uri.s = crt->uri; + new_uri.len = crt->len; + if (rewrite_uri(msg, &new_uri) < 0) { + LM_ERR("unable to rewrite Request-URI for branch %u\n", i); + ret = -3; + goto done; + } + ret = lookup(msg, d, NULL); + if(ret>0) { + /* move r-uri branch attributes to crt branch */ + found = 1; + + if (unlikely(msg->new_uri.len > MAX_URI_SIZE - 1)) { + LM_ERR("too long uri: %.*s\n", msg->new_uri.len, + msg->new_uri.s); + ret = -3; + goto done; + } + + /* copy the dst_uri */ + if (msg->dst_uri.len>0 && msg->dst_uri.s!=NULL) { + if (unlikely(msg->dst_uri.len > MAX_URI_SIZE - 1)) { + LM_ERR("too long dst_uri: %.*s\n", msg->dst_uri.len, + msg->dst_uri.s); + ret = -3; + goto done; + } + + memcpy(crt->dst_uri, msg->dst_uri.s, msg->dst_uri.len); + crt->dst_uri[msg->dst_uri.len] = 0; + crt->dst_uri_len = msg->dst_uri.len; + } + + /* copy the path string */ + if (unlikely(msg->path_vec.len>0 && msg->path_vec.s!=NULL)) { + if (unlikely(msg->path_vec.len > MAX_PATH_SIZE - 1)) { + LM_ERR("too long path: %.*s\n", msg->path_vec.len, + msg->path_vec.s); + ret = -3; + goto done; + } + memcpy(crt->path, msg->path_vec.s, msg->path_vec.len); + crt->path[msg->path_vec.len] = 0; + crt->path_len = msg->path_vec.len; + } + + /* copy the ruri */ + memcpy(crt->uri, msg->new_uri.s, msg->new_uri.len); + crt->uri[msg->new_uri.len] = 0; + crt->len = msg->new_uri.len; + crt->q = get_ruri_q(); + + crt->force_send_socket = msg->force_send_socket; + getbflagsval(0, &crt->flags); + } + reset_ruri_branch(msg); + } + +done: + reset_ruri_branch(msg); + msg->new_uri = ruri_b_uri; + msg->parsed_uri_ok = 0; + msg->dst_uri = ruri_b_dst_uri; + msg->path_vec = ruri_b_path; + set_ruri_q(ruri_b_q); + set_force_socket(msg, ruri_b_socket); + setbflagsval(0, ruri_b_flags); + + return (found)?1:ret; +} + /*! \brief the is_registered() function * Return true if the AOR in the Request-URI is registered, * it is similar to lookup but registered neither rewrites diff --git a/modules_k/registrar/lookup.h b/modules_k/registrar/lookup.h index 8680f14..93780ae 100644 --- a/modules_k/registrar/lookup.h +++ b/modules_k/registrar/lookup.h @@ -41,6 +41,11 @@ */ int lookup(struct sip_msg* _m, udomain_t* _d, str* _uri);
+/*! \brief + * Lookup r-uri and additional branches in usrloc + */ +int lookup_branches(sip_msg_t *msg, udomain_t *d); +
/*! \brief * Return true if the AOR in the Request-URI is registered, diff --git a/modules_k/registrar/reg_mod.c b/modules_k/registrar/reg_mod.c index a38b00a..de4067f 100644 --- a/modules_k/registrar/reg_mod.c +++ b/modules_k/registrar/reg_mod.c @@ -91,6 +91,7 @@ static void mod_destroy(void); static int w_save2(struct sip_msg* _m, char* _d, char* _cflags); static int w_save3(struct sip_msg* _m, char* _d, char* _cflags, char* _uri); static int w_lookup(struct sip_msg* _m, char* _d, char* _p2); +static int w_lookup_branches(struct sip_msg* _m, char* _d, char* _p2); static int w_registered(struct sip_msg* _m, char* _d, char* _uri); static int w_unregister(struct sip_msg* _m, char* _d, char* _uri);
@@ -186,6 +187,8 @@ static cmd_export_t cmds[] = { {"reg_free_contacts", (cmd_function)pv_free_contacts, 1, fixup_str_null, 0, REQUEST_ROUTE| FAILURE_ROUTE }, + {"lookup_branches", (cmd_function)w_lookup_branches, 1, domain_uri_fixup, 0, + REQUEST_ROUTE | FAILURE_ROUTE }, {"bind_registrar", (cmd_function)bind_registrar, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} @@ -437,6 +440,15 @@ static int w_lookup(struct sip_msg* _m, char* _d, char* _uri) return lookup(_m, (udomain_t*)_d, (uri.len>0)?&uri:NULL); }
+/*! \brief + * Wrapper to lookup_branches(location) + */ +static int w_lookup_branches(sip_msg_t* _m, char* _d, char* _p2) +{ + return lookup_branches(_m, (udomain_t*)_d); +} + + static int w_registered(struct sip_msg* _m, char* _d, char* _uri) { str uri = {0};