Browse code

Added the possibility to set priorities of URIs in the destination set.

Jan Janak authored on 25/04/2004 15:13:24
Showing 5 changed files
... ...
@@ -280,7 +280,8 @@ int do_action(struct action* a, struct sip_msg* msg)
280 280
 				break;
281 281
 			}
282 282
 			ret=append_branch( msg, a->p1.string, 
283
-				a->p1.string ? strlen(a->p1.string):0 );
283
+					   a->p1.string ? strlen(a->p1.string):0,
284
+					   a->p2.number);
284 285
 			break;
285 286
 
286 287
 		/* jku begin: is_length_greater_than */
... ...
@@ -76,6 +76,7 @@
76 76
 #include "name_alias.h"
77 77
 #include "usr_avp.h"
78 78
 #include "ut.h"
79
+#include "dset.h"
79 80
 
80 81
 
81 82
 #include "config.h"
... ...
@@ -1431,11 +1432,12 @@ cmd:		FORWARD LPAREN host RPAREN	{ $$=mk_action(	FORWARD_T,
1431 1431
 		| STRIP error { $$=0; yyerror("missing '(' or ')' ?"); }
1432 1432
 		| STRIP LPAREN error RPAREN { $$=0; yyerror("bad argument, "
1433 1433
 														"number expected"); }
1434
-
1434
+                | APPEND_BRANCH LPAREN STRING COMMA NUMBER RPAREN { $$=mk_action( APPEND_BRANCH_T,
1435
+										                        STRING_ST, NUMBER_ST, $3, (void *)$5) ; }
1435 1436
 		| APPEND_BRANCH LPAREN STRING RPAREN { $$=mk_action( APPEND_BRANCH_T,
1436
-													STRING_ST, 0, $3, 0) ; }
1437
+													STRING_ST, NUMBER_ST, $3, (void *)Q_UNSPECIFIED) ; }
1437 1438
 		| APPEND_BRANCH LPAREN RPAREN { $$=mk_action( APPEND_BRANCH_T,
1438
-													STRING_ST, 0, 0, 0 ) ; }
1439
+													STRING_ST, NUMBER_ST, 0, (void *)Q_UNSPECIFIED ) ; }
1439 1440
 		| APPEND_BRANCH {  $$=mk_action( APPEND_BRANCH_T, STRING_ST, 0, 0, 0 ) ; }
1440 1441
 
1441 1442
 		| SET_HOSTPORT LPAREN STRING RPAREN { $$=mk_action( SET_HOSTPORT_T, 
... ...
@@ -3,7 +3,7 @@
3 3
  *
4 4
  * destination set
5 5
  *
6
- * Copyright (C) 2001-2003 Fhg Fokus
6
+ * Copyright (C) 2001-2004 FhG FOKUS
7 7
  *
8 8
  * This file is part of ser, a free SIP server.
9 9
  *
... ...
@@ -27,143 +27,236 @@
27 27
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28 28
  */
29 29
 
30
-
31 30
 #include <string.h>
32
-
33 31
 #include "dprint.h"
34 32
 #include "config.h"
35 33
 #include "parser/parser_f.h"
36 34
 #include "parser/msg_parser.h"
37 35
 #include "ut.h"
38 36
 #include "hash_func.h"
39
-#include "dset.h"
40 37
 #include "error.h"
38
+#include "dset.h"
41 39
 
40
+#define CONTACT "Contact: "
41
+#define CONTACT_LEN (sizeof(CONTACT) - 1)
42 42
 
43
+#define CONTACT_DELIM ", "
44
+#define CONTACT_DELIM_LEN (sizeof(CONTACT_DELIM) - 1)
45
+
46
+#define Q_PARAM ">;q="
47
+#define Q_PARAM_LEN (sizeof(Q_PARAM) - 1)
48
+
49
+struct branch
50
+{
51
+	char uri[MAX_URI_SIZE];
52
+	unsigned int len;
53
+	int q; /* Preference of the contact among
54
+		* contact within the array */
55
+};
56
+
57
+
58
+/* 
59
+ * Where we store URIs of additional transaction branches
60
+ * (-1 because of the default branch, #0)
61
+ */
62
+static struct branch branches[MAX_BRANCHES - 1];
43 63
 
44
-/* where we store URIs of additional transaction branches
45
-  (-1 because of the default branch, #0)
46
-*/
47
-static struct branch branches[ MAX_BRANCHES - 1 ];
48 64
 /* how many of them we have */
49
-static unsigned int nr_branches=0;
65
+static unsigned int nr_branches = 0;
66
+
50 67
 /* branch iterator */
51
-static int branch_iterator=0;
68
+static int branch_iterator = 0;
69
+
70
+/* The q parameter of the Request-URI */
71
+static qvalue_t ruri_q = Q_UNSPECIFIED; 
72
+
52 73
 
74
+/*
75
+ * Intialize the branch iterator, the next
76
+ * call to next_branch will return the first
77
+ * contact from the dset array
78
+ */
53 79
 void init_branch_iterator(void)
54 80
 {
55
-	branch_iterator=0;
81
+	branch_iterator = 0;
56 82
 }
57 83
 
58
-char *next_branch( int *len )
84
+
85
+/*
86
+ * Return the next branch from the dset
87
+ * array, 0 is returned if there are no
88
+ * more branches
89
+ */
90
+char* next_branch(int* len, qvalue_t* q)
59 91
 {
60 92
 	unsigned int i;
61 93
 
62
-	i=branch_iterator;
63
-	if (i<nr_branches) {
94
+	i = branch_iterator;
95
+	if (i < nr_branches) {
64 96
 		branch_iterator++;
65
-		*len=branches[i].len;
97
+		*len = branches[i].len;
98
+		*q = branches[i].q;
66 99
 		return branches[i].uri;
67 100
 	} else {
68
-		*len=0;
101
+		*len = 0;
102
+		*q = Q_UNSPECIFIED;
69 103
 		return 0;
70 104
 	}
71 105
 }
72 106
 
73
-void clear_branches()
107
+
108
+/*
109
+ * Empty the dset array
110
+ */
111
+void clear_branches(void)
74 112
 {
75
-	nr_branches=0;
113
+	nr_branches = 0;
114
+	ruri_q = Q_UNSPECIFIED;
76 115
 }
77 116
 
78
-/* add a new branch to current transaction */
79
-int append_branch( struct sip_msg *msg, char *uri, int uri_len )
117
+
118
+/* 
119
+ * Add a new branch to current transaction 
120
+ */
121
+int append_branch(struct sip_msg* msg, char* uri, int uri_len, qvalue_t q)
80 122
 {
81
-	/* if we have already set up the maximum number
82
-	   of branches, don't try new ones */
83
-	if (nr_branches==MAX_BRANCHES-1) {
123
+	     /* if we have already set up the maximum number
124
+	      * of branches, don't try new ones 
125
+	      */
126
+	if (nr_branches == MAX_BRANCHES - 1) {
84 127
 		LOG(L_ERR, "ERROR: append_branch: max nr of branches exceeded\n");
85
-		ser_error=E_TOO_MANY_BRANCHES;
128
+		ser_error = E_TOO_MANY_BRANCHES;
86 129
 		return -1;
87 130
 	}
88 131
 
89
-	if (uri_len>MAX_URI_SIZE-1) {
132
+	if (uri_len > MAX_URI_SIZE - 1) {
90 133
 		LOG(L_ERR, "ERROR: append_branch: too long uri: %.*s\n",
91
-			uri_len, uri );
134
+		    uri_len, uri);
92 135
 		return -1;
93 136
 	}
94 137
 
95
-	/* if not parameterized, take current uri */
96
-	if (uri==0) {
138
+	     /* if not parameterized, take current uri */
139
+	if (uri == 0) {
97 140
 		if (msg->new_uri.s) { 
98
-			uri=msg->new_uri.s;
99
-			uri_len=msg->new_uri.len;
141
+			uri = msg->new_uri.s;
142
+			uri_len = msg->new_uri.len;
100 143
 		} else {
101
-			uri=msg->first_line.u.request.uri.s;
102
-			uri_len=msg->first_line.u.request.uri.len;
144
+			uri = msg->first_line.u.request.uri.s;
145
+			uri_len = msg->first_line.u.request.uri.len;
103 146
 		}
104 147
 	}
105 148
 	
106
-	memcpy( branches[nr_branches].uri, uri, uri_len );
107
-	/* be safe -- add zero termination */
108
-	branches[nr_branches].uri[uri_len]=0;
109
-	branches[nr_branches].len=uri_len;
149
+	memcpy(branches[nr_branches].uri, uri, uri_len);
150
+	     /* be safe -- add zero termination */
151
+	branches[nr_branches].uri[uri_len] = 0;
152
+	branches[nr_branches].len = uri_len;
153
+	branches[nr_branches].q = q;
110 154
 	
111 155
 	nr_branches++;
112 156
 	return 1;
113 157
 }
114 158
 
115 159
 
116
-
117
-char *print_dset( struct sip_msg *msg, int *len ) 
160
+/*
161
+ * Create a Contact header field from the dset
162
+ * array
163
+ */
164
+char* print_dset(struct sip_msg* msg, int* len) 
118 165
 {
119
-	int cnt;
166
+	int cnt, i;
167
+	qvalue_t q;
120 168
 	str uri;
121
-	char *p;
122
-	int i;
169
+	char* p;
123 170
 	static char dset[MAX_REDIRECTION_LEN];
124 171
 
125 172
 	if (msg->new_uri.s) {
126
-		cnt=1;
127
-		*len=msg->new_uri.len;
173
+		cnt = 1;
174
+		*len = msg->new_uri.len;
175
+		if (ruri_q != Q_UNSPECIFIED) {
176
+			*len += 1 + Q_PARAM_LEN + len_q(ruri_q);
177
+		}
128 178
 	} else {
129
-		cnt=0;
130
-		*len=0;
179
+		cnt = 0;
180
+		*len = 0;
131 181
 	}
132 182
 
133 183
 	init_branch_iterator();
134
-	while ((uri.s=next_branch(&uri.len))) {
184
+	while ((uri.s = next_branch(&uri.len, &q))) {
135 185
 		cnt++;
136
-		*len+=uri.len;
186
+		*len += uri.len;
187
+		if (q != Q_UNSPECIFIED) {
188
+			*len += 1 + Q_PARAM_LEN + len_q(q);
189
+		}
137 190
 	}
138 191
 
139
-	if (cnt==0) return 0;	
192
+	if (cnt == 0) return 0;	
140 193
 
141
-	*len+=CONTACT_LEN+CRLF_LEN+(cnt-1)*CONTACT_DELIM_LEN;
194
+	*len += CONTACT_LEN + CRLF_LEN + (cnt - 1) * CONTACT_DELIM_LEN;
142 195
 
143
-	if (*len+1>MAX_REDIRECTION_LEN) {
196
+	if (*len + 1 > MAX_REDIRECTION_LEN) {
144 197
 		LOG(L_ERR, "ERROR: redirection buffer length exceed\n");
145 198
 		return 0;
146 199
 	}
147 200
 
148
-	memcpy(dset, CONTACT, CONTACT_LEN );
149
-	p=dset+CONTACT_LEN;
201
+	memcpy(dset, CONTACT, CONTACT_LEN);
202
+	p = dset + CONTACT_LEN;
150 203
 	if (msg->new_uri.s) {
204
+		if (ruri_q != Q_UNSPECIFIED) {
205
+			*p++ = '<';
206
+		}
207
+
151 208
 		memcpy(p, msg->new_uri.s, msg->new_uri.len);
152
-		p+=msg->new_uri.len;
153
-		i=1;
154
-	} else i=0;
209
+		p += msg->new_uri.len;
210
+
211
+		if (ruri_q != Q_UNSPECIFIED) {
212
+			memcpy(p, Q_PARAM, Q_PARAM_LEN);
213
+			p += Q_PARAM_LEN;
214
+			p += print_q(p, q);
215
+		}
216
+		i = 1;
217
+	} else {
218
+		i = 0;
219
+	}
155 220
 
156 221
 	init_branch_iterator();
157
-	while ((uri.s=next_branch(&uri.len))) {
222
+	while ((uri.s = next_branch(&uri.len, &q))) {
158 223
 		if (i) {
159
-			memcpy(p, CONTACT_DELIM, CONTACT_DELIM_LEN );
160
-			p+=2;
224
+			memcpy(p, CONTACT_DELIM, CONTACT_DELIM_LEN);
225
+			p += CONTACT_DELIM_LEN;
226
+		}
227
+
228
+		if (q != Q_UNSPECIFIED) {
229
+			*p++ = '<';
161 230
 		}
231
+
162 232
 		memcpy(p, uri.s, uri.len);
163
-		p+=uri.len;
233
+		p += uri.len;
234
+		if (q != Q_UNSPECIFIED) {
235
+			memcpy(p, Q_PARAM, Q_PARAM_LEN);
236
+			p += Q_PARAM_LEN;
237
+			p += print_q(p, q);
238
+		}
164 239
 		i++;
165 240
 	}
166
-	memcpy(p, CRLF " ", CRLF_LEN+1);
241
+
242
+	memcpy(p, CRLF " ", CRLF_LEN + 1);
167 243
 	return dset;
168 244
 }
169 245
 
246
+
247
+/*
248
+ * Sets the q parameter of the Request-URI
249
+ */
250
+void set_ruri_q(qvalue_t q)
251
+{
252
+	ruri_q = q;
253
+}
254
+
255
+
256
+/*
257
+ * Return the q value of the Request-URI
258
+ */
259
+qvalue_t get_ruri_q(void)
260
+{
261
+	return ruri_q;
262
+}
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * $Id$
3 3
  *
4
- * Copyright (C) 2001-2003 Fhg Fokus
4
+ * Copyright (C) 2001-2004 FhG FOKUS
5 5
  *
6 6
  * This file is part of ser, a free SIP server.
7 7
  *
... ...
@@ -25,36 +25,53 @@
25 25
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26 26
  */
27 27
 
28
+#ifndef _DSET_H
29
+#define _DSET_H
28 30
 
29
-#ifndef _T_FORKS_H
30
-#define _T_FORKS_H
31
+#include "qvalue.h"
31 32
 
32
-#include "config.h"
33
+struct sip_msg;
33 34
 
34
-#define CONTACT "Contact: "
35
-#define CONTACT_LEN 9
36
-#define CONTACT_DELIM ", "
37
-#define CONTACT_DELIM_LEN 2
35
+/* 
36
+ * Add a new branch to current transaction 
37
+ */
38
+int append_branch(struct sip_msg* msg, char* uri, int uri_len, qvalue_t q);
38 39
 
39 40
 
40
-struct branch
41
-{
42
-	char uri[MAX_URI_SIZE];
43
-	unsigned int len;
44
-};
41
+/* 
42
+ * Iterate through the list of transaction branches 
43
+ */
44
+void init_branch_iterator(void);
45
+
46
+
47
+/*
48
+ * Get the next branch in the current transaction
49
+ */
50
+char* next_branch(int* len, qvalue_t* q);
51
+
52
+
53
+/*
54
+ * Empty the array of branches
55
+ */
56
+void clear_branches(void);
45 57
 
46
-struct sip_msg;
47 58
 
48 59
 /*
49
-typedef int (*tfork_f)( struct sip_msg *msg, char *uri, int uri_len );
50
-*/
51
-
52
-/* add a new branch to current transaction */
53
-int append_branch( struct sip_msg *msg, char *uri, int uri_len );
54
-/* iterate through list of new transaction branches */
55
-void init_branch_iterator();
56
-char *next_branch( int *len );
57
-void clear_branches();
58
-
59
-char *print_dset( struct sip_msg *msg, int *len );
60
-#endif
60
+ * Create a Contact header field from the
61
+ * list of current branches
62
+ */
63
+char* print_dset(struct sip_msg* msg, int* len);
64
+
65
+
66
+/* 
67
+ * Set the q value of the Request-URI
68
+ */
69
+void set_ruri_q(qvalue_t q);
70
+
71
+
72
+/* 
73
+ * Get the q value of the Request-URI
74
+ */
75
+qvalue_t get_ruri_q(void);
76
+
77
+#endif /* _DSET_H */
... ...
@@ -403,7 +403,7 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
403 403
 	str current_uri;
404 404
 	branch_bm_t	added_branches;
405 405
 	int first_branch;
406
-	int i;
406
+	int i, q;
407 407
 	struct cell *t_invite;
408 408
 	int success_branch;
409 409
 	int try_new;
... ...
@@ -444,7 +444,7 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
444 444
 	} else try_new=0;
445 445
 
446 446
 	init_branch_iterator();
447
-	while((current_uri.s=next_branch( &current_uri.len))) {
447
+	while((current_uri.s=next_branch( &current_uri.len, &q))) {
448 448
 		try_new++;
449 449
 		branch_ret=add_uac( t, p_msg, &current_uri, 
450 450
 				    (p_msg->dst_uri.len) ? (&p_msg->dst_uri) : &current_uri,