Module: sip-router
Branch: master
Commit: 217f9fddbca31e06075132dd75a645d612d7af93
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=217f9fd…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)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 */