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