53d13a60095546e489a61e1751a5d1701ccaf14f
[sip-router] / modules / tm / t_fwd.c
1 /*
2  * $Id$
3  *
4  */
5
6 #include "hash_func.h"
7 #include "t_funcs.h"
8 #include "../../dprint.h"
9 #include "../../config.h"
10 #include "../../parser/parser_f.h"
11 #include "../../ut.h"
12 #include "../../timer.h"
13
14 #include "t_hooks.h"
15
16
17 #define shm_free_lump( _lmp) \
18         do{\
19                 if ((_lmp)) {\
20                         if ((_lmp)->op==LUMP_ADD && (_lmp)->u.value )\
21                                 shm_free((_lmp)->u.value);\
22                         shm_free((_lmp));\
23                 }\
24         }while(0);
25
26
27
28 /* function returns:
29  *       1 - forward successfull
30  *      -1 - error during forward
31  */
32 int t_forward_nonack( struct sip_msg* p_msg , unsigned int dest_ip_param ,
33                                                                                                 unsigned int dest_port_param )
34 {
35         int          branch;
36         unsigned int len;
37         char         *buf, *shbuf;
38         struct cell  *T_source = T;
39         struct lump  *a,*b,*b1,*c;
40         str          backup_uri;
41
42
43         buf    = 0;
44         shbuf  = 0;
45         backup_uri.s = p_msg->new_uri.s;
46         backup_uri.len = p_msg->new_uri.len;
47
48         /* sets as first fork the default outgoing */
49         nr_forks++;
50         t_forks[0].ip = dest_ip_param;
51         t_forks[0].port = dest_port_param;
52         t_forks[0].uri.len = p_msg->new_uri.len;
53         t_forks[0].uri.s =  p_msg->new_uri.s;
54         t_forks[0].free_flag = 0;
55
56
57         /* are we forwarding for the first time? */
58         if ( T->uac[0].request.buffer )
59         {       /* rewriting a request should really not happen -- retransmission
60                    does not rewrite, whereas a new request should be written
61                    somewhere else */
62                 LOG( L_CRIT, "ERROR: t_forward_nonack: attempt to rewrite"
63                         " request structures\n");
64                 return 0;
65         }
66
67         DBG("DEBUG: t_forward_nonack: first time forwarding\n");
68         /* special case : CANCEL */
69         if ( p_msg->REQ_METHOD==METHOD_CANCEL  )
70         {
71                 DBG("DEBUG: t_forward_nonack: it's CANCEL\n");
72                 /* find original cancelled transaction; if found, use its
73                    next-hops; otherwise use those passed by script */
74                 if ( T->T_canceled==T_UNDEFINED )
75                         T->T_canceled = t_lookupOriginalT( hash_table , p_msg );
76                 /* if found */
77                 if ( T->T_canceled!=T_NULL )
78                 {
79                         for(nr_forks=0;nr_forks<T->T_canceled->nr_of_outgoings;nr_forks++)
80                         {
81                                 /* if in 1xx status, send to the same destination */
82                                 if ( (T->T_canceled->uac[nr_forks].status/100)==1 )
83                                 {
84                                         DBG("DEBUG: t_forward_nonack: branch %d not finalize"
85                                                 ": sending CANCEL for it\n",nr_forks);
86                                         t_forks[nr_forks].ip =
87                                           T->T_canceled->uac[nr_forks].request.to.sin_addr.s_addr;
88                                         t_forks[nr_forks].port =
89                                           T->T_canceled->uac[nr_forks].request.to.sin_port;
90                                         t_forks[nr_forks].uri.len =
91                                           T->T_canceled->uac[nr_forks].uri.len;
92                                         t_forks[nr_forks].uri.s =
93                                           T->T_canceled->uac[nr_forks].uri.s;
94                                         t_forks[nr_forks].free_flag = 0;
95                                 }else{
96                                         /* transaction exists, but nothing to cancel */
97                                         DBG("DEBUG: t_forward_nonack: branch %d finalized"
98                                                 ": no CANCEL sent here\n",nr_forks);
99                                         t_forks[nr_forks].ip = 0;
100                                 }
101                         }
102 #ifdef USE_SYNONIM
103                         T_source = T->T_canceled;
104                         T->label  = T->T_canceled->label;
105 #endif
106                 } else { /* transaction doesnot exists  */
107                         DBG("DEBUG: t_forward_nonack: canceled request not found! "
108                         "nothing to CANCEL\n");
109                 }
110         }/* end special case CANCEL*/
111
112 #ifndef USE_SYNONIM
113         if ( nr_forks && add_branch_label( T_source, T->uas.request , 0 )==-1)
114                 goto error;
115 #endif
116
117         DBG("DEBUG: t_forward_nonack: nr_forks=%d\n",nr_forks);
118         for(branch=0;branch<nr_forks;branch++)
119         {
120                 if (!t_forks[branch].ip)
121                         goto end_loop;
122                 DBG("DEBUG: t_forward_nonack: branch = %d\n",branch);
123                 /*generates branch param*/
124                 if ( add_branch_label( T_source, p_msg , branch )==-1)
125                         goto error;
126                 /* remove all the HDR_VIA type lumps */
127                 if (branch)
128                         for(b=p_msg->add_rm,b1=0;b;b1=b,b=b->next)
129                                 if (b->type==HDR_VIA)
130                                 {
131                                         for(a=b->before;a;)
132                                                 {c=a->before;free_lump(a);pkg_free(a);a=c;}
133                                         for(a=b->after;a;)
134                                                 {c=a->after;free_lump(a);pkg_free(a);a=c;}
135                                         if (b1) b1->next = b->next;
136                                                 else p_msg->add_rm = b->next;
137                                         free_lump(b);pkg_free(b);
138                                 }
139                 /* updates the new uri*/
140                 p_msg->new_uri.s = t_forks[branch].uri.s;
141                 p_msg->new_uri.len = t_forks[branch].uri.len;
142                 if ( !(buf = build_req_buf_from_sip_req  ( p_msg, &len)))
143                         goto error;
144                 /* allocates a new retrans_buff for the outbound request */
145                 DBG("DEBUG: t_forward_nonack: building outbound request"
146                         " for branch %d.\n",branch);
147                 shbuf = (char *) shm_malloc( len );
148                 if (!shbuf)
149                 {
150                         LOG(L_ERR, "ERROR: t_forward_nonack: out of shmem buffer\n");
151                         goto error;
152                 }
153                 T->uac[branch].request.buffer = shbuf;
154                 T->uac[branch].request.buffer_len = len ;
155                 memcpy( T->uac[branch].request.buffer , buf , len );
156                 /* keeps a hooker to uri inside buffer*/
157                 T->uac[branch].uri.s = T->uac[branch].request.buffer +
158                         (p_msg->first_line.u.request.uri.s - p_msg->buf);
159                 T->uac[branch].uri.len=t_forks[branch].uri.s?(t_forks[branch].uri.len)
160                         :(p_msg->first_line.u.request.uri.len);
161                 /* send the request */
162                 T->uac[branch].request.to.sin_addr.s_addr = t_forks[branch].ip;
163                 T->uac[branch].request.to.sin_port = t_forks[branch].port;
164                 T->uac[branch].request.to.sin_family = AF_INET;
165                 SEND_BUFFER( &(T->uac[branch].request) );
166
167                 pkg_free( buf ) ;
168                 buf=NULL;
169
170                 DBG("DEBUG: t_forward_nonack: starting timers (retrans and FR) %d\n",
171                         get_ticks() );
172                 /*sets and starts the FINAL RESPONSE timer */
173                 set_timer( hash_table, &(T->uac[branch].request.fr_timer),
174                 /*p_msg->REQ_METHOD==METHOD_INVITE?FR_INV_TIMER_LIST:FR_TIMER_LIST);*/
175                         FR_TIMER_LIST ); 
176                 /* sets and starts the RETRANS timer */
177                 T->uac[branch].request.retr_list = RT_T1_TO_1;
178                 set_timer( hash_table, &(T->uac[branch].request.retr_timer),
179                         RT_T1_TO_1 );
180                 end_loop:
181                 T->nr_of_outgoings++ ;
182                 DBG("DEBUG: branch %d done; outgoing uri=|%.*s|\n",branch,
183                         T->uac[branch].uri.len,T->uac[branch].uri.s);
184         }
185
186         /* if we have a branch spec. for NO_RESPONSE_RECEIVED, we have to 
187         move it immediatly after the last parallel branch */
188         if (t_forks[NO_RPL_BRANCH].ip && T->nr_of_outgoings!=NO_RPL_BRANCH )
189         {
190                 branch = T->nr_of_outgoings;
191                 T->uac[branch].request.to.sin_addr.s_addr = t_forks[NO_RPL_BRANCH].ip;
192                 T->uac[branch].request.to.sin_port = t_forks[NO_RPL_BRANCH].port;
193                 T->uac[branch].uri.s = t_forks[NO_RPL_BRANCH].uri.s;
194                 T->uac[branch].uri.len = t_forks[NO_RPL_BRANCH].uri.len;
195         }
196         p_msg->new_uri.s = backup_uri.s;
197         p_msg->new_uri.len = backup_uri.len;
198         t_clear_forks();
199         return 1;
200
201 error:
202         if (shbuf) shm_free(shbuf);
203         T->uac[branch].request.buffer=NULL;
204         if (buf) pkg_free( buf );
205         p_msg->new_uri.s = backup_uri.s;
206         p_msg->new_uri.len = backup_uri.len;
207         t_clear_forks();
208         return -1;
209 }
210
211
212
213
214 int t_forward_ack( struct sip_msg* p_msg , unsigned int dest_ip_param ,
215                                                                                 unsigned int dest_port_param )
216 {
217         int branch;
218         unsigned int len;
219         char *buf, *ack;
220 #ifdef _DONT_USE
221         struct sockaddr_in to_sock;
222 #endif
223
224
225         /* drop local ACKs */
226         if (T->uas.status/100!=2 ) {
227                 DBG("DEBUG: t_forward_ACK:  local ACK dropped\n");
228                 return 1;
229         }
230
231         branch=T->relaied_reply_branch;
232         /* double-check for odd relaying */
233         if ( branch <0 || branch>=T->nr_of_outgoings ) {
234                 DBG("DEBUG: t_forward_ack: strange relaied_reply_branch:"
235                         " %d out of %d\n",branch, T->nr_of_outgoings );
236                 return -1;
237         }
238
239         DBG("DEBUG: t_forward_ack: forwarding ACK [%d]\n",branch);
240         /* not able to build branch -- then better give up */
241         if ( add_branch_label( T, p_msg , branch )==-1) {
242                 LOG( L_ERR, "ERROR: t_forward_ack failed to add branch label\n" );
243                 return 0;
244         }
245         /* not able to build outbound request -- then better give up */
246         if ( !(buf = build_req_buf_from_sip_req  ( p_msg, &len)))  {
247                 LOG(L_ERR,"ERROR: t_forward_ack failed to generate outbound ACK\n");
248                 return 0;
249         };
250
251 #ifdef _DONT_USE
252         /* strange conditions -- no INVITE before me ?!?! */
253         if ( (rb=T->outbound_request[branch])==NULL ) {
254                 /* better stateless than nothing */
255                 goto fwd_sl;
256         }
257 #endif
258
259         /* check for bizzar race condition if two processes receive
260            two ACKs concurrently; use shmem semaphore for protection
261            -- we have to enter it here anyway (the trick with inACKed
262            inside the protection region) */
263         if  (T->uas.isACKed ) {
264                 LOG(L_WARN,"Warning: ACK received when there's one; check upstream\n");
265                 return 1;
266         }
267         ack = shm_malloc( len );
268         memcpy(ack , buf , len);
269         pkg_free( buf );
270
271         T->uas.isACKed = 1;
272         SEND_PR_BUFFER( &(T->uac[branch].request), ack, len );
273         callback_event( TMCB_E2EACK, p_msg );
274         return attach_ack( T, branch, ack , len );
275
276 #ifdef _DON_USE
277 fwd_sl: /* some strange conditions occured; try statelessly */
278         LOG(L_ERR, "ERROR: fwd-ing a 2xx ACK with T-state failed; "
279                 "trying statelessly\n");
280         memset( &to_sock, sizeof to_sock, 0 );
281         to_sock.sin_family = AF_INET;
282         to_sock.sin_port =  dest_port_param;
283         to_sock.sin_addr.s_addr = dest_ip_param;
284         udp_send( buf, len, (struct sockaddr*)(&to_sock), 
285                 sizeof(struct sockaddr_in) );
286         free( buf );
287         return 1;
288 #endif
289 }
290
291
292
293
294 int forward_serial_branch(struct cell* Trans,int branch)
295 {
296         struct sip_msg*  p_msg = Trans->uas.request;
297         struct lump      *a, *b, *b1, *c;
298         unsigned int     len;
299         char             *buf=0, *shbuf=0;
300         str              backup_uri;
301
302         backup_uri.s = p_msg->new_uri.s;
303         backup_uri.len = p_msg->new_uri.len;
304
305         /*generates branch param*/
306         if ( add_branch_label( Trans, p_msg , branch )==-1)
307                 goto error;
308         /* remove all the HDR_VIA type lumps - they are in SHM memory!!! */
309         for(b=p_msg->add_rm,b1=0;b;b1=b,b=b->next)
310                 if (b->type==HDR_VIA)
311                 {
312                         for(a=b->before;a;)
313                                 {c=a->before;shm_free_lump(a);a=c;}
314                         for(a=b->after;a;)
315                                 {c=a->after;shm_free_lump(a);a=c;}
316                         if (b1) b1->next = b->next;
317                                 else p_msg->add_rm = b->next;
318                         shm_free_lump(b);
319                 }
320
321         DBG("DEBUG: t_forward_serial_branch: building req for branch"
322                 "%d; uri=|%.*s|.\n", branch, Trans->uac[branch].uri.len,
323                 Trans->uac[branch].uri.s);
324         /* updates the new uri*/
325         p_msg->new_uri.s = Trans->uac[branch].uri.s;
326         p_msg->new_uri.len = Trans->uac[branch].uri.len;
327         if ( !(buf = build_req_buf_from_sip_req  ( p_msg, &len)))
328                 goto error;
329         shm_free(Trans->uac[branch].uri.s);
330
331         /* allocates a new retrans_buff for the outbound request */
332         shbuf = (char *) shm_malloc( len );
333         if (!shbuf)
334         {
335                 LOG(L_ERR, "ERROR: t_forward_serial_branch: out of shmem buffer\n");
336                 goto error;
337         }
338         Trans->uac[branch].request.buffer = shbuf;
339         Trans->uac[branch].request.buffer_len = len ;
340         memcpy( Trans->uac[branch].request.buffer , buf , len );
341         /* keeps a hooker to uri inside buffer*/
342         Trans->uac[branch].uri.s = Trans->uac[branch].request.buffer +
343                 (p_msg->first_line.u.request.uri.s - p_msg->buf);
344         Trans->uac[branch].uri.len=p_msg->new_uri.len?(p_msg->new_uri.len)
345                 :(p_msg->first_line.u.request.uri.len);
346         Trans->nr_of_outgoings++ ;
347         /* send the request */
348         Trans->uac[branch].request.to.sin_family = AF_INET;
349         SEND_BUFFER( &(T->uac[branch].request) );
350
351         pkg_free( buf ) ;
352         buf=NULL;
353
354         DBG("DEBUG: t_forward_serial_branch:starting timers (retrans and FR) %d\n",
355                 get_ticks() );
356         /*sets and starts the FINAL RESPONSE timer */
357         set_timer( hash_table, &(T->uac[branch].request.fr_timer), 
358                         FR_TIMER_LIST ); 
359                         /* p_msg->REQ_METHOD==METHOD_INVITE ? FR_INV_TIMER_LIST : FR_TIMER_LIST ); */
360         /* sets and starts the RETRANS timer */
361         T->uac[branch].request.retr_list = RT_T1_TO_1;
362         set_timer( hash_table, &(T->uac[branch].request.retr_timer), RT_T1_TO_1 );
363
364         p_msg->new_uri.s = backup_uri.s;
365         p_msg->new_uri.len = backup_uri.len;
366
367         for(b=p_msg->add_rm,b1=0;b;b1=b,b=b->next)
368                 if (b->type==HDR_VIA)
369                 {
370                         for(a=b->before;a;)
371                                 {c=a->before;free_lump(a);pkg_free(a);a=c;}
372                         for(a=b->after;a;)
373                                 {c=a->after;free_lump(a);pkg_free(a);a=c;}
374                         if (b1) b1->next = b->next;
375                                 else p_msg->add_rm = b->next;
376                         free_lump(b);pkg_free(b);
377                 }
378
379         return 1;
380
381 error:
382         if (shbuf) shm_free(shbuf);
383         T->uac[branch].request.buffer=NULL;
384         if (buf) pkg_free( buf );
385         p_msg->new_uri.s = backup_uri.s;
386         p_msg->new_uri.len = backup_uri.len;
387         return -1;
388 }
389
390
391