... | ... |
@@ -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 | 1432 |
| STRIP error { $$=0; yyerror("missing '(' or ')' ?"); } |
1432 | 1433 |
| STRIP LPAREN error RPAREN { $$=0; yyerror("bad argument, " |
1433 | 1434 |
"number expected"); } |
1434 |
- |
|
1435 |
+ | APPEND_BRANCH LPAREN STRING COMMA NUMBER RPAREN { $$=mk_action( APPEND_BRANCH_T, |
|
1436 |
+ STRING_ST, NUMBER_ST, $3, (void *)$5) ; } |
|
1435 | 1437 |
| APPEND_BRANCH LPAREN STRING RPAREN { $$=mk_action( APPEND_BRANCH_T, |
1436 |
- STRING_ST, 0, $3, 0) ; } |
|
1438 |
+ STRING_ST, NUMBER_ST, $3, (void *)Q_UNSPECIFIED) ; } |
|
1437 | 1439 |
| APPEND_BRANCH LPAREN RPAREN { $$=mk_action( APPEND_BRANCH_T, |
1438 |
- STRING_ST, 0, 0, 0 ) ; } |
|
1440 |
+ STRING_ST, NUMBER_ST, 0, (void *)Q_UNSPECIFIED ) ; } |
|
1439 | 1441 |
| APPEND_BRANCH { $$=mk_action( APPEND_BRANCH_T, STRING_ST, 0, 0, 0 ) ; } |
1440 | 1442 |
|
1441 | 1443 |
| 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( ¤t_uri.len))) { |
|
447 |
+ while((current_uri.s=next_branch( ¤t_uri.len, &q))) { |
|
448 | 448 |
try_new++; |
449 | 449 |
branch_ret=add_uac( t, p_msg, ¤t_uri, |
450 | 450 |
(p_msg->dst_uri.len) ? (&p_msg->dst_uri) : ¤t_uri, |