117f5771b04e0829d5ce49f2422dd7e9c60a2cd3
[sip-router] / dset.c
1 /*
2  * $Id$
3  *
4  * destination set
5  */
6
7 #include <string.h>
8
9 #include "dprint.h"
10 #include "config.h"
11 #include "parser/parser_f.h"
12 #include "parser/msg_parser.h"
13 #include "ut.h"
14 #include "hash_func.h"
15 #include "dset.h"
16
17
18
19 /* where we store URIs of additional transaction branches
20   (-1 because of the default branch, #0)
21 */
22 static struct branch branches[ MAX_BRANCHES - 1 ];
23 /* how many of them we have */
24 static unsigned int nr_branches=0;
25 /* branch iterator */
26 static int branch_iterator=0;
27
28 void init_branch_iterator(void)
29 {
30         branch_iterator=0;
31 }
32
33 char *next_branch( int *len )
34 {
35         unsigned int i;
36
37         i=branch_iterator;
38         if (i<nr_branches) {
39                 branch_iterator++;
40                 *len=branches[i].len;
41                 return branches[i].uri;
42         } else {
43                 *len=0;
44                 return 0;
45         }
46 }
47
48 void clear_branches()
49 {
50         nr_branches=0;
51 }
52
53 /* add a new branch to current transaction */
54 int append_branch( struct sip_msg *msg, char *uri, int uri_len )
55 {
56         /* if we have already set up the maximum number
57            of branches, don't try new ones */
58         if (nr_branches==MAX_BRANCHES-1) {
59                 LOG(L_ERR, "ERROR: append_branch: max nr of branches exceeded\n");
60                 return -1;
61         }
62
63         if (uri_len>MAX_URI_SIZE-1) {
64                 LOG(L_ERR, "ERROR: append_branch: too long uri: %.*s\n",
65                         uri_len, uri );
66                 return -1;
67         }
68
69         /* if not parameterized, take current uri */
70         if (uri==0) {
71                 if (msg->new_uri.s) { 
72                         uri=msg->new_uri.s;
73                         uri_len=msg->new_uri.len;
74                 } else {
75                         uri=msg->first_line.u.request.uri.s;
76                         uri_len=msg->first_line.u.request.uri.len;
77                 }
78         }
79         
80         memcpy( branches[nr_branches].uri, uri, uri_len );
81         /* be safe -- add zero termination */
82         branches[nr_branches].uri[uri_len]=0;
83         branches[nr_branches].len=uri_len;
84         
85         nr_branches++;
86         return 1;
87 }
88
89
90
91 char *print_dset( struct sip_msg *msg, int *len ) 
92 {
93         int cnt;
94         str uri;
95         char *p;
96         int i;
97         static char dset[MAX_REDIRECTION_LEN];
98
99         if (msg->new_uri.s) {
100                 cnt=1;
101                 *len=msg->new_uri.len;
102         } else {
103                 cnt=0;
104                 *len=0;
105         }
106
107         init_branch_iterator();
108         while ((uri.s=next_branch(&uri.len))) {
109                 cnt++;
110                 *len+=uri.len;
111         }
112
113         if (cnt==0) return 0;   
114
115         *len+=CONTACT_LEN+CRLF_LEN+(cnt-1)*CONTACT_DELIM_LEN;
116
117         if (*len+1>MAX_REDIRECTION_LEN) {
118                 LOG(L_ERR, "ERROR: redirection buffer length exceed\n");
119                 return 0;
120         }
121
122         memcpy(dset, CONTACT, CONTACT_LEN );
123         p=dset+CONTACT_LEN;
124         if (msg->new_uri.s) {
125                 memcpy(p, msg->new_uri.s, msg->new_uri.len);
126                 p+=msg->new_uri.len;
127                 i=1;
128         } else i=0;
129
130         init_branch_iterator();
131         while ((uri.s=next_branch(&uri.len))) {
132                 if (i) {
133                         memcpy(p, CONTACT_DELIM, CONTACT_DELIM_LEN );
134                         p+=2;
135                 }
136                 memcpy(p, uri.s, uri.len);
137                 p+=uri.len;
138                 i++;
139         }
140         memcpy(p, CRLF " ", CRLF_LEN+1);
141         return dset;
142 }
143