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