94095575e32a38e514decdfa7899b4e05215abcb
[sip-router] / dset.c
1 /*
2  * $Id$
3  *
4  * destination set
5  *
6  * Copyright (C) 2001-2004 FhG FOKUS
7  *
8  * This file is part of ser, a free SIP server.
9  *
10  * ser is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version
14  *
15  * For a license to use the ser software under conditions
16  * other than those described here, or to purchase support for this
17  * software, please contact iptel.org by e-mail at the following addresses:
18  *    info@iptel.org
19  *
20  * ser is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License 
26  * along with this program; if not, write to the Free Software 
27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28  */
29
30 #include <string.h>
31 #include "dprint.h"
32 #include "config.h"
33 #include "parser/parser_f.h"
34 #include "parser/msg_parser.h"
35 #include "ut.h"
36 #include "hash_func.h"
37 #include "error.h"
38 #include "dset.h"
39 #include "mem/mem.h"
40 #include "ip_addr.h"
41
42 #define CONTACT "Contact: "
43 #define CONTACT_LEN (sizeof(CONTACT) - 1)
44
45 #define CONTACT_DELIM ", "
46 #define CONTACT_DELIM_LEN (sizeof(CONTACT_DELIM) - 1)
47
48 #define Q_PARAM ">;q="
49 #define Q_PARAM_LEN (sizeof(Q_PARAM) - 1)
50
51 struct branch
52 {
53         char uri[MAX_URI_SIZE];
54         unsigned int len;
55
56              /* Real destination of the request */
57         char dst_uri[MAX_URI_SIZE];
58         unsigned int dst_uri_len;
59
60         /* Path set */
61         char path[MAX_PATH_SIZE];
62         unsigned int path_len;
63
64         int q; /* Preference of the contact among
65                 * contact within the array */
66         struct socket_info* force_send_socket;
67
68         /* Branch flags */
69         flag_t flags;
70 };
71
72
73 /* 
74  * Where we store URIs of additional transaction branches
75  * (-1 because of the default branch, #0)
76  */
77 static struct branch branches[MAX_BRANCHES - 1];
78
79 /* how many of them we have */
80 unsigned int nr_branches = 0;
81
82 /* branch iterator */
83 static int branch_iterator = 0;
84
85 /* The q parameter of the Request-URI */
86 static qvalue_t ruri_q = Q_UNSPECIFIED;
87
88 /* Branch flags of the Request-URI */
89 static flag_t ruri_bflags;
90
91
92 static inline flag_t* get_bflags_ptr(unsigned int branch)
93 {
94         if (branch == 0) return &ruri_bflags;
95         if (branch - 1 < nr_branches) return &branches[branch - 1].flags;
96         return NULL;
97 }
98
99
100 int setbflag(unsigned int branch, flag_t flag)
101 {
102         flag_t* flags;
103
104         if ((flags = get_bflags_ptr(branch)) == NULL) return -1;
105         (*flags) |= 1 << flag;
106         return 1;
107 }
108
109
110 int isbflagset(unsigned int branch, flag_t flag)
111 {
112         flag_t* flags;
113
114         if ((flags = get_bflags_ptr(branch)) == NULL) return -1;
115         return ((*flags) & (1 << flag)) ? 1 : -1;
116 }
117
118
119 int resetbflag(unsigned int branch, flag_t flag)
120 {
121         flag_t* flags;
122
123         if ((flags = get_bflags_ptr(branch)) == NULL) return -1;
124         (*flags) &= ~ (1 << flag);
125         return 1;
126 }
127
128
129 int getbflagsval(unsigned int branch, flag_t* res)
130 {
131         flag_t* flags;
132         if (res == NULL) return -1;
133         if ((flags = get_bflags_ptr(branch)) == NULL) return -1;
134         *res = *flags;
135         return 1;
136 }
137
138
139 int setbflagsval(unsigned int branch, flag_t val)
140 {
141         flag_t* flags;
142         if ((flags = get_bflags_ptr(branch)) == NULL) return -1;
143         *flags = val;
144         return 1;
145 }
146
147
148 /*
149  * Initialize the branch iterator, the next
150  * call to next_branch will return the first
151  * contact from the dset array
152  */
153 void init_branch_iterator(void)
154 {
155         branch_iterator = 0;
156 }
157
158
159 /*
160  * Return the next branch from the dset
161  * array, 0 is returned if there are no
162  * more branches
163  */
164 char* next_branch(int* len, qvalue_t* q, char** dst_uri, int* dst_len, struct socket_info** force_socket)
165 {
166         unsigned int i;
167
168         i = branch_iterator;
169         if (i < nr_branches) {
170                 branch_iterator++;
171                 *len = branches[i].len;
172                 *q = branches[i].q;
173                 if (dst_uri && dst_len) {
174                         *dst_uri = branches[i].dst_uri;
175                         *dst_len = branches[i].dst_uri_len;
176                 }
177                 if (force_socket) {
178                         *force_socket = branches[i].force_send_socket;
179                 }
180                 return branches[i].uri;
181         } else {
182                 *len = 0;
183                 *q = Q_UNSPECIFIED;
184                 if (dst_uri && dst_len) {
185                         *dst_uri = 0;
186                         *dst_len = 0;
187                 }
188                 if (force_socket) {
189                         *force_socket = 0;
190                 }
191                 return 0;
192         }
193 }
194
195
196 /** \brief Get a branch from the destination set
197  * \return Return the 'i' branch from the dset
198  * array, 0 is returned if there are no
199  * more branches
200  */
201 char* get_branch(unsigned int i, int* len, qvalue_t* q, str* dst_uri,
202                                  str* path, unsigned int *flags, struct socket_info** force_socket)
203 {
204         if (i < nr_branches) {
205                 *len = branches[i].len;
206                 *q = branches[i].q;
207                 if (dst_uri) {
208                         dst_uri->len = branches[i].dst_uri_len;
209                         dst_uri->s = (dst_uri->len)?branches[i].dst_uri:0;
210                 }
211                 if (path) {
212                         path->len = branches[i].path_len;
213                         path->s = (path->len)?branches[i].path:0;
214                 }
215                 if (force_socket)
216                         *force_socket = branches[i].force_send_socket;
217                 if (flags)
218                         *flags = branches[i].flags;
219                 return branches[i].uri;
220         } else {
221                 *len = 0;
222                 *q = Q_UNSPECIFIED;
223                 if (dst_uri) {
224                         dst_uri->s = 0;
225                         dst_uri->len = 0;
226                 }
227                 if (force_socket)
228                         *force_socket = 0;
229                 if (flags)
230                         *flags = 0;
231                 return 0;
232         }
233 }
234
235
236 /*
237  * Empty the dset array
238  */
239 void clear_branches(void)
240 {
241         nr_branches = 0;
242         ruri_q = Q_UNSPECIFIED;
243 }
244
245
246 /* 
247  * Add a new branch to current transaction 
248  */
249 int append_branch(struct sip_msg* msg, char* uri, int uri_len, char* dst_uri, int dst_uri_len, 
250                   qvalue_t q, struct socket_info* force_socket)
251 {
252              /* if we have already set up the maximum number
253               * of branches, don't try new ones 
254               */
255         if (nr_branches == MAX_BRANCHES - 1) {
256                 LOG(L_ERR, "ERROR: append_branch: max nr of branches exceeded\n");
257                 ser_error = E_TOO_MANY_BRANCHES;
258                 return -1;
259         }
260
261         if (uri_len > MAX_URI_SIZE - 1) {
262                 LOG(L_ERR, "ERROR: append_branch: too long uri: %.*s\n",
263                     uri_len, uri);
264                 return -1;
265         }
266         
267         if (dst_uri_len > MAX_URI_SIZE - 1) {
268                 LOG(L_ERR, "ERROR: append_branch: too long dst_uri: %.*s\n",
269                     dst_uri_len, ZSW(dst_uri));
270                 return -1;
271         }
272
273              /* if not parameterized, take current uri */
274         if (uri == 0) {
275                 if (msg->new_uri.s) { 
276                         uri = msg->new_uri.s;
277                         uri_len = msg->new_uri.len;
278                 } else {
279                         uri = msg->first_line.u.request.uri.s;
280                         uri_len = msg->first_line.u.request.uri.len;
281                 }
282         }
283         
284         memcpy(branches[nr_branches].uri, uri, uri_len);
285              /* be safe -- add zero termination */
286         branches[nr_branches].uri[uri_len] = 0;
287         branches[nr_branches].len = uri_len;
288         branches[nr_branches].q = q;
289         
290         if (dst_uri && dst_uri_len) {
291                 memcpy(branches[nr_branches].dst_uri, dst_uri, dst_uri_len);
292                 branches[nr_branches].dst_uri[dst_uri_len] = 0;
293                 branches[nr_branches].dst_uri_len = dst_uri_len;
294         } else {
295                 branches[nr_branches].dst_uri[0] = '\0';
296                 branches[nr_branches].dst_uri_len = 0;
297         }
298
299         branches[nr_branches].force_send_socket = force_socket;
300         
301         nr_branches++;
302         return 1;
303 }
304
305
306 /* ! \brief
307  * Add a new branch to current transaction using str parameters
308  * Kamailio compatibility version
309  */
310 int km_append_branch(struct sip_msg* msg, str* uri, str* dst_uri, str* path,
311                 qvalue_t q, unsigned int flags, struct socket_info* force_socket)
312 {
313         str luri;
314
315 #ifdef USE_LOCAL_ROUTE
316         if (dset_state==0)
317                 return -1;
318 #endif
319
320         /* if we have already set up the maximum number
321          * of branches, don't try new ones 
322          */
323         if (nr_branches == MAX_BRANCHES - 1) {
324                 LOG(L_ERR, "max nr of branches exceeded\n");
325                 ser_error = E_TOO_MANY_BRANCHES;
326                 return -1;
327         }
328
329         /* if not parameterized, take current uri */
330         if (uri==0 || uri->len==0 || uri->s==0) {
331                 if (msg->new_uri.s)
332                         luri = msg->new_uri;
333                 else
334                         luri = msg->first_line.u.request.uri;
335         } else {
336                 luri = *uri;
337         }
338
339         if (luri.len > MAX_URI_SIZE - 1) {
340                 LOG(L_ERR, "too long uri: %.*s\n", luri.len, luri.s);
341                 return -1;
342         }
343
344         /* copy the dst_uri */
345         if (dst_uri && dst_uri->len && dst_uri->s) {
346                 if (dst_uri->len > MAX_URI_SIZE - 1) {
347                         LOG(L_ERR, "too long dst_uri: %.*s\n",
348                                 dst_uri->len, dst_uri->s);
349                         return -1;
350                 }
351                 memcpy(branches[nr_branches].dst_uri, dst_uri->s, dst_uri->len);
352                 branches[nr_branches].dst_uri[dst_uri->len] = 0;
353                 branches[nr_branches].dst_uri_len = dst_uri->len;
354         } else {
355                 branches[nr_branches].dst_uri[0] = '\0';
356                 branches[nr_branches].dst_uri_len = 0;
357         }
358
359         /* copy the path string */
360         if (path && path->len && path->s) {
361                 if (path->len > MAX_PATH_SIZE - 1) {
362                         LOG(L_ERR, "too long path: %.*s\n", path->len, path->s);
363                         return -1;
364                 }
365                 memcpy(branches[nr_branches].path, path->s, path->len);
366                 branches[nr_branches].path[path->len] = 0;
367                 branches[nr_branches].path_len = path->len;
368         } else {
369                 branches[nr_branches].path[0] = '\0';
370                 branches[nr_branches].path_len = 0;
371         }
372
373         /* copy the ruri */
374         memcpy(branches[nr_branches].uri, luri.s, luri.len);
375         branches[nr_branches].uri[luri.len] = 0;
376         branches[nr_branches].len = luri.len;
377         branches[nr_branches].q = q;
378
379         branches[nr_branches].force_send_socket = force_socket;
380         branches[nr_branches].flags = flags;
381
382         nr_branches++;
383         return 1;
384 }
385
386
387 /*
388  * Create a Contact header field from the dset
389  * array
390  */
391 char* print_dset(struct sip_msg* msg, int* len) 
392 {
393         int cnt, i;
394         unsigned int qlen;
395         qvalue_t q;
396         str uri;
397         char* p, *qbuf;
398         static char dset[MAX_REDIRECTION_LEN];
399
400         if (msg->new_uri.s) {
401                 cnt = 1;
402                 *len = msg->new_uri.len;
403                 if (ruri_q != Q_UNSPECIFIED) {
404                         *len += 1 + Q_PARAM_LEN + len_q(ruri_q);
405                 }
406         } else {
407                 cnt = 0;
408                 *len = 0;
409         }
410
411         init_branch_iterator();
412         while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0))) {
413                 cnt++;
414                 *len += uri.len;
415                 if (q != Q_UNSPECIFIED) {
416                         *len += 1 + Q_PARAM_LEN + len_q(q);
417                 }
418         }
419
420         if (cnt == 0) return 0; 
421
422         *len += CONTACT_LEN + CRLF_LEN + (cnt - 1) * CONTACT_DELIM_LEN;
423
424         if (*len + 1 > MAX_REDIRECTION_LEN) {
425                 LOG(L_ERR, "ERROR: redirection buffer length exceed\n");
426                 return 0;
427         }
428
429         memcpy(dset, CONTACT, CONTACT_LEN);
430         p = dset + CONTACT_LEN;
431         if (msg->new_uri.s) {
432                 if (ruri_q != Q_UNSPECIFIED) {
433                         *p++ = '<';
434                 }
435
436                 memcpy(p, msg->new_uri.s, msg->new_uri.len);
437                 p += msg->new_uri.len;
438
439                 if (ruri_q != Q_UNSPECIFIED) {
440                         memcpy(p, Q_PARAM, Q_PARAM_LEN);
441                         p += Q_PARAM_LEN;
442
443                         qbuf = q2str(ruri_q, &qlen);
444                         memcpy(p, qbuf, qlen);
445                         p += qlen;
446                 }
447                 i = 1;
448         } else {
449                 i = 0;
450         }
451
452         init_branch_iterator();
453         while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0))) {
454                 if (i) {
455                         memcpy(p, CONTACT_DELIM, CONTACT_DELIM_LEN);
456                         p += CONTACT_DELIM_LEN;
457                 }
458
459                 if (q != Q_UNSPECIFIED) {
460                         *p++ = '<';
461                 }
462
463                 memcpy(p, uri.s, uri.len);
464                 p += uri.len;
465                 if (q != Q_UNSPECIFIED) {
466                         memcpy(p, Q_PARAM, Q_PARAM_LEN);
467                         p += Q_PARAM_LEN;
468
469                         qbuf = q2str(q, &qlen);
470                         memcpy(p, qbuf, qlen);
471                         p += qlen;
472                 }
473                 i++;
474         }
475
476         memcpy(p, CRLF " ", CRLF_LEN + 1);
477         return dset;
478 }
479
480
481 /*
482  * Sets the q parameter of the Request-URI
483  */
484 void set_ruri_q(qvalue_t q)
485 {
486         ruri_q = q;
487 }
488
489
490 /*
491  * Return the q value of the Request-URI
492  */
493 qvalue_t get_ruri_q(void)
494 {
495         return ruri_q;
496 }
497
498
499
500 /*
501  * Get actual Request-URI
502  */
503 int get_request_uri(struct sip_msg* _m, str* _u)
504 {
505              /* Use new_uri if present */
506         if (_m->new_uri.s) {
507                 _u->s = _m->new_uri.s;
508                 _u->len = _m->new_uri.len;
509         } else {
510                 _u->s = _m->first_line.u.request.uri.s;
511                 _u->len = _m->first_line.u.request.uri.len;
512         }
513
514         return 0;
515 }
516
517
518 /*
519  * Rewrite Request-URI
520  */
521 int rewrite_uri(struct sip_msg* _m, str* _s)
522 {
523         char* buf;
524
525         buf = (char*)pkg_malloc(_s->len + 1);
526         if (!buf) {
527                 LOG(L_ERR, "ERROR: rewrite_uri: No memory left\n");
528                 return -1;
529         }
530
531         memcpy(buf, _s->s, _s->len);
532         buf[_s->len] = '\0';
533
534         _m->parsed_uri_ok = 0;
535         if (_m->new_uri.s) {
536                 pkg_free(_m->new_uri.s);
537         }
538
539         _m->new_uri.s = buf;
540         _m->new_uri.len = _s->len;
541
542         DBG("rewrite_uri: Rewriting Request-URI with '%.*s'\n", _s->len, 
543                                                                                                                                                    buf);
544         return 1;
545 }
546