Module: sip-router
Branch: master
Commit: 671ce93e7e51a0a01c5675bac154f3dfaec6c3fb
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=671ce93…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)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(a)%.*s"%.*s", puri.user.len, puri.user.s,
+ it->body.len, it->body.s);
+ } else {
+ snprintf(buf, 512, "%.*s(a)%.*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(a)%.*s"%.*s", puri.user.len, puri.user.s,
+ it->body.len, it->body.s);
+ } else {
+ snprintf(buf, 512, "%.*s(a)%.*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, ¶ms)<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
/* --------------------------------------------------------- */
/* */