Attached is a patch for the domain module which adds a function that 
allows checking if a domain specified in an avp is local. This is a 
generalization of the is_*_local() functions already present in the 
domain module.

The function is called is_domain_local() and accepts as input an avp 
specification. It will then take that avp value and check if the domain 
(which supposedly the avp holds) is local.

the input parameter of the function can be one of:

1. $ruri  - will check the domain part of the request uri
2. $from  - will check the domain part of the From header
3. avp name or alias - will check the value of the avp/alias

For case 3 the avp should contain the domain part only, unlike the cases 1 
or 2 where the domain part will be taken from $ruri/$from internally.

Cases 1 and 2 are present for convenience and to simplify usage in the 
most used cases. They can of course be emulated by using the 3rd form, 
but with an extra avp_write function call:

avp_write("$ruri/domain", "i:888")
is_domain_local("i:888")

The following forms are equivalent with the old forms:

is_domain_local("$ruri") == is_uri_host_local()
is_domain_local("$from") == is_from_local()

but new uses are possible:

is_domain_local("i:888")
is_domain_local("s:my_domain")
is_domain_local("$an_alias")


Who is responsible for this code please consider applying this patch.

-- 
Dan
? avp.diff
Index: domain.c
===================================================================
RCS file: /cvsroot/openser/sip-server/modules/domain/domain.c,v
retrieving revision 1.2
diff -u -b -B -r1.2 domain.c
--- domain.c	6 Sep 2005 16:16:16 -0000	1.2
+++ domain.c	20 Jan 2006 08:09:58 -0000
@@ -206,6 +206,42 @@
 
 
 /*
+ * Check if domain given by parameter is local
+ *
+ * parameter can be one of:
+ * - $ruri             - check domain from request uri
+ * - $from             - check domain from From header
+ * - avp name or alias - check the domain given by the value
+ *                       pointed by the avp name/alias
+ */
+int w_is_domain_local(struct sip_msg* _msg, char* _s1, char* _s2)
+{
+    struct param_source *ps;
+    struct usr_avp *avp;
+    int_str avp_value;
+
+    ps = (struct param_source*) _s1;
+
+    switch (ps->source) {
+    case PARAM_SOURCE_RURI:
+        return is_uri_host_local(_msg, _s1, _s2);
+    case PARAM_SOURCE_FROM:
+        return is_from_local(_msg, _s1, _s2);
+    case PARAM_SOURCE_AVP:
+        avp = search_first_avp(ps->avp_type, ps->avp_name, &avp_value);
+        if (!avp || !(avp->flags & AVP_VAL_STR) || !avp_value.s || !avp_value.s->s || !avp_value.s->len) {
+            DBG("domain/w_is_domain_local(): Undefined, empty or non-string avp, nothing to check\n");
+            return -1;
+        }
+        return is_domain_local(avp_value.s);
+    default:
+        LOG(L_ERR, "domain/w_is_domain_local(): invalid input parameter\n");
+        return 0;
+    }
+}
+
+
+/*
  * Reload domain table to new hash table and when done, make new hash table
  * current one.
  */
Index: domain.h
===================================================================
RCS file: /cvsroot/openser/sip-server/modules/domain/domain.h,v
retrieving revision 1.1.1.1
diff -u -b -B -r1.1.1.1 domain.h
--- domain.h	13 Jun 2005 16:47:37 -0000	1.1.1.1
+++ domain.h	20 Jan 2006 08:09:58 -0000
@@ -40,6 +40,17 @@
  */
 int is_uri_host_local(struct sip_msg* _msg, char* _s1, char* _s2);
 
+/*
+ * Check if domain given by parameter is local
+ *
+ * parameter can be one of:
+ * - $ruri             - check domain from request uri
+ * - $from             - check domain from From header
+ * - avp name or alias - check the domain given by the value
+ *                       pointed by the avp name/alias
+ */
+int w_is_domain_local(struct sip_msg* _msg, char* _s1, char* _s2);
+
 int domain_db_bind(char* db_url);
 int domain_db_init(char* db_url);
 void domain_db_close();
Index: domain_mod.c
===================================================================
RCS file: /cvsroot/openser/sip-server/modules/domain/domain_mod.c,v
retrieving revision 1.5
diff -u -b -B -r1.5 domain_mod.c
--- domain_mod.c	22 Nov 2005 22:03:18 -0000	1.5
+++ domain_mod.c	20 Jan 2006 08:09:58 -0000
@@ -35,6 +35,7 @@
 #include "domain_mod.h"
 #include <stdio.h>
 #include "../../mem/shm_mem.h"
+#include "../../mem/mem.h"
 #include "../../sr_module.h"
 #include "domain.h"
 #include "fifo.h"
@@ -46,6 +47,7 @@
 static int mod_init(void);
 static void destroy(void);
 static int child_init(int rank);
+static int fixup_avp(void** param, int param_no);
 
 MODULE_VERSION
 
@@ -84,6 +86,7 @@
 static cmd_export_t cmds[] = {
 	{"is_from_local",     is_from_local,     0, 0, REQUEST_ROUTE},
 	{"is_uri_host_local", is_uri_host_local, 0, 0, REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE},
+	{"is_domain_local",   w_is_domain_local, 1, fixup_avp, REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE},
 	{0, 0, 0, 0, 0}
 };
 
@@ -208,3 +211,61 @@
 	 * it is closed in mod_init already
 	 */
 }
+
+
+static int fixup_avp(void** param, int param_no)
+{
+    struct param_source *ps = NULL;
+    int_str avp_name;
+    char *src;
+    str avp;
+
+    if (param_no==1) {
+        src = (char*) *param;
+
+        ps = (struct param_source*) pkg_malloc(sizeof(struct param_source));
+        if (ps == NULL) {
+            LOG(L_ERR, "ERROR: domain/fixup_avp(): out of pkg mem\n");
+            return E_OUT_OF_MEM;
+        }
+        memset(ps, 0, sizeof(struct param_source));
+
+        if (strcasecmp(src, "$ruri") == 0) {
+            ps->source = PARAM_SOURCE_RURI;
+        } else if (strcasecmp(src, "$from") == 0) {
+            ps->source = PARAM_SOURCE_FROM;
+        } else {
+            ps->source = PARAM_SOURCE_AVP;
+            avp.s = src;
+            avp.len = strlen(src);
+            if (parse_avp_spec(&avp, &ps->avp_type, &avp_name)!=0) {
+                LOG(L_ERR, "ERROR: domain/fixup_avp(): invalid avp specification: %s\n", src);
+                pkg_free(ps);
+                return E_UNSPEC;
+            }
+            /* copy the avp name into the ps structure */
+            if (ps->avp_type & AVP_NAME_STR) {
+                ps->avp_name.s = (str*) pkg_malloc(sizeof(str) + avp_name.s->len + 1);
+                if (ps->avp_name.s == NULL) {
+                    LOG(L_ERR, "ERROR: domain/fixup_avp(): out of pkg mem\n");
+                    pkg_free(ps);
+                    return E_OUT_OF_MEM;
+                }
+                ps->avp_name.s->len = avp_name.s->len;
+                ps->avp_name.s->s = ((char*)ps->avp_name.s) + sizeof(str);
+                memcpy(ps->avp_name.s->s, avp_name.s->s, avp_name.s->len);
+                ps->avp_name.s->s[ps->avp_name.s->len] = 0;
+            } else {
+                ps->avp_name.n = avp_name.n;
+            }
+        }
+
+        pkg_free(*param);
+        *param = (void*)ps;
+
+    }
+
+    return 0;
+}
+
+
Index: domain_mod.h
===================================================================
RCS file: /cvsroot/openser/sip-server/modules/domain/domain_mod.h,v
retrieving revision 1.1.1.1
diff -u -b -B -r1.1.1.1 domain_mod.h
--- domain_mod.h	13 Jun 2005 16:47:37 -0000	1.1.1.1
+++ domain_mod.h	20 Jan 2006 08:09:58 -0000
@@ -29,6 +29,7 @@
 
 #include "../../db/db.h"
 #include "../../str.h"
+#include "../../usr_avp.h"
 
 
 /*
@@ -36,6 +37,13 @@
  */
 #define HASH_SIZE 128
 
+/* flags for param source for is_domain_local() */
+#define PARAM_SOURCE_NONE  (0)
+#define PARAM_SOURCE_AVP   (1<<0)
+#define PARAM_SOURCE_RURI  (1<<1)
+#define PARAM_SOURCE_FROM  (1<<2)
+
+
 /*
  * Type definitions
  */
@@ -44,6 +52,13 @@
 	struct domain_list *next;
 };
 
+typedef struct param_source {
+	int source;       /* One of PARAM_SOURCE_XXX from above */
+
+	int avp_type;     /* If source is an avp, the avp type else 0 */
+	int_str avp_name; /* If source is an avp, the avp name else NULL */
+} param_source;
+
 /*
  * Module parameters variables
  */
_______________________________________________
Devel mailing list
[email protected]
http://openser.org/cgi-bin/mailman/listinfo/devel

Reply via email to