Merge commit 'origin/andrei/type_conversion'
[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 int get_branch_iterator(void)
159 {
160         return branch_iterator;
161 }
162
163 /*
164  * Return the next branch from the dset
165  * array, 0 is returned if there are no
166  * more branches
167  */
168 char* next_branch(int* len, qvalue_t* q, char** dst_uri, int* dst_len, struct socket_info** force_socket)
169 {
170         unsigned int i;
171
172         i = branch_iterator;
173         if (i < nr_branches) {
174                 branch_iterator++;
175                 *len = branches[i].len;
176                 *q = branches[i].q;
177                 if (dst_uri && dst_len) {
178                         *dst_uri = branches[i].dst_uri;
179                         *dst_len = branches[i].dst_uri_len;
180                 }
181                 if (force_socket) {
182                         *force_socket = branches[i].force_send_socket;
183                 }
184                 return branches[i].uri;
185         } else {
186                 *len = 0;
187                 *q = Q_UNSPECIFIED;
188                 if (dst_uri && dst_len) {
189                         *dst_uri = 0;
190                         *dst_len = 0;
191                 }
192                 if (force_socket) {
193                         *force_socket = 0;
194                 }
195                 return 0;
196         }
197 }
198
199
200 /** \brief Get a branch from the destination set
201  * \return Return the 'i' branch from the dset
202  * array, 0 is returned if there are no
203  * more branches
204  */
205 char* get_branch(unsigned int i, int* len, qvalue_t* q, str* dst_uri,
206                                  str* path, unsigned int *flags, struct socket_info** force_socket)
207 {
208         if (i < nr_branches) {
209                 *len = branches[i].len;
210                 *q = branches[i].q;
211                 if (dst_uri) {
212                         dst_uri->len = branches[i].dst_uri_len;
213                         dst_uri->s = (dst_uri->len)?branches[i].dst_uri:0;
214                 }
215                 if (path) {
216                         path->len = branches[i].path_len;
217                         path->s = (path->len)?branches[i].path:0;
218                 }
219                 if (force_socket)
220                         *force_socket = branches[i].force_send_socket;
221                 if (flags)
222                         *flags = branches[i].flags;
223                 return branches[i].uri;
224         } else {
225                 *len = 0;
226                 *q = Q_UNSPECIFIED;
227                 if (dst_uri) {
228                         dst_uri->s = 0;
229                         dst_uri->len = 0;
230                 }
231                 if (force_socket)
232                         *force_socket = 0;
233                 if (flags)
234                         *flags = 0;
235                 return 0;
236         }
237 }
238
239
240 /*
241  * Empty the dset array
242  */
243 void clear_branches(void)
244 {
245         nr_branches = 0;
246         ruri_q = Q_UNSPECIFIED;
247 }
248
249
250 /* 
251  * Add a new branch to current transaction 
252  */
253 int append_branch(struct sip_msg* msg, char* uri, int uri_len, char* dst_uri, int dst_uri_len, 
254                   qvalue_t q, struct socket_info* force_socket)
255 {
256              /* if we have already set up the maximum number
257               * of branches, don't try new ones 
258               */
259         if (nr_branches == MAX_BRANCHES - 1) {
260                 LOG(L_ERR, "ERROR: append_branch: max nr of branches exceeded\n");
261                 ser_error = E_TOO_MANY_BRANCHES;
262                 return -1;
263         }
264
265         if (uri_len > MAX_URI_SIZE - 1) {
266                 LOG(L_ERR, "ERROR: append_branch: too long uri: %.*s\n",
267                     uri_len, uri);
268                 return -1;
269         }
270         
271         if (dst_uri_len > MAX_URI_SIZE - 1) {
272                 LOG(L_ERR, "ERROR: append_branch: too long dst_uri: %.*s\n",
273                     dst_uri_len, ZSW(dst_uri));
274                 return -1;
275         }
276
277              /* if not parameterized, take current uri */
278         if (uri == 0) {
279                 if (msg->new_uri.s) { 
280                         uri = msg->new_uri.s;
281                         uri_len = msg->new_uri.len;
282                 } else {
283                         uri = msg->first_line.u.request.uri.s;
284                         uri_len = msg->first_line.u.request.uri.len;
285                 }
286         }
287         
288         memcpy(branches[nr_branches].uri, uri, uri_len);
289              /* be safe -- add zero termination */
290         branches[nr_branches].uri[uri_len] = 0;
291         branches[nr_branches].len = uri_len;
292         branches[nr_branches].q = q;
293         
294         if (dst_uri && dst_uri_len) {
295                 memcpy(branches[nr_branches].dst_uri, dst_uri, dst_uri_len);
296                 branches[nr_branches].dst_uri[dst_uri_len] = 0;
297                 branches[nr_branches].dst_uri_len = dst_uri_len;
298         } else {
299                 branches[nr_branches].dst_uri[0] = '\0';
300                 branches[nr_branches].dst_uri_len = 0;
301         }
302
303         branches[nr_branches].force_send_socket = force_socket;
304         
305         nr_branches++;
306         return 1;
307 }
308
309
310 /* ! \brief
311  * Add a new branch to current transaction using str parameters
312  * Kamailio compatibility version
313  */
314 int km_append_branch(struct sip_msg* msg, str* uri, str* dst_uri, str* path,
315                 qvalue_t q, unsigned int flags, struct socket_info* force_socket)
316 {
317         str luri;
318
319 #ifdef USE_LOCAL_ROUTE
320         if (dset_state==0)
321                 return -1;
322 #endif
323
324         /* if we have already set up the maximum number
325          * of branches, don't try new ones 
326          */
327         if (nr_branches == MAX_BRANCHES - 1) {
328                 LOG(L_ERR, "max nr of branches exceeded\n");
329                 ser_error = E_TOO_MANY_BRANCHES;
330                 return -1;
331         }
332
333         /* if not parameterized, take current uri */
334         if (uri==0 || uri->len==0 || uri->s==0) {
335                 if (msg->new_uri.s)
336                         luri = msg->new_uri;
337                 else
338                         luri = msg->first_line.u.request.uri;
339         } else {
340                 luri = *uri;
341         }
342
343         if (luri.len > MAX_URI_SIZE - 1) {
344                 LOG(L_ERR, "too long uri: %.*s\n", luri.len, luri.s);
345                 return -1;
346         }
347
348         /* copy the dst_uri */
349         if (dst_uri && dst_uri->len && dst_uri->s) {
350                 if (dst_uri->len > MAX_URI_SIZE - 1) {
351                         LOG(L_ERR, "too long dst_uri: %.*s\n",
352                                 dst_uri->len, dst_uri->s);
353                         return -1;
354                 }
355                 memcpy(branches[nr_branches].dst_uri, dst_uri->s, dst_uri->len);
356                 branches[nr_branches].dst_uri[dst_uri->len] = 0;
357                 branches[nr_branches].dst_uri_len = dst_uri->len;
358         } else {
359                 branches[nr_branches].dst_uri[0] = '\0';
360                 branches[nr_branches].dst_uri_len = 0;
361         }
362
363         /* copy the path string */
364         if (path && path->len && path->s) {
365                 if (path->len > MAX_PATH_SIZE - 1) {
366                         LOG(L_ERR, "too long path: %.*s\n", path->len, path->s);
367                         return -1;
368                 }
369                 memcpy(branches[nr_branches].path, path->s, path->len);
370                 branches[nr_branches].path[path->len] = 0;
371                 branches[nr_branches].path_len = path->len;
372         } else {
373                 branches[nr_branches].path[0] = '\0';
374                 branches[nr_branches].path_len = 0;
375         }
376
377         /* copy the ruri */
378         memcpy(branches[nr_branches].uri, luri.s, luri.len);
379         branches[nr_branches].uri[luri.len] = 0;
380         branches[nr_branches].len = luri.len;
381         branches[nr_branches].q = q;
382
383         branches[nr_branches].force_send_socket = force_socket;
384         branches[nr_branches].flags = flags;
385
386         nr_branches++;
387         return 1;
388 }
389
390
391 /*
392  * Create a Contact header field from the dset
393  * array
394  */
395 char* print_dset(struct sip_msg* msg, int* len) 
396 {
397         int cnt, i;
398         unsigned int qlen;
399         qvalue_t q;
400         str uri;
401         char* p, *qbuf;
402         static char dset[MAX_REDIRECTION_LEN];
403
404         if (msg->new_uri.s) {
405                 cnt = 1;
406                 *len = msg->new_uri.len;
407                 if (ruri_q != Q_UNSPECIFIED) {
408                         *len += 1 + Q_PARAM_LEN + len_q(ruri_q);
409                 }
410         } else {
411                 cnt = 0;
412                 *len = 0;
413         }
414
415         init_branch_iterator();
416         while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0))) {
417                 cnt++;
418                 *len += uri.len;
419                 if (q != Q_UNSPECIFIED) {
420                         *len += 1 + Q_PARAM_LEN + len_q(q);
421                 }
422         }
423
424         if (cnt == 0) return 0; 
425
426         *len += CONTACT_LEN + CRLF_LEN + (cnt - 1) * CONTACT_DELIM_LEN;
427
428         if (*len + 1 > MAX_REDIRECTION_LEN) {
429                 LOG(L_ERR, "ERROR: redirection buffer length exceed\n");
430                 return 0;
431         }
432
433         memcpy(dset, CONTACT, CONTACT_LEN);
434         p = dset + CONTACT_LEN;
435         if (msg->new_uri.s) {
436                 if (ruri_q != Q_UNSPECIFIED) {
437                         *p++ = '<';
438                 }
439
440                 memcpy(p, msg->new_uri.s, msg->new_uri.len);
441                 p += msg->new_uri.len;
442
443                 if (ruri_q != Q_UNSPECIFIED) {
444                         memcpy(p, Q_PARAM, Q_PARAM_LEN);
445                         p += Q_PARAM_LEN;
446
447                         qbuf = q2str(ruri_q, &qlen);
448                         memcpy(p, qbuf, qlen);
449                         p += qlen;
450                 }
451                 i = 1;
452         } else {
453                 i = 0;
454         }
455
456         init_branch_iterator();
457         while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0))) {
458                 if (i) {
459                         memcpy(p, CONTACT_DELIM, CONTACT_DELIM_LEN);
460                         p += CONTACT_DELIM_LEN;
461                 }
462
463                 if (q != Q_UNSPECIFIED) {
464                         *p++ = '<';
465                 }
466
467                 memcpy(p, uri.s, uri.len);
468                 p += uri.len;
469                 if (q != Q_UNSPECIFIED) {
470                         memcpy(p, Q_PARAM, Q_PARAM_LEN);
471                         p += Q_PARAM_LEN;
472
473                         qbuf = q2str(q, &qlen);
474                         memcpy(p, qbuf, qlen);
475                         p += qlen;
476                 }
477                 i++;
478         }
479
480         memcpy(p, CRLF " ", CRLF_LEN + 1);
481         return dset;
482 }
483
484
485 /*
486  * Sets the q parameter of the Request-URI
487  */
488 void set_ruri_q(qvalue_t q)
489 {
490         ruri_q = q;
491 }
492
493
494 /*
495  * Return the q value of the Request-URI
496  */
497 qvalue_t get_ruri_q(void)
498 {
499         return ruri_q;
500 }
501
502
503
504 /*
505  * Get actual Request-URI
506  */
507 int get_request_uri(struct sip_msg* _m, str* _u)
508 {
509              /* Use new_uri if present */
510         if (_m->new_uri.s) {
511                 _u->s = _m->new_uri.s;
512                 _u->len = _m->new_uri.len;
513         } else {
514                 _u->s = _m->first_line.u.request.uri.s;
515                 _u->len = _m->first_line.u.request.uri.len;
516         }
517
518         return 0;
519 }
520
521
522 /*
523  * Rewrite Request-URI
524  */
525 int rewrite_uri(struct sip_msg* _m, str* _s)
526 {
527         char* buf;
528
529         buf = (char*)pkg_malloc(_s->len + 1);
530         if (!buf) {
531                 LOG(L_ERR, "ERROR: rewrite_uri: No memory left\n");
532                 return -1;
533         }
534
535         memcpy(buf, _s->s, _s->len);
536         buf[_s->len] = '\0';
537
538         _m->parsed_uri_ok = 0;
539         if (_m->new_uri.s) {
540                 pkg_free(_m->new_uri.s);
541         }
542
543         _m->new_uri.s = buf;
544         _m->new_uri.len = _s->len;
545
546         DBG("rewrite_uri: Rewriting Request-URI with '%.*s'\n", _s->len, 
547                                                                                                                                                    buf);
548         return 1;
549 }
550