Module: sip-router Branch: master Commit: 671ce93e7e51a0a01c5675bac154f3dfaec6c3fb URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=671ce93e...
Author: Daniel-Constantin Mierla miconda@gmail.com Committer: Daniel-Constantin Mierla miconda@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, ¶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
/* --------------------------------------------------------- */ /* */