- more warning & cosmetic fixes
[sip-router] / modules / tm / t_fwd.c
1 /*
2  * $Id$
3  *
4  *
5  * Copyright (C) 2001-2003 Fhg Fokus
6  *
7  * This file is part of ser, a free SIP server.
8  *
9  * ser is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version
13  *
14  * For a license to use the ser software under conditions
15  * other than those described here, or to purchase support for this
16  * software, please contact iptel.org by e-mail at the following addresses:
17  *    info@iptel.org
18  *
19  * ser is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License 
25  * along with this program; if not, write to the Free Software 
26  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27  */
28
29
30 #include "../../dprint.h"
31 #include "../../config.h"
32 #include "../../parser/parser_f.h"
33 #include "../../ut.h"
34 #include "../../timer.h"
35 #include "../../hash_func.h"
36 #include "../../globals.h"
37 #include "../../dset.h"
38 #include "t_funcs.h"
39 #include "t_hooks.h"
40 #include "t_msgbuilder.h"
41 #include "ut.h"
42 #include "t_cancel.h"
43 #include "t_lookup.h"
44 #include "t_fwd.h"
45 #include "fix_lumps.h"
46 #include "config.h"
47
48
49 #ifdef _OBSOLETED
50 #define shm_free_lump( _lmp) \
51         do{\
52                 if ((_lmp)) {\
53                         if ((_lmp)->op==LUMP_ADD && (_lmp)->u.value )\
54                                 shm_free((_lmp)->u.value);\
55                         shm_free((_lmp));\
56                 }\
57         }while(0);
58 #endif
59
60 char *print_uac_request( struct cell *t, struct sip_msg *i_req,
61         int branch, str *uri, unsigned int *len, struct socket_info *send_sock )
62 {
63         char *buf, *shbuf;
64
65         shbuf=0;
66
67         /* ... we calculate branch ... */       
68         if (!t_setbranch( t, i_req, branch )) {
69                 LOG(L_ERR, "ERROR: print_uac_request: branch computation failed\n");
70                 goto error01;
71         }
72
73         /* ... update uri ... */
74         i_req->new_uri=*uri;
75
76         /* ... give apps a chance to change things ... */
77         callback_event( TMCB_REQUEST_OUT, t, i_req, -i_req->REQ_METHOD);
78
79         /* ... and build it now */
80         buf=build_req_buf_from_sip_req( i_req, len, send_sock );
81 #ifdef DBG_MSG_QA
82         if (buf[*len-1]==0) {
83                 LOG(L_ERR, "ERROR: print_uac_request: sanity check failed\n");
84                 abort();
85         }
86 #endif
87         if (!buf) {
88                 LOG(L_ERR, "ERROR: print_uac_request: no pkg_mem\n"); 
89                 ser_error=E_OUT_OF_MEM;
90                 goto error01;
91         }
92         /*      clean Via's we created now -- they would accumulate for
93                 other branches  and for  shmem i_req they would mix up
94                 shmem with pkg_mem
95         */
96 #ifdef OBSOLETED
97         if (branch) for(b=i_req->add_rm,b1=0;b;b1=b,b=b->next)
98                 if (b->type==HDR_VIA) {
99                         for(a=b->before;a;)
100                                 {c=a->before;free_lump(a);pkg_free(a);a=c;}
101                         for(a=b->after;a;)
102                                 {c=a->after;free_lump(a);pkg_free(a);a=c;}
103                         if (b1) b1->next = b->next;
104                         else i_req->add_rm = b->next;
105                         free_lump(b);pkg_free(b);
106                 }
107 #endif
108         free_via_lump(&i_req->add_rm);
109
110         shbuf=(char *)shm_malloc(*len);
111         if (!shbuf) {
112                 ser_error=E_OUT_OF_MEM;
113                 LOG(L_ERR, "ERROR: print_uac_request: no shmem\n");
114                 goto error02;
115         }
116         memcpy( shbuf, buf, *len );
117
118 error02:
119         pkg_free( buf );
120 error01:
121         return shbuf;
122 }
123
124 /* introduce a new uac to transaction; returns its branch id (>=0)
125    or error (<0); it doesn't send a message yet -- a reply to it
126    might itnerfere with the processes of adding multiple branches
127 */
128 int add_uac( struct cell *t, struct sip_msg *request, str *uri, 
129         struct proxy_l *proxy )
130 {
131
132         int ret;
133         short temp_proxy;
134         union sockaddr_union to;
135         unsigned short branch;
136         struct socket_info* send_sock;
137         char *shbuf;
138         unsigned int len;
139
140         branch=t->nr_of_outgoings;
141         if (branch==MAX_BRANCHES) {
142                 LOG(L_ERR, "ERROR: add_uac: maximum number of branches exceeded\n");
143                 ret=E_CFG;
144                 goto error;
145         }
146
147         /* check existing buffer -- rewriting should never occur */
148         if (t->uac[branch].request.buffer) {
149                 LOG(L_CRIT, "ERROR: add_uac: buffer rewrite attempt\n");
150                 ret=ser_error=E_BUG;
151                 goto error;
152         }
153
154         /* check DNS resolution */
155         if (proxy) temp_proxy=0; else {
156                 proxy=uri2proxy( uri );
157                 if (proxy==0)  {
158                         ret=E_BAD_ADDRESS;
159                         goto error;
160                 }
161                 temp_proxy=1;
162         }
163
164         if (proxy->ok==0) {
165                 if (proxy->host.h_addr_list[proxy->addr_idx+1])
166                         proxy->addr_idx++;
167                 else proxy->addr_idx=0;
168                 proxy->ok=1;
169         }
170
171         hostent2su( &to, &proxy->host, proxy->addr_idx, 
172                 proxy->port ? htons(proxy->port):htons(SIP_PORT));
173
174         send_sock=get_send_socket( &to );
175         if (send_sock==0) {
176                 LOG(L_ERR, "ERROR: add_uac: can't fwd to af %d "
177                         " (no corresponding listening socket)\n",
178                         to.s.sa_family );
179                 ret=ser_error=E_NO_SOCKET;
180                 goto error01;
181         }
182
183         /* now message printing starts ... */
184         shbuf=print_uac_request( t, request, branch, uri, 
185                 &len, send_sock );
186         if (!shbuf) {
187                 ret=ser_error=E_OUT_OF_MEM;
188                 goto error01;
189         }
190
191         /* things went well, move ahead and install new buffer! */
192         t->uac[branch].request.to=to;
193         t->uac[branch].request.send_sock=send_sock;
194         t->uac[branch].request.buffer=shbuf;
195         t->uac[branch].request.buffer_len=len;
196         t->uac[branch].uri.s=t->uac[branch].request.buffer+
197                 request->first_line.u.request.method.len+1;
198         t->uac[branch].uri.len=uri->len;
199         t->nr_of_outgoings++;
200
201         /* update stats */
202         proxy->tx++;
203         proxy->tx_bytes+=len;
204
205         /* done! */     
206         ret=branch;
207                 
208 error01:
209         if (temp_proxy) {
210                 free_proxy( proxy );
211                 free( proxy );
212         }
213 error:
214         return ret;
215 }
216
217 int e2e_cancel_branch( struct sip_msg *cancel_msg, struct cell *t_cancel, 
218         struct cell *t_invite, int branch )
219 {
220         int ret;
221         char *shbuf;
222         unsigned int len;
223
224         if (t_cancel->uac[branch].request.buffer) {
225                 LOG(L_CRIT, "ERROR: e2e_cancel_branch: buffer rewrite attempt\n");
226                 ret=ser_error=E_BUG;
227                 goto error;
228         }       
229
230         /* note -- there is a gap in proxy stats -- we don't update 
231            proxy stats with CANCEL (proxy->ok, proxy->tx, etc.)
232         */
233
234         /* print */
235         shbuf=print_uac_request( t_cancel, cancel_msg, branch, 
236                 &t_invite->uac[branch].uri, &len, 
237                 t_invite->uac[branch].request.send_sock);
238         if (!shbuf) {
239                 LOG(L_ERR, "ERROR: e2e_cancel_branch: printing e2e cancel failed\n");
240                 ret=ser_error=E_OUT_OF_MEM;
241                 goto error;
242         }
243         
244         /* install buffer */
245         t_cancel->uac[branch].request.to=t_invite->uac[branch].request.to;
246         t_cancel->uac[branch].request.send_sock=t_invite->uac[branch].request.send_sock;
247         t_cancel->uac[branch].request.buffer=shbuf;
248         t_cancel->uac[branch].request.buffer_len=len;
249         t_cancel->uac[branch].uri.s=t_cancel->uac[branch].request.buffer+
250                 cancel_msg->first_line.u.request.method.len+1;
251         t_cancel->uac[branch].uri.len=t_invite->uac[branch].uri.len;
252         
253
254         /* success */
255         ret=1;
256
257
258 error:
259         return ret;
260 }
261
262 void e2e_cancel( struct sip_msg *cancel_msg, 
263         struct cell *t_cancel, struct cell *t_invite )
264 {
265         branch_bm_t cancel_bm;
266         int i;
267         int lowest_error;
268         str backup_uri;
269         int ret;
270
271         cancel_bm=0;
272         lowest_error=0;
273
274         backup_uri=cancel_msg->new_uri;
275         /* determine which branches to cancel ... */
276         which_cancel( t_invite, &cancel_bm );
277         t_cancel->nr_of_outgoings=t_invite->nr_of_outgoings;
278         /* fix label -- it must be same for reply matching */
279         t_cancel->label=t_invite->label;
280         /* ... and install CANCEL UACs */
281         for (i=0; i<t_invite->nr_of_outgoings; i++)
282                 if (cancel_bm & (1<<i)) {
283                         ret=e2e_cancel_branch(cancel_msg, t_cancel, t_invite, i);
284                         if (ret<0) cancel_bm &= ~(1<<i);
285                         if (ret<lowest_error) lowest_error=ret;
286                 }
287         cancel_msg->new_uri=backup_uri;
288
289         /* send them out */
290         for (i=0; i<t_cancel->nr_of_outgoings; i++) {
291                 if (cancel_bm & (1<<i)) {
292                         if (SEND_BUFFER( &t_cancel->uac[i].request)==-1) {
293                                 LOG(L_ERR, "ERROR: e2e_cancel: send failed\n");
294                         }
295                         start_retr( &t_cancel->uac[i].request );
296                 }
297         }
298
299
300         /* if error occured, let it know upstream (final reply
301            will also move the transaction on wait state
302         */
303         if (lowest_error<0) {
304                 LOG(L_ERR, "ERROR: cancel error\n");
305                 t_reply( t_cancel, cancel_msg, 500, "cancel error");
306         /* if there are pending branches, let upstream know we
307            are working on it
308         */
309         } else if (cancel_bm) {
310                 DBG("DEBUG: e2e_cancel: e2e cancel proceeding\n");
311                 t_reply( t_cancel, cancel_msg, 200, CANCELLING );
312         /* if the transaction exists, but there is no more pending
313            branch, tell usptream we're done
314         */
315         } else {
316                 DBG("DEBUG: e2e_cancel: e2e cancel -- no more pending branches\n");
317                 t_reply( t_cancel, cancel_msg, 200, CANCEL_DONE );
318         }
319         /* we could await downstream UAS's 487 replies; however,
320            if some of the branches does not do that, we could wait
321            long time and annoy upstream UAC which wants to see 
322            a result of CANCEL quickly
323         */
324         DBG("DEBUG: e2e_cancel: sending 487\n");
325         t_reply(t_invite, t_invite->uas.request, 487, CANCELLED );
326 }
327
328
329 /* function returns:
330  *       1 - forward successfull
331  *      -1 - error during forward
332  */
333 int t_forward_nonack( struct cell *t, struct sip_msg* p_msg , 
334         struct proxy_l * proxy )
335 {
336         str          backup_uri;
337         int branch_ret, lowest_ret;
338         str current_uri;
339         branch_bm_t     added_branches;
340         int first_branch;
341         int i;
342         struct cell *t_invite;
343
344         /* make -Wall happy */
345         current_uri.s=0;
346
347         t->kr|=REQ_FWDED;
348
349         if (p_msg->REQ_METHOD==METHOD_CANCEL) {
350                 t_invite=t_lookupOriginalT(  p_msg );
351                 if (t_invite!=T_NULL) {
352                         e2e_cancel( p_msg, t, t_invite );
353                         UNREF(t_invite);
354                         return 1;
355                 }
356         }
357
358         /* backup current uri ... add_uac changes it */
359         backup_uri = p_msg->new_uri;
360         /* if no more specific error code is known, use this */
361         lowest_ret=E_BUG;
362         /* branches added */
363         added_branches=0;
364         /* branch to begin with */
365         first_branch=t->nr_of_outgoings;
366
367         /* on first-time forwarding, use current uri, later only what
368            is in additional branches (which may be continuously refilled
369         */
370         if (first_branch==0) {
371                 branch_ret=add_uac( t, p_msg, 
372                         p_msg->new_uri.s ? &p_msg->new_uri :  
373                                 &p_msg->first_line.u.request.uri,
374                         proxy );
375                 if (branch_ret>=0) 
376                         added_branches |= 1<<branch_ret;
377                 else
378                         lowest_ret=branch_ret;
379         }
380
381         init_branch_iterator();
382         while((current_uri.s=next_branch( &current_uri.len))) {
383                 branch_ret=add_uac( t, p_msg, &current_uri, proxy );
384                 /* pick some of the errors in case things go wrong;
385                    note that picking lowest error is just as good as
386                    any other algorithm which picks any other negative
387                    branch result */
388                 if (branch_ret>=0) 
389                         added_branches |= 1<<branch_ret;
390                 else
391                         lowest_ret=branch_ret;
392         }
393         /* consume processed branches */
394         clear_branches();
395
396         /* restore original URI */
397         p_msg->new_uri=backup_uri;
398
399         /* don't forget to clear all branches processed so far */
400
401         /* things went wrong ... no new branch has been fwd-ed at all */
402         if (added_branches==0)
403                 return lowest_ret;
404
405         /* if someone set on_negative, store in in T-context */
406         t->on_negative=get_on_negative();
407
408         /* send them out now */
409         for (i=first_branch; i<t->nr_of_outgoings; i++) {
410                 if (added_branches & (1<<i)) {
411                         if (SEND_BUFFER( &t->uac[i].request)==-1) {
412                                 LOG(L_ERR, "ERROR: add_uac: sending request failed\n");
413                                 if (proxy) { proxy->errors++; proxy->ok=0; }
414                         }
415                         start_retr( &t->uac[i].request );
416                 }
417         }
418         return 1;
419 }       
420
421 int t_replicate(struct sip_msg *p_msg,  struct proxy_l *proxy )
422 {
423         /* this is a quite horrible hack -- we just take the message
424            as is, including Route-s, Record-route-s, and Vias ,
425            forward it downstream and prevent replies received
426            from relaying by setting the replication/local_trans bit;
427
428                 nevertheless, it should be good enough for the primary
429                 customer of this function, REGISTER replication
430
431                 if we want later to make it thoroughly, we need to
432                 introduce delete lumps for all the header fields above
433         */
434         return t_relay_to(p_msg, proxy, 1 /* replicate */);
435 }