Browse code

- fixed a bug.

Jan Janak authored on 11/04/2003 12:37:52
Showing 2 changed files
... ...
@@ -30,21 +30,28 @@
30 30
  */
31 31
 
32 32
 
33
-#include <stdio.h>
34 33
 #include <string.h>
35 34
 #include "../../mem/shm_mem.h"
36 35
 #include "../../dprint.h"
37 36
 #include "../../parser/contact/parse_contact.h"
38 37
 #include "../../parser/parse_to.h"
39 38
 #include "../../parser/parse_from.h"
39
+#include "../../parser/parse_uri.h"
40 40
 #include "../../trim.h"
41 41
 #include "../../ut.h"
42
+#include "../../config.h"
42 43
 #include "dlg.h"
43 44
 
44 45
 
45 46
 #define NORMAL_ORDER 0  /* Create route set in normal order - UAS */
46 47
 #define REVERSE_ORDER 1 /* Create route set in reverse order - UAC */
47 48
 
49
+#define ROUTE_PREFIX "Route: "
50
+#define ROUTE_PREFIX_LEN (sizeof(ROUTE_PREFIX) - 1)
51
+
52
+#define ROUTE_SEPARATOR "," CRLF "       "
53
+#define ROUTE_SEPARATOR_LEN (sizeof(ROUTE_SEPARATOR) - 1)
54
+
48 55
 
49 56
 /*
50 57
  * Make a copy of a str structure using shm_malloc
... ...
@@ -63,6 +70,50 @@ static inline int str_duplicate(str* _d, str* _s)
63 70
 }
64 71
 
65 72
 
73
+/*
74
+ * Calculate dialog hooks
75
+ */
76
+static inline int calculate_hooks(dlg_t* _d)
77
+{
78
+	str* uri;
79
+	struct sip_uri puri;
80
+	param_hooks_t hooks;
81
+	param_t* params;
82
+
83
+	if (_d->route_set) {
84
+		uri = &_d->route_set->nameaddr.uri;
85
+		if (parse_uri(uri->s, uri->len, &puri) < 0) {
86
+			LOG(L_ERR, "calculate_hooks(): Error while parsing URI\n");
87
+			return -1;
88
+		}
89
+
90
+		if (parse_params(&puri.params, CLASS_URI, &hooks, &params) < 0) {
91
+			LOG(L_ERR, "calculate_hooks(): Error while parsing parameters\n");
92
+			return -2;
93
+		}
94
+		free_params(params);
95
+		
96
+		if (hooks.uri.lr) {
97
+			if (_d->rem_target.s) _d->hooks.request_uri = &_d->rem_target;
98
+			else _d->hooks.request_uri = &_d->rem_uri;
99
+			_d->hooks.next_hop = &_d->route_set->nameaddr.uri;
100
+			_d->hooks.first_route = _d->route_set;
101
+		} else {
102
+			_d->hooks.request_uri = &_d->route_set->nameaddr.uri;
103
+			_d->hooks.next_hop = _d->hooks.request_uri;
104
+			_d->hooks.first_route = _d->route_set->next;
105
+			_d->hooks.last_route = &_d->rem_target;
106
+		}
107
+	} else {
108
+		if (_d->rem_target.s) _d->hooks.request_uri = &_d->rem_target;
109
+		else _d->hooks.request_uri = &_d->rem_uri;
110
+		_d->hooks.next_hop = _d->hooks.request_uri;
111
+	}
112
+
113
+	return 0;
114
+}
115
+
116
+
66 117
 /*
67 118
  * Create a new dialog
68 119
  */
... ...
@@ -97,6 +148,13 @@ int new_dlg_uac(str* _cid, str* _ltag, unsigned int _lseq, str* _luri, str* _rur
97 148
 	res->loc_seq.is_set = 1;
98 149
 
99 150
 	*_d = res;
151
+
152
+	if (calculate_hooks(*_d) < 0) {
153
+		LOG(L_ERR, "new_dlg_uac(): Error while calculating hooks\n");
154
+		shm_free(res);
155
+		return -2;
156
+	}
157
+
100 158
 	return 0;
101 159
 }
102 160
 
... ...
@@ -310,6 +368,11 @@ static inline int dlg_new_resp_uac(dlg_t* _d, struct sip_msg* _m)
310 368
 		      */
311 369
 		if (response2dlg(_m, _d) < 0) return -1;
312 370
 		_d->state = DLG_CONFIRMED;
371
+
372
+		if (calculate_hooks(_d) < 0) {
373
+			LOG(L_ERR, "dlg_new_resp_uac(): Error while calculating hooks\n");
374
+			return -2;
375
+		}
313 376
 	} else {
314 377
 		     /* 
315 378
 		      * A negative final response, mark the dialog as destroyed
... ...
@@ -345,6 +408,11 @@ static inline int dlg_early_resp_uac(dlg_t* _d, struct sip_msg* _m)
345 408
 		      */
346 409
 		if (response2dlg(_m, _d) < 0) return -1;
347 410
 		_d->state = DLG_CONFIRMED;
411
+
412
+		if (calculate_hooks(_d) < 0) {
413
+			LOG(L_ERR, "dlg_early_resp_uac(): Error while calculating hooks\n");
414
+			return -2;
415
+		}
348 416
 	} else {
349 417
 		     /* Else terminate the dialog */
350 418
 		_d->state = DLG_DESTROYED;
... ...
@@ -633,8 +701,16 @@ int new_dlg_uas(struct sip_msg* _req, int _code, str* _tag, dlg_t** _d)
633 701
 			return -5;
634 702
 		}
635 703
 	}
636
-
704
+	
637 705
 	*_d = res;
706
+
707
+	(*_d)->state = DLG_CONFIRMED;
708
+	if (calculate_hooks(*_d) < 0) {
709
+		LOG(L_ERR, "new_dlg_uas(): Error while calculating hooks\n");
710
+		shm_free(*_d);
711
+		return -6;
712
+	}
713
+
638 714
 	return 0;
639 715
 }
640 716
 
... ...
@@ -687,6 +763,81 @@ int dlg_request_uas(dlg_t* _d, struct sip_msg* _m)
687 763
 }
688 764
 
689 765
 
766
+/*
767
+ * Calculate length of the route set
768
+ */
769
+int calculate_routeset_length(dlg_t* _d)
770
+{
771
+	int len;
772
+	rr_t* ptr;
773
+
774
+	len = 0;
775
+	ptr = _d->hooks.first_route;
776
+
777
+	if (ptr) {
778
+		len = ROUTE_PREFIX_LEN;
779
+		len += CRLF_LEN;
780
+	}
781
+
782
+	while(ptr) {
783
+		len += ptr->len;
784
+		ptr = ptr->next;
785
+		if (ptr) len += ROUTE_SEPARATOR_LEN;
786
+	} 
787
+
788
+	if (_d->hooks.last_route) {
789
+		len += ROUTE_SEPARATOR_LEN + 2; /* < > */
790
+		len += _d->hooks.last_route->len;
791
+	}
792
+
793
+	return len;
794
+}
795
+
796
+
797
+/*
798
+ *
799
+ * Print the route set
800
+ */
801
+char* print_routeset(char* buf, dlg_t* _d)
802
+{
803
+	rr_t* ptr;
804
+
805
+	ptr = _d->hooks.first_route;
806
+
807
+	if (ptr) {
808
+		memcpy(buf, ROUTE_PREFIX, ROUTE_PREFIX_LEN);
809
+		buf += ROUTE_PREFIX_LEN;
810
+	}
811
+
812
+	while(ptr) {
813
+		memcpy(buf, ptr->nameaddr.name.s, ptr->len);
814
+		buf += ptr->len;
815
+
816
+		ptr = ptr->next;
817
+		if (ptr) {
818
+			memcpy(buf, ROUTE_SEPARATOR, ROUTE_SEPARATOR_LEN);
819
+			buf += ROUTE_SEPARATOR_LEN;
820
+		}
821
+	} 
822
+
823
+	if (_d->hooks.last_route) {
824
+		memcpy(buf, ROUTE_SEPARATOR "<", ROUTE_SEPARATOR_LEN + 1);
825
+		buf += ROUTE_SEPARATOR_LEN + 1;
826
+		memcpy(buf, _d->hooks.last_route->s, _d->hooks.last_route->len);
827
+		buf += _d->hooks.last_route->len;
828
+		*buf = '>';
829
+		buf++;
830
+	}
831
+
832
+	if (_d->hooks.first_route) {
833
+		memcpy(buf, CRLF, CRLF_LEN);
834
+		buf += CRLF_LEN;
835
+	}
836
+
837
+	return buf;
838
+}
839
+
840
+
690 841
 /*
691 842
  * Destroy a dialog state
692 843
  */
... ...
@@ -711,28 +862,36 @@ void free_dlg(dlg_t* _d)
711 862
 /*
712 863
  * Print a dialog structure, just for debugging
713 864
  */
714
-void print_dlg(dlg_t* _d)
865
+void print_dlg(FILE* out, dlg_t* _d)
715 866
 {
716
-	printf("====dlg_t===\n");
717
-	printf("id.call_id    : '%.*s'\n", _d->id.call_id.len, _d->id.call_id.s);
718
-	printf("id.rem_tag    : '%.*s'\n", _d->id.rem_tag.len, _d->id.rem_tag.s);
719
-	printf("id.loc_tag    : '%.*s'\n", _d->id.loc_tag.len, _d->id.loc_tag.s);
720
-	printf("loc_seq.value : %d\n", _d->loc_seq.value);
721
-	printf("loc_seq.is_set: %s\n", _d->loc_seq.is_set ? "YES" : "NO");
722
-	printf("rem_seq.value : %d\n", _d->rem_seq.value);
723
-	printf("rem_seq.is_set: %s\n", _d->rem_seq.is_set ? "YES" : "NO");
724
-	printf("loc_uri       : '%.*s'\n", _d->loc_uri.len, _d->loc_uri.s);
725
-	printf("rem_uri       : '%.*s'\n", _d->rem_uri.len, _d->rem_uri.s);
726
-	printf("rem_target    : '%.*s'\n", _d->rem_target.len, _d->rem_target.s);
727
-	printf("secure:       : %d\n", _d->secure);
728
-	printf("state         : ");
867
+	fprintf(out, "====dlg_t===\n");
868
+	fprintf(out, "id.call_id    : '%.*s'\n", _d->id.call_id.len, _d->id.call_id.s);
869
+	fprintf(out, "id.rem_tag    : '%.*s'\n", _d->id.rem_tag.len, _d->id.rem_tag.s);
870
+	fprintf(out, "id.loc_tag    : '%.*s'\n", _d->id.loc_tag.len, _d->id.loc_tag.s);
871
+	fprintf(out, "loc_seq.value : %d\n", _d->loc_seq.value);
872
+	fprintf(out, "loc_seq.is_set: %s\n", _d->loc_seq.is_set ? "YES" : "NO");
873
+	fprintf(out, "rem_seq.value : %d\n", _d->rem_seq.value);
874
+	fprintf(out, "rem_seq.is_set: %s\n", _d->rem_seq.is_set ? "YES" : "NO");
875
+	fprintf(out, "loc_uri       : '%.*s'\n", _d->loc_uri.len, _d->loc_uri.s);
876
+	fprintf(out, "rem_uri       : '%.*s'\n", _d->rem_uri.len, _d->rem_uri.s);
877
+	fprintf(out, "rem_target    : '%.*s'\n", _d->rem_target.len, _d->rem_target.s);
878
+	fprintf(out, "secure:       : %d\n", _d->secure);
879
+	fprintf(out, "state         : ");
729 880
 	switch(_d->state) {
730
-	case DLG_NEW:       printf("DLG_NEW");       break;
731
-	case DLG_EARLY:     printf("DLG_EARLY");     break;
732
-	case DLG_CONFIRMED: printf("DLG_CONFIRMED"); break;
733
-	case DLG_DESTROYED: printf("DLG_DESTROYED"); break;
734
-	}
881
+	case DLG_NEW:       fprintf(out, "DLG_NEW\n");       break;
882
+	case DLG_EARLY:     fprintf(out, "DLG_EARLY\n");     break;
883
+	case DLG_CONFIRMED: fprintf(out, "DLG_CONFIRMED\n"); break;
884
+	case DLG_DESTROYED: fprintf(out, "DLG_DESTROYED\n"); break;
885
+	}
886
+	print_rr(out, _d->route_set);
887
+	if (_d->hooks.request_uri) 
888
+		fprintf(out, "hooks.request_uri: '%.*s'\n", _d->hooks.request_uri->len, _d->hooks.request_uri->s);
889
+	if (_d->hooks.next_hop) 
890
+		fprintf(out, "hooks.next_hop   : '%.*s'\n", _d->hooks.next_hop->len, _d->hooks.next_hop->s);
891
+	if (_d->hooks.first_route) 
892
+		fprintf(out, "hooks.first_route: '%.*s'\n", _d->hooks.first_route->len, _d->hooks.first_route->nameaddr.name.s);
893
+	if (_d->hooks.last_route)
894
+		fprintf(out, "hooks.last_route : '%.*s'\n", _d->hooks.last_route->len, _d->hooks.last_route->s);
735 895
 	
736
-	print_rr(_d->route_set);
737
-	printf("====dlg_t====\n");
896
+	fprintf(out, "====dlg_t====\n");
738 897
 }
... ...
@@ -32,6 +32,7 @@
32 32
 #define DLG_H
33 33
 
34 34
 
35
+#include <stdio.h>
35 36
 #include "../../str.h"
36 37
 #include "../../parser/parse_rr.h"
37 38
 #include "../../parser/msg_parser.h"
... ...
@@ -67,6 +68,22 @@ typedef struct dlg_id {
67 68
 } dlg_id_t;
68 69
 
69 70
 
71
+/*
72
+ * It is neccessary to analyze the dialog data to find out
73
+ * what URI put into the Record-Route, where the message
74
+ * should be really sent and how to construct the route
75
+ * set of the message. This structure stores this information
76
+ * so we don't have to calculate each time we want to send a
77
+ * message within dialog
78
+ */
79
+typedef struct dlg_hooks {
80
+	str* request_uri;   /* This should be put into Request-URI */
81
+	str* next_hop;      /* Where the message should be really sent */
82
+	rr_t* first_route;  /* First route to be printed into the message */
83
+	str* last_route;    /* If not zero add this as the last route */
84
+} dlg_hooks_t;
85
+
86
+
70 87
 /*
71 88
  * Structure representing dialog state
72 89
  */
... ...
@@ -80,6 +97,10 @@ typedef struct dlg {
80 97
 	unsigned char secure;   /* Secure flag -- currently not used */
81 98
 	dlg_state_t state;      /* State of the dialog */
82 99
 	rr_t* route_set;        /* Route set */
100
+	dlg_hooks_t hooks;      /* Various hooks used to store information that
101
+				 * can be reused when building a message (to
102
+				 * prevent repeated analysing of the dialog data
103
+				 */
83 104
 } dlg_t;
84 105
 
85 106
 
... ...
@@ -116,7 +137,20 @@ void free_dlg(dlg_t* _d);
116 137
 /*
117 138
  * Print a dialog structure, just for debugging
118 139
  */
119
-void print_dlg(dlg_t* _d);
140
+void print_dlg(FILE* out, dlg_t* _d);
141
+
142
+
143
+/*
144
+ * Calculate length of the route set
145
+ */
146
+int calculate_routeset_length(dlg_t* _d);
147
+
148
+
149
+/*
150
+ *
151
+ * Print the route set
152
+ */
153
+char* print_routeset(char* buf, dlg_t* _d);
120 154
 
121 155
 
122 156
 #endif /* DLG_H */