core: Changed WS from being a flag on a TCP/TLS connection to a protocol in its own...
[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 /** destination set / branches support.
31  * @file dset.c
32  * @ingroup core
33  * Module: @ref core
34  */
35
36 #include <string.h>
37 #include "dprint.h"
38 #include "config.h"
39 #include "parser/parser_f.h"
40 #include "parser/msg_parser.h"
41 #include "ut.h"
42 #include "hash_func.h"
43 #include "error.h"
44 #include "dset.h"
45 #include "mem/mem.h"
46 #include "ip_addr.h"
47
48 #define CONTACT "Contact: "
49 #define CONTACT_LEN (sizeof(CONTACT) - 1)
50
51 #define CONTACT_DELIM ", "
52 #define CONTACT_DELIM_LEN (sizeof(CONTACT_DELIM) - 1)
53
54 #define Q_PARAM ">;q="
55 #define Q_PARAM_LEN (sizeof(Q_PARAM) - 1)
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];
63
64 /* how many of them we have */
65 unsigned int nr_branches = 0;
66
67 /* branch iterator */
68 static int branch_iterator = 0;
69
70 /* used to mark ruris "consumed" when branching (1 new, 0 consumed) */
71 int ruri_is_new = 0;
72
73 /* The q parameter of the Request-URI */
74 static qvalue_t ruri_q = Q_UNSPECIFIED;
75
76 /* Branch flags of the Request-URI */
77 static flag_t ruri_bflags;
78
79
80 /*! \brief
81  * Return pointer to branch[idx] structure
82  * @param idx - branch index
83  *
84  * @return  pointer to branch or NULL if invalid branch
85  */
86 branch_t *get_sip_branch(int idx)
87 {
88         if(nr_branches==0)
89                 return NULL;
90         if(idx<0)
91         {
92                 if(nr_branches + idx >= 0)
93                         return &branches[nr_branches+idx];
94                 return NULL;
95         }
96         if(idx < nr_branches)
97                 return &branches[idx];
98         return 0;
99 }
100
101 /*! \brief
102  * Drop branch[idx]
103  * @param idx - branch index
104  *
105  * @return  0 on success, -1 on error
106  */
107 int drop_sip_branch(int idx)
108 {
109         if(nr_branches==0 || idx>=nr_branches)
110                 return 0;
111         if(idx<0 && nr_branches+idx<0)
112                 return 0;
113         /* last branch */
114         if(idx==nr_branches-1)
115         {
116                 nr_branches--;
117                 return 0;
118         }
119         if(idx<0)
120                 idx = nr_branches+idx;
121         /* shift back one position */
122         for(; idx<nr_branches-1; idx++)
123                 memcpy(&branches[idx], &branches[idx+1], sizeof(branch_t));
124         nr_branches--;
125         return 0;
126 }
127
128 static inline flag_t* get_bflags_ptr(unsigned int branch)
129 {
130         if (branch == 0) return &ruri_bflags;
131         if (branch - 1 < nr_branches) return &branches[branch - 1].flags;
132         return NULL;
133 }
134
135
136 int setbflag(unsigned int branch, flag_t flag)
137 {
138         flag_t* flags;
139
140         if ((flags = get_bflags_ptr(branch)) == NULL) return -1;
141         (*flags) |= 1 << flag;
142         return 1;
143 }
144
145
146 int isbflagset(unsigned int branch, flag_t flag)
147 {
148         flag_t* flags;
149
150         if ((flags = get_bflags_ptr(branch)) == NULL) return -1;
151         return ((*flags) & (1 << flag)) ? 1 : -1;
152 }
153
154
155 int resetbflag(unsigned int branch, flag_t flag)
156 {
157         flag_t* flags;
158
159         if ((flags = get_bflags_ptr(branch)) == NULL) return -1;
160         (*flags) &= ~ (1 << flag);
161         return 1;
162 }
163
164
165 int getbflagsval(unsigned int branch, flag_t* res)
166 {
167         flag_t* flags;
168         if (res == NULL) return -1;
169         if ((flags = get_bflags_ptr(branch)) == NULL) return -1;
170         *res = *flags;
171         return 1;
172 }
173
174
175 int setbflagsval(unsigned int branch, flag_t val)
176 {
177         flag_t* flags;
178         if ((flags = get_bflags_ptr(branch)) == NULL) return -1;
179         *flags = val;
180         return 1;
181 }
182
183
184 /*
185  * Initialize the branch iterator, the next
186  * call to next_branch will return the first
187  * contact from the dset array
188  */
189 void init_branch_iterator(void)
190 {
191         branch_iterator = 0;
192 }
193
194 /**
195  * return the value of current branch iterator
196  */
197 int get_branch_iterator(void)
198 {
199         return branch_iterator;
200 }
201
202 /**
203  * set the value of current branch interator
204  */
205 void set_branch_iterator(int n)
206 {
207         branch_iterator = n;
208 }
209
210
211 /** \brief Get a branch from the destination set
212  * \return Return the 'i' branch from the dset
213  * array, 0 is returned if there are no
214  * more branches
215  */
216 char* get_branch(unsigned int i, int* len, qvalue_t* q, str* dst_uri,
217                                  str* path, unsigned int *flags,
218                                  struct socket_info** force_socket)
219 {
220         if (i < nr_branches) {
221                 *len = branches[i].len;
222                 *q = branches[i].q;
223                 if (dst_uri) {
224                         dst_uri->len = branches[i].dst_uri_len;
225                         dst_uri->s = (dst_uri->len)?branches[i].dst_uri:0;
226                 }
227                 if (path) {
228                         path->len = branches[i].path_len;
229                         path->s = (path->len)?branches[i].path:0;
230                 }
231                 if (force_socket)
232                         *force_socket = branches[i].force_send_socket;
233                 if (flags)
234                         *flags = branches[i].flags;
235                 return branches[i].uri;
236         } else {
237                 *len = 0;
238                 *q = Q_UNSPECIFIED;
239                 if (dst_uri) {
240                         dst_uri->s = 0;
241                         dst_uri->len = 0;
242                 }
243                 if (path) {
244                         path->s = 0;
245                         path->len = 0;
246                 }
247                 if (force_socket)
248                         *force_socket = 0;
249                 if (flags)
250                         *flags = 0;
251                 return 0;
252         }
253 }
254
255
256
257 /** Return the next branch from the dset array.
258  * 0 is returned if there are no more branches
259  */
260 char* next_branch(int* len, qvalue_t* q, str* dst_uri, str* path,
261                                         unsigned int* flags, struct socket_info** force_socket)
262 {
263         char* ret;
264         
265         ret=get_branch(branch_iterator, len, q, dst_uri, path, flags,
266                                         force_socket);
267         if (likely(ret))
268                 branch_iterator++;
269         return ret;
270 }
271
272
273 /*
274  * Empty the dset array
275  */
276 void clear_branches(void)
277 {
278         nr_branches = 0;
279         ruri_q = Q_UNSPECIFIED;
280         ruri_bflags = 0;
281         ruri_mark_consumed();
282 }
283
284
285
286 /**  Add a new branch to the current transaction.
287  * @param msg - sip message, used for getting the uri if not specified (0).
288  * @param uri - uri, can be 0 (in which case the uri is taken from msg)
289  * @param dst_uri - destination uri, can be 0.
290  * @param path - path vector (passed in a string), can be 0.
291  * @param q  - q value.
292  * @param flags - per branch flags.
293  * @param force_socket - socket that should be used when sending.
294  *
295  * @return  <0 (-1) on failure, 1 on success (script convention).
296  */
297 int append_branch(struct sip_msg* msg, str* uri, str* dst_uri, str* path,
298                 qvalue_t q, unsigned int flags, struct socket_info* force_socket)
299 {
300         str luri;
301
302         /* if we have already set up the maximum number
303          * of branches, don't try new ones 
304          */
305         if (unlikely(nr_branches == MAX_BRANCHES - 1)) {
306                 LOG(L_ERR, "max nr of branches exceeded\n");
307                 ser_error = E_TOO_MANY_BRANCHES;
308                 return -1;
309         }
310
311         /* if not parameterized, take current uri */
312         if (uri==0 || uri->len==0 || uri->s==0) {
313                 if (msg->new_uri.s)
314                         luri = msg->new_uri;
315                 else
316                         luri = msg->first_line.u.request.uri;
317         } else {
318                 luri = *uri;
319         }
320
321         if (unlikely(luri.len > MAX_URI_SIZE - 1)) {
322                 LOG(L_ERR, "too long uri: %.*s\n", luri.len, luri.s);
323                 return -1;
324         }
325
326         /* copy the dst_uri */
327         if (dst_uri && dst_uri->len && dst_uri->s) {
328                 if (unlikely(dst_uri->len > MAX_URI_SIZE - 1)) {
329                         LOG(L_ERR, "too long dst_uri: %.*s\n", dst_uri->len, dst_uri->s);
330                         return -1;
331                 }
332                 memcpy(branches[nr_branches].dst_uri, dst_uri->s, dst_uri->len);
333                 branches[nr_branches].dst_uri[dst_uri->len] = 0;
334                 branches[nr_branches].dst_uri_len = dst_uri->len;
335         } else {
336                 branches[nr_branches].dst_uri[0] = '\0';
337                 branches[nr_branches].dst_uri_len = 0;
338         }
339
340         /* copy the path string */
341         if (unlikely(path && path->len && path->s)) {
342                 if (unlikely(path->len > MAX_PATH_SIZE - 1)) {
343                         LOG(L_ERR, "too long path: %.*s\n", path->len, path->s);
344                         return -1;
345                 }
346                 memcpy(branches[nr_branches].path, path->s, path->len);
347                 branches[nr_branches].path[path->len] = 0;
348                 branches[nr_branches].path_len = path->len;
349         } else {
350                 branches[nr_branches].path[0] = '\0';
351                 branches[nr_branches].path_len = 0;
352         }
353
354         /* copy the ruri */
355         memcpy(branches[nr_branches].uri, luri.s, luri.len);
356         branches[nr_branches].uri[luri.len] = 0;
357         branches[nr_branches].len = luri.len;
358         branches[nr_branches].q = q;
359
360         branches[nr_branches].force_send_socket = force_socket;
361         branches[nr_branches].flags = flags;
362
363         nr_branches++;
364         return 1;
365 }
366
367
368 /*
369  * Create a Contact header field from the dset
370  * array
371  */
372 char* print_dset(struct sip_msg* msg, int* len) 
373 {
374         int cnt, i;
375         unsigned int qlen;
376         qvalue_t q;
377         str uri;
378         char* p, *qbuf;
379         int crt_branch;
380         static char dset[MAX_REDIRECTION_LEN];
381
382         if (msg->new_uri.s) {
383                 cnt = 1;
384                 *len = msg->new_uri.len;
385                 if (ruri_q != Q_UNSPECIFIED) {
386                         *len += 1 + Q_PARAM_LEN + len_q(ruri_q);
387                 }
388         } else {
389                 cnt = 0;
390                 *len = 0;
391         }
392
393         /* backup current branch index to restore it later */
394         crt_branch = get_branch_iterator();
395
396         init_branch_iterator();
397         while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0, 0))) {
398                 cnt++;
399                 *len += uri.len;
400                 if (q != Q_UNSPECIFIED) {
401                         *len += 1 + Q_PARAM_LEN + len_q(q);
402                 }
403         }
404
405         if (cnt == 0) return 0; 
406
407         *len += CONTACT_LEN + CRLF_LEN + (cnt - 1) * CONTACT_DELIM_LEN;
408
409         if (*len + 1 > MAX_REDIRECTION_LEN) {
410                 LOG(L_ERR, "ERROR: redirection buffer length exceed\n");
411                 goto error;
412         }
413
414         memcpy(dset, CONTACT, CONTACT_LEN);
415         p = dset + CONTACT_LEN;
416         if (msg->new_uri.s) {
417                 if (ruri_q != Q_UNSPECIFIED) {
418                         *p++ = '<';
419                 }
420
421                 memcpy(p, msg->new_uri.s, msg->new_uri.len);
422                 p += msg->new_uri.len;
423
424                 if (ruri_q != Q_UNSPECIFIED) {
425                         memcpy(p, Q_PARAM, Q_PARAM_LEN);
426                         p += Q_PARAM_LEN;
427
428                         qbuf = q2str(ruri_q, &qlen);
429                         memcpy(p, qbuf, qlen);
430                         p += qlen;
431                 }
432                 i = 1;
433         } else {
434                 i = 0;
435         }
436
437         init_branch_iterator();
438         while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0, 0))) {
439                 if (i) {
440                         memcpy(p, CONTACT_DELIM, CONTACT_DELIM_LEN);
441                         p += CONTACT_DELIM_LEN;
442                 }
443
444                 if (q != Q_UNSPECIFIED) {
445                         *p++ = '<';
446                 }
447
448                 memcpy(p, uri.s, uri.len);
449                 p += uri.len;
450                 if (q != Q_UNSPECIFIED) {
451                         memcpy(p, Q_PARAM, Q_PARAM_LEN);
452                         p += Q_PARAM_LEN;
453
454                         qbuf = q2str(q, &qlen);
455                         memcpy(p, qbuf, qlen);
456                         p += qlen;
457                 }
458                 i++;
459         }
460
461         memcpy(p, CRLF " ", CRLF_LEN + 1);
462         set_branch_iterator(crt_branch);
463         return dset;
464
465 error:
466         set_branch_iterator(crt_branch);
467         return 0;
468 }
469
470
471 /*
472  * Sets the q parameter of the Request-URI
473  */
474 void set_ruri_q(qvalue_t q)
475 {
476         ruri_q = q;
477 }
478
479
480 /*
481  * Return the q value of the Request-URI
482  */
483 qvalue_t get_ruri_q(void)
484 {
485         return ruri_q;
486 }
487
488
489
490 /*
491  * Rewrite Request-URI
492  */
493 int rewrite_uri(struct sip_msg* _m, str* _s)
494 {
495         char* buf;
496
497         buf = (char*)pkg_malloc(_s->len + 1);
498         if (!buf) {
499                 LOG(L_ERR, "ERROR: rewrite_uri: No memory left\n");
500                 return -1;
501         }
502
503         memcpy(buf, _s->s, _s->len);
504         buf[_s->len] = '\0';
505
506         _m->parsed_uri_ok = 0;
507         if (_m->new_uri.s) {
508                 pkg_free(_m->new_uri.s);
509         }
510
511         _m->new_uri.s = buf;
512         _m->new_uri.len = _s->len;
513         /* mark ruri as new and available for forking */
514         ruri_mark_new();
515
516         return 1;
517 }
518