[sr-dev] git:master: core: helper functions to add or restore alias parameter to an uri

Daniel-Constantin Mierla miconda at gmail.com
Fri Oct 4 10:56:26 CEST 2013


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

Author: Daniel-Constantin Mierla <miconda at gmail.com>
Committer: Daniel-Constantin Mierla <miconda at 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 */




More information about the sr-dev mailing list