Browse code

core: helper functions to add or restore alias parameter to an uri

Daniel-Constantin Mierla authored on 03/10/2013 07:13:39
Showing 2 changed files
... ...
@@ -37,6 +37,7 @@
37 37
 #include "dprint.h"
38 38
 #include "config.h"
39 39
 #include "parser/parser_f.h"
40
+#include "parser/parse_uri.h"
40 41
 #include "parser/msg_parser.h"
41 42
 #include "ut.h"
42 43
 #include "hash_func.h"
... ...
@@ -719,3 +720,160 @@ int msg_get_src_addr(sip_msg_t *msg, str *uri, int mode)
719 720
 	return 0;
720 721
 }
721 722
 
723
+/**
724
+ * add alias parameter with encoding of source address
725
+ * - nuri->s must point to a buffer of nuri->len size
726
+ */
727
+int uri_add_rcv_alias(sip_msg_t *msg, str *uri, str *nuri)
728
+{
729
+	char* p;
730
+	str ip, port;
731
+	int len;
732
+
733
+	if (msg==NULL || uri==NULL || nuri==NULL) {
734
+		LM_ERR("invalid parameter value\n");
735
+		return -1;
736
+	}
737
+
738
+	ip.s = ip_addr2a(&msg->rcv.src_ip);
739
+	ip.len = strlen(ip.s);
740
+
741
+	port.s = int2str(msg->rcv.src_port, &port.len);
742
+
743
+	/*uri;alias=[ip]~port~proto*/
744
+	len = uri->len+ip.len+port.len+12;
745
+	if(len>=nuri->len) {
746
+		LM_ERR("not enough space for new uri: %d\n", len);
747
+		return -1;
748
+	}
749
+	p = nuri->s;
750
+	memcpy(p, uri->s, uri->len);
751
+	p += uri->len;
752
+	memcpy(p, ";alias=", 7);
753
+	p += 7;
754
+	if (msg->rcv.src_ip.af == AF_INET6)
755
+		*p++ = '[';
756
+	memcpy(p, ip.s, ip.len);
757
+	p += ip.len;
758
+	if (msg->rcv.src_ip.af == AF_INET6)
759
+		*p++ = ']';
760
+	*p++ = '~';
761
+	memcpy(p, port.s, port.len);
762
+	p += port.len;
763
+	*p++ = '~';
764
+	*p++ = msg->rcv.proto + '0';
765
+	nuri->len = p - nuri->s;
766
+	nuri->s[nuri->len] = '\0';
767
+
768
+	LM_DBG("encoded <%.*s> => [%.*s]\n",
769
+			uri->len, uri->s, nuri->len, nuri->s);
770
+	return 0;
771
+}
772
+
773
+/**
774
+ * restore from alias parameter with encoding of source address
775
+ * - nuri->s must point to a buffer of nuri->len size
776
+ * - suri->s must point to a buffer of suri->len size
777
+ */
778
+int uri_restore_rcv_alias(str *uri, str *nuri, str *suri)
779
+{
780
+	char* p;
781
+	str skip;
782
+	str ip, port, sproto;
783
+	int proto;
784
+
785
+	if (uri==NULL || nuri==NULL || suri==NULL) {
786
+		LM_ERR("invalid parameter value\n");
787
+		return -1;
788
+	}
789
+
790
+	/* sip:x;alias=1.1.1.1~0~0 */
791
+	if(uri->len < 23) {
792
+		/* no alias possible */
793
+		return -2;
794
+	}
795
+	p = uri->s + uri->len-18;
796
+	skip.s = 0;
797
+	while(p>uri->s+5) {
798
+		if(strncmp(p, ";alias=", 7)==0) {
799
+			skip.s = p;
800
+			break;
801
+		}
802
+		p--;
803
+	}
804
+	if(skip.s==0) {
805
+		/* alias parameter not found */
806
+		return -2;
807
+	}
808
+	p += 7;
809
+	ip.s = p;
810
+	p = (char*)memchr(ip.s, '~', (size_t)(uri->s+uri->len-ip.s));
811
+	if(p==NULL) {
812
+		/* proper alias parameter not found */
813
+		return -2;
814
+	}
815
+	ip.len = p - ip.s;
816
+	p++;
817
+	if(p>=uri->s+uri->len) {
818
+		/* proper alias parameter not found */
819
+		return -2;
820
+	}
821
+	port.s = p;
822
+	p = (char*)memchr(port.s, '~', (size_t)(uri->s+uri->len-port.s));
823
+	if(p==NULL) {
824
+		/* proper alias parameter not found */
825
+		return -2;
826
+	}
827
+	port.len = p - port.s;
828
+	p++;
829
+	if(p>=uri->s+uri->len) {
830
+		/* proper alias parameter not found */
831
+		return -2;
832
+	}
833
+	proto = (int)(*p - '0');
834
+	p++;
835
+
836
+	if(p!=uri->s+uri->len && *p!=';') {
837
+		/* proper alias parameter not found */
838
+		return -2;
839
+	}
840
+	skip.len = (int)(p - skip.s);
841
+
842
+	if(suri->len<=4+ip.len+1+port.len+11/*;transport=*/+4) {
843
+		LM_ERR("address buffer too small\n");
844
+		return -1;
845
+	}
846
+	if(nuri->len<=uri->len - skip.len) {
847
+		LM_ERR("uri buffer too small\n");
848
+		return -1;
849
+	}
850
+
851
+	p = nuri->s;
852
+	memcpy(p, uri->s, (size_t)(skip.s-uri->s));
853
+	p += skip.s-uri->s;
854
+	memcpy(p, skip.s+skip.len, (size_t)(uri->s+uri->len - skip.s - skip.len));
855
+	p += uri->s+uri->len - skip.s - skip.len;
856
+	nuri->len = p - nuri->s;
857
+
858
+	p = suri->s;
859
+	strncpy(p, "sip:", 4);
860
+	p += 4;
861
+	strncpy(p, ip.s, ip.len);
862
+	p += ip.len;
863
+	*p++ = ':';
864
+	strncpy(p, port.s, port.len);
865
+	p += port.len;
866
+	proto_type_to_str((unsigned short)proto, &sproto);
867
+	if(sproto.len>0 && proto!=PROTO_UDP) {
868
+		strncpy(p, ";transport=", 11);
869
+		p += 11;
870
+		strncpy(p, sproto.s, sproto.len);
871
+		p += sproto.len;
872
+	}
873
+	suri->len = p - suri->s;
874
+
875
+	LM_DBG("decoded <%.*s> => [%.*s] [%.*s]\n",
876
+			uri->len, uri->s, nuri->len, nuri->s, suri->len, suri->s);
877
+
878
+	return 0;
879
+}
... ...
@@ -255,4 +255,7 @@ int getbflagsval(unsigned int branch, flag_t* res);
255 255
  */
256 256
 int setbflagsval(unsigned int branch, flag_t val);
257 257
 
258
+int uri_add_rcv_alias(sip_msg_t *msg, str *uri, str *nuri);
259
+int uri_restore_rcv_alias(str *uri, str *nuri, str *suri);
260
+
258 261
 #endif /* _DSET_H */