Module: sip-router Branch: master Commit: 217f9fddbca31e06075132dd75a645d612d7af93 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=217f9fdd...
Author: Daniel-Constantin Mierla miconda@gmail.com Committer: Daniel-Constantin Mierla miconda@gmail.com Date: Thu Oct 3 09:13:39 2013 +0200
core: helper functions to add or restore alias parameter to an uri
---
dset.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ dset.h | 3 + 2 files changed, 161 insertions(+), 0 deletions(-)
diff --git a/dset.c b/dset.c index 6ca3c02..13b000b 100644 --- a/dset.c +++ b/dset.c @@ -37,6 +37,7 @@ #include "dprint.h" #include "config.h" #include "parser/parser_f.h" +#include "parser/parse_uri.h" #include "parser/msg_parser.h" #include "ut.h" #include "hash_func.h" @@ -719,3 +720,160 @@ int msg_get_src_addr(sip_msg_t *msg, str *uri, int mode) return 0; }
+/** + * add alias parameter with encoding of source address + * - nuri->s must point to a buffer of nuri->len size + */ +int uri_add_rcv_alias(sip_msg_t *msg, str *uri, str *nuri) +{ + char* p; + str ip, port; + int len; + + if (msg==NULL || uri==NULL || nuri==NULL) { + LM_ERR("invalid parameter value\n"); + return -1; + } + + ip.s = ip_addr2a(&msg->rcv.src_ip); + ip.len = strlen(ip.s); + + port.s = int2str(msg->rcv.src_port, &port.len); + + /*uri;alias=[ip]~port~proto*/ + len = uri->len+ip.len+port.len+12; + if(len>=nuri->len) { + LM_ERR("not enough space for new uri: %d\n", len); + return -1; + } + p = nuri->s; + memcpy(p, uri->s, uri->len); + p += uri->len; + memcpy(p, ";alias=", 7); + p += 7; + if (msg->rcv.src_ip.af == AF_INET6) + *p++ = '['; + memcpy(p, ip.s, ip.len); + p += ip.len; + if (msg->rcv.src_ip.af == AF_INET6) + *p++ = ']'; + *p++ = '~'; + memcpy(p, port.s, port.len); + p += port.len; + *p++ = '~'; + *p++ = msg->rcv.proto + '0'; + nuri->len = p - nuri->s; + nuri->s[nuri->len] = '\0'; + + LM_DBG("encoded <%.*s> => [%.*s]\n", + uri->len, uri->s, nuri->len, nuri->s); + return 0; +} + +/** + * restore from alias parameter with encoding of source address + * - nuri->s must point to a buffer of nuri->len size + * - suri->s must point to a buffer of suri->len size + */ +int uri_restore_rcv_alias(str *uri, str *nuri, str *suri) +{ + char* p; + str skip; + str ip, port, sproto; + int proto; + + if (uri==NULL || nuri==NULL || suri==NULL) { + LM_ERR("invalid parameter value\n"); + return -1; + } + + /* sip:x;alias=1.1.1.1~0~0 */ + if(uri->len < 23) { + /* no alias possible */ + return -2; + } + p = uri->s + uri->len-18; + skip.s = 0; + while(p>uri->s+5) { + if(strncmp(p, ";alias=", 7)==0) { + skip.s = p; + break; + } + p--; + } + if(skip.s==0) { + /* alias parameter not found */ + return -2; + } + p += 7; + ip.s = p; + p = (char*)memchr(ip.s, '~', (size_t)(uri->s+uri->len-ip.s)); + if(p==NULL) { + /* proper alias parameter not found */ + return -2; + } + ip.len = p - ip.s; + p++; + if(p>=uri->s+uri->len) { + /* proper alias parameter not found */ + return -2; + } + port.s = p; + p = (char*)memchr(port.s, '~', (size_t)(uri->s+uri->len-port.s)); + if(p==NULL) { + /* proper alias parameter not found */ + return -2; + } + port.len = p - port.s; + p++; + if(p>=uri->s+uri->len) { + /* proper alias parameter not found */ + return -2; + } + proto = (int)(*p - '0'); + p++; + + if(p!=uri->s+uri->len && *p!=';') { + /* proper alias parameter not found */ + return -2; + } + skip.len = (int)(p - skip.s); + + if(suri->len<=4+ip.len+1+port.len+11/*;transport=*/+4) { + LM_ERR("address buffer too small\n"); + return -1; + } + if(nuri->len<=uri->len - skip.len) { + LM_ERR("uri buffer too small\n"); + return -1; + } + + p = nuri->s; + memcpy(p, uri->s, (size_t)(skip.s-uri->s)); + p += skip.s-uri->s; + memcpy(p, skip.s+skip.len, (size_t)(uri->s+uri->len - skip.s - skip.len)); + p += uri->s+uri->len - skip.s - skip.len; + nuri->len = p - nuri->s; + + p = suri->s; + strncpy(p, "sip:", 4); + p += 4; + strncpy(p, ip.s, ip.len); + p += ip.len; + *p++ = ':'; + strncpy(p, port.s, port.len); + p += port.len; + proto_type_to_str((unsigned short)proto, &sproto); + if(sproto.len>0 && proto!=PROTO_UDP) { + strncpy(p, ";transport=", 11); + p += 11; + strncpy(p, sproto.s, sproto.len); + p += sproto.len; + } + suri->len = p - suri->s; + + LM_DBG("decoded <%.*s> => [%.*s] [%.*s]\n", + uri->len, uri->s, nuri->len, nuri->s, suri->len, suri->s); + + return 0; +} diff --git a/dset.h b/dset.h index c811cdb..af90312 100644 --- a/dset.h +++ b/dset.h @@ -255,4 +255,7 @@ int getbflagsval(unsigned int branch, flag_t* res); */ int setbflagsval(unsigned int branch, flag_t val);
+int uri_add_rcv_alias(sip_msg_t *msg, str *uri, str *nuri); +int uri_restore_rcv_alias(str *uri, str *nuri, str *suri); + #endif /* _DSET_H */