Module: sip-router
Branch: master
Commit: 2ac602d3de1330705ecfdede660d43c02e4b4334
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=2ac602d…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)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};