[sr-dev] git:master: xmpp: new parameter gwmap for sip-xmpp domain translation

Daniel-Constantin Mierla miconda at gmail.com
Mon Mar 19 15:11:01 CET 2012


Module: sip-router
Branch: master
Commit: 671ce93e7e51a0a01c5675bac154f3dfaec6c3fb
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=671ce93e7e51a0a01c5675bac154f3dfaec6c3fb

Author: Daniel-Constantin Mierla <miconda at gmail.com>
Committer: Daniel-Constantin Mierla <miconda at gmail.com>
Date:   Mon Mar 19 14:09:40 2012 +0100

xmpp: new parameter gwmap for sip-xmpp domain translation

- gwmap can get a valus as a list of
  'sipdomain1=xmppdomain1;...;sipdomainN=xmppdomainN'
- whenever a sip-to-xmpp message is sent, any matching sipdomain in src
  or dst address is translated to appropiate xmppdomain
- the other way around, when a xmpp-to-sip message is sent, then any
  matching xmpp domain in src or dst address is translated to appropiate
  sip domain
- this allow getting rid of the URI encoding with delimiter
- if a domain is not found, the src/dst domains are preserved as they
  are in SIP to XMPP and vice versa
- if the xmppdomain is not provided explicitely, sipdomain is considered
  to be also the xmpp domain

---

 modules_k/xmpp/util.c |  203 ++++++++++++++++++++++++++++++++++++++++---------
 modules_k/xmpp/xmpp.c |   40 ++++++++++
 modules_k/xmpp/xode.h |    3 +-
 3 files changed, 210 insertions(+), 36 deletions(-)

diff --git a/modules_k/xmpp/util.c b/modules_k/xmpp/util.c
index bdce7f6..143b170 100644
--- a/modules_k/xmpp/util.c
+++ b/modules_k/xmpp/util.c
@@ -34,16 +34,21 @@
 
 #include "xmpp.h"
 #include "../../parser/parse_uri.h"
+#include "../../parser/parse_param.h"
 
-/*! \brief decode sip:user*domain1\@domain2 -> user\@domain1 
-	\note In many kinds of gateway scenarios, the % sign is a common character used
-		See the MSN XMPP transports for an example.
+extern param_t *_xmpp_gwmap_list;
+
+/*! \brief decode sip:user*domain1\@domain2 -> user\@domain1
+ *     or based on gwmap sip:user\@sipdomain -> user\@xmppdomain
+ *	\note In many kinds of gateway scenarios, the % sign is a common character used
+ *		See the MSN XMPP transports for an example.
  */
 char *decode_uri_sip_xmpp(char *uri)
 {
-	struct sip_uri puri;
+	sip_uri_t puri;
 	static char buf[512];
 	char *p;
+	param_t *it = NULL;
 
 	if (!uri)
 		return NULL;
@@ -51,21 +56,43 @@ char *decode_uri_sip_xmpp(char *uri)
 		LM_ERR("failed to parse URI\n");
 		return NULL;
 	}
-	strncpy(buf, puri.user.s, sizeof(buf));
-	buf[puri.user.len] = 0;
+	if(_xmpp_gwmap_list==0)
+	{
+		strncpy(buf, puri.user.s, sizeof(buf));
+		buf[puri.user.len] = 0;
 	
-	/* replace domain separator */
-	if ((p = strchr(buf, domain_separator)))
-		*p = '@';
-
+		/* replace domain separator */
+		if ((p = strchr(buf, domain_separator)))
+			*p = '@';
+	} else {
+		for(it=_xmpp_gwmap_list; it; it=it->next)
+		{
+			if(it->name.len==puri.host.len
+					&& strncasecmp(it->name.s, puri.host.s, it->name.len)==0)
+			{
+				break;
+			}
+		}
+		if(it && it->body.len>0)
+		{
+			snprintf(buf, 512, "%.*s@%.*s", puri.user.len, puri.user.s,
+					it->body.len, it->body.s);
+		} else {
+			snprintf(buf, 512, "%.*s@%.*s", puri.user.len, puri.user.s,
+					puri.host.len, puri.host.s);
+		}
+	}
 	return buf;
 }
 
-/*! \brief  encode sip:user\@domain -> user*domain\@xmpp_domain */
+/*! \brief  encode sip:user\@domain -> user*domain\@xmpp_domain
+ *     or based on gwmap sip:user\@sipdomain -> user\@xmppdomain
+ */
 char *encode_uri_sip_xmpp(char *uri)
 {
-	struct sip_uri puri;
+	sip_uri_t puri;
 	static char buf[512];
+	param_t *it = NULL;
 
 	if (!uri)
 		return NULL;
@@ -73,51 +100,157 @@ char *encode_uri_sip_xmpp(char *uri)
 		LM_ERR("failed to parse URI\n");
 		return NULL;
 	}
-	snprintf(buf, sizeof(buf), "%.*s%c%.*s@%s",
-		puri.user.len, puri.user.s,
-		domain_separator,
-		puri.host.len, puri.host.s,
-		xmpp_domain);
+	if(_xmpp_gwmap_list==0)
+	{
+		snprintf(buf, sizeof(buf), "%.*s%c%.*s@%s",
+			puri.user.len, puri.user.s,
+			domain_separator,
+			puri.host.len, puri.host.s,
+			xmpp_domain);
+	} else {
+		for(it=_xmpp_gwmap_list; it; it=it->next)
+		{
+			if(it->name.len==puri.host.len
+					&& strncasecmp(it->name.s, puri.host.s, it->name.len)==0)
+			{
+				break;
+			}
+		}
+		if(it && it->body.len>0)
+		{
+			snprintf(buf, 512, "%.*s@%.*s", puri.user.len, puri.user.s,
+					it->body.len, it->body.s);
+		} else {
+			snprintf(buf, 512, "%.*s@%.*s", puri.user.len, puri.user.s,
+					puri.host.len, puri.host.s);
+		}
+	}
 	return buf;
 }
 
-/*! \brief  decode user*domain1\@domain2 -> sip:user\@domain1 */
+/*! \brief  decode user*domain1\@domain2 -> sip:user\@domain1
+ *     or based on gwmap sip:user\@xmppdomain -> user\@sipdomain
+ */
 char *decode_uri_xmpp_sip(char *jid)
 {
 	static char buf[512];
 	char *p;
+	char tbuf[512];
+	sip_uri_t puri;
+	str sd;
+	param_t *it = NULL;
 
 	if (!jid)
 		return NULL;
-	snprintf(buf, sizeof(buf), "sip:%s", jid);
 
-	/* strip off resource */
-	if ((p = strchr(buf, '/')))
-		*p = 0;
-	/* strip off domain */
-	if ((p = strchr(buf, '@')))
-		*p = 0;
-	/* replace domain separator */
-	if ((p = strchr(buf, domain_separator)))
-		*p = '@';
+	if(_xmpp_gwmap_list==0)
+	{
+		snprintf(buf, sizeof(buf), "sip:%s", jid);
+
+		/* strip off resource */
+		if ((p = strchr(buf, '/')))
+			*p = 0;
+		/* strip off domain */
+		if ((p = strchr(buf, '@')))
+			*p = 0;
+		/* replace domain separator */
+		if ((p = strchr(buf, domain_separator)))
+			*p = '@';
+	} else {
+		snprintf(tbuf, sizeof(tbuf), "sip:%s", jid);
+
+		/* strip off resource */
+		if ((p = strchr(tbuf, '/')))
+			*p = 0;
+		if (parse_uri(tbuf, strlen(tbuf), &puri) < 0) {
+			LM_ERR("failed to parse URI\n");
+			return NULL;
+		}
+		for(it=_xmpp_gwmap_list; it; it=it->next)
+		{
+			if(it->body.len>0)
+			{
+				sd = it->body;
+			} else {
+				sd = it->name;
+			}
+			if(sd.len==puri.host.len
+					&& strncasecmp(sd.s, puri.host.s, sd.len)==0)
+			{
+				break;
+			}
+		}
+		if(it)
+		{
+			snprintf(buf, 512, "sip:%.*s@%.*s", puri.user.len, puri.user.s,
+					it->name.len, it->name.s);
+		} else {
+			snprintf(buf, 512, "sip:%.*s@%.*s", puri.user.len, puri.user.s,
+					puri.host.len, puri.host.s);
+		}
 
+	}
 	return buf;
 }
 
-/*! \brief  encode user\@domain -> sip:user*domain\@gateway_domain */
+/*! \brief  encode user\@domain -> sip:user*domain\@gateway_domain
+ *     or based on gwmap sip:user\@xmppdomain -> user\@sipdomain
+ */
 char *encode_uri_xmpp_sip(char *jid)
 {
 	static char buf[512];
 	char *p;
+	char tbuf[512];
+	sip_uri_t puri;
+	str sd;
+	param_t *it = NULL;
 
 	if (!jid)
 		return NULL;
-	/* TODO: maybe not modify jid? */
-	if ((p = strchr(jid, '/')))
-		*p = 0;
-	if ((p = strchr(jid, '@')))
-		*p = domain_separator;
-	snprintf(buf, sizeof(buf), "sip:%s@%s", jid, gateway_domain);
+
+	if(_xmpp_gwmap_list==0)
+	{
+		/* TODO: maybe not modify jid? */
+		if ((p = strchr(jid, '/')))
+			*p = 0;
+		if ((p = strchr(jid, '@')))
+			*p = domain_separator;
+		snprintf(buf, sizeof(buf), "sip:%s@%s", jid, gateway_domain);
+	} else {
+		snprintf(tbuf, sizeof(tbuf), "sip:%s", jid);
+
+		/* strip off resource */
+		if ((p = strchr(tbuf, '/')))
+			*p = 0;
+		if (parse_uri(tbuf, strlen(tbuf), &puri) < 0) {
+			LM_ERR("failed to parse URI\n");
+			return NULL;
+		}
+		for(it=_xmpp_gwmap_list; it; it=it->next)
+		{
+			if(it->body.len>0)
+			{
+				sd = it->body;
+			} else {
+				sd = it->name;
+			}
+			if(sd.len==puri.host.len
+					&& strncasecmp(sd.s, puri.host.s, sd.len)==0)
+			{
+				break;
+			}
+		}
+		if(it)
+		{
+			snprintf(buf, 512, "sip:%.*s@%.*s", puri.user.len, puri.user.s,
+					it->name.len, it->name.s);
+		} else {
+			snprintf(buf, 512, "sip:%.*s@%.*s", puri.user.len, puri.user.s,
+					puri.host.len, puri.host.s);
+		}
+
+	}
+
 	return buf;
 }
 
diff --git a/modules_k/xmpp/xmpp.c b/modules_k/xmpp/xmpp.c
index ad087e4..98ba4cf 100644
--- a/modules_k/xmpp/xmpp.c
+++ b/modules_k/xmpp/xmpp.c
@@ -117,6 +117,7 @@
 #include "../../parser/msg_parser.h"
 #include "../../parser/parse_content.h"
 #include "../../parser/parse_from.h"
+#include "../../parser/parse_param.h"
 #include "../../modules/tm/tm_load.h"
 #include "../../cfg/cfg_struct.h"
 
@@ -139,6 +140,8 @@ static int  child_init(int rank);
 static void xmpp_process(int rank);
 static int  cmd_send_message(struct sip_msg* msg, char* _foo, char* _bar);
 
+int xmpp_gwmap_param(modparam_t type, void *val);
+
 static int pipe_fds[2] = {-1,-1};
 
 /*
@@ -154,6 +157,8 @@ int xmpp_port = 0;
 char *xmpp_password = "secret";
 str outbound_proxy= {0, 0};
 
+param_t *_xmpp_gwmap_list = NULL;
+
 #define DEFAULT_COMPONENT_PORT 5347
 #define DEFAULT_SERVER_PORT 5269
 
@@ -184,6 +189,7 @@ static param_export_t params[] = {
 	{ "xmpp_port",			INT_PARAM, &xmpp_port },
 	{ "xmpp_password",		STR_PARAM, &xmpp_password },
 	{ "outbound_proxy",		STR_PARAM, &outbound_proxy.s},
+	{ "gwmap",              STR_PARAM|USE_FUNC_PARAM, (void*)xmpp_gwmap_param},
 	{0, 0, 0}
 };
 
@@ -484,3 +490,37 @@ int xmpp_send_xnotify(str *from, str *to, str *msg, str *id)
 	return xmpp_send_pipe_cmd(XMPP_PIPE_SEND_PNOTIFY, from, to, msg, id);
 }
 
+/*!
+ *
+ */
+int xmpp_gwmap_param(modparam_t type, void *val)
+{
+	str inv;
+	param_hooks_t phooks;
+	param_t *params = NULL;
+	param_t *it = NULL;
+
+	if(val==NULL)
+		return -1;
+	inv.s = (char*)val;
+	inv.len = strlen(inv.s);
+	if(inv.len<=0)
+		return -1;
+
+	if(inv.s[inv.len-1]==';')
+		inv.len--;
+	if (parse_params(&inv, CLASS_ANY, &phooks, &params)<0)
+	{
+		LM_ERR("failed parsing params value\n");
+		return -1;
+	}
+	if(_xmpp_gwmap_list==NULL)
+	{
+		_xmpp_gwmap_list = params;
+	} else {
+		it = _xmpp_gwmap_list;
+		while(it->next) it = it->next;
+		it->next = params;
+	}
+	return 0;
+}
diff --git a/modules_k/xmpp/xode.h b/modules_k/xmpp/xode.h
index d1b3b52..2e009c1 100644
--- a/modules_k/xmpp/xode.h
+++ b/modules_k/xmpp/xode.h
@@ -71,7 +71,7 @@
 extern "C" {
 #endif
 
-
+#ifndef __OS_darwin
 #ifndef HAVE_SNPRINTF
 extern int ap_snprintf(char *, size_t, const char *, ...);
 #define snprintf ap_snprintf
@@ -81,6 +81,7 @@ extern int ap_snprintf(char *, size_t, const char *, ...);
 extern int ap_vsnprintf(char *, size_t, const char *, va_list ap);
 #define vsnprintf ap_vsnprintf
 #endif
+#endif
 
 /* --------------------------------------------------------- */
 /*                                                           */




More information about the sr-dev mailing list