- TM retransmissions disabled for all but UDP
[sip-router] / modules / tm / t_funcs.c
1 /*
2  * $Id$
3  *
4  * transaction maintenance functions
5  *
6  * Copyright (C) 2001-2003 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  * History:
31  * -------
32  *  2003-03-01  start_retr changed to retransmit only for UDP
33  *  2003-02-13  modified send_pr_buffer to use msg_send & rb->dst (andrei)
34  */
35
36
37 #include "defs.h"
38
39
40 #include <limits.h>
41 #include "../../dprint.h"
42 #include "../../config.h"
43 #include "../../parser/parser_f.h"
44 #include "../../ut.h"
45 #include "../../hash_func.h"
46 #include "../../dset.h"
47 #include "t_funcs.h"
48 #include "t_fwd.h"
49 #include "t_lookup.h"
50 #include "config.h"
51 #include "t_stats.h"
52
53
54 /* ----------------------------------------------------- */
55
56 int send_pr_buffer( struct retr_buf *rb,
57         void *buf, int len, char *function, int line )
58 {
59         if (buf && len && rb )
60                 return msg_send( rb->dst.send_sock, rb->dst.proto, &rb->dst.to,
61                                          rb->dst.proto_reserved1, buf, len);
62         else {
63                 LOG(L_CRIT, "ERROR: sending an empty buffer from %s (%d)\n",
64                         function, line );
65                 return -1;
66         }
67 }
68
69 void start_retr( struct retr_buf *rb )
70 {
71         if (rb->dst.proto==PROTO_UDP) {
72                 rb->retr_list=RT_T1_TO_1;
73                 set_timer( &rb->retr_timer, RT_T1_TO_1 );
74         }
75         set_timer( &rb->fr_timer, FR_TIMER_LIST );
76 }
77
78
79
80
81
82 void tm_shutdown()
83 {
84
85         DBG("DEBUG: tm_shutdown : start\n");
86         unlink_timer_lists();
87
88         /* destroy the hash table */
89         DBG("DEBUG: tm_shutdown : empting hash table\n");
90         free_hash_table( );
91         DBG("DEBUG: tm_shutdown: releasing timers\n");
92         free_timer_table();
93         DBG("DEBUG: tm_shutdown : removing semaphores\n");
94         lock_cleanup();
95         free_tm_stats();
96         DBG("DEBUG: tm_shutdown : done\n");
97 }
98
99
100 /*   returns 1 if everything was OK or -1 for error
101 */
102 int t_release_transaction( struct cell *trans )
103 {
104         set_kr(trans,REQ_RLSD);
105
106         reset_timer( & trans->uas.response.fr_timer );
107         reset_timer( & trans->uas.response.retr_timer );
108
109         cleanup_uac_timers( trans );
110         
111         put_on_wait( trans );
112         return 1;
113 }
114
115
116 /* ----------------------------HELPER FUNCTIONS-------------------------------- */
117
118
119 /*
120   */
121 void put_on_wait(  struct cell  *Trans  )
122 {
123
124 #ifdef EXTRA_DEBUG
125         DBG("DEBUG: put on WAIT \n");
126 #endif
127
128
129         /* we put the transaction on wait timer; we do it only once
130            in transaction's timelife because putting it multiple-times
131            might result in a second instance of a wait timer to be
132            set after the first one fired; on expiration of the second
133            instance, the transaction would be re-deleted
134
135                         PROCESS1                PROCESS2                TIMER PROCESS
136                 0. 200/INVITE rx;
137                    put_on_wait
138                 1.                                      200/INVITE rx;
139                 2.                                                                      WAIT fires; transaction
140                                                                                         about to be deleted
141                 3.                                      avoid putting
142                                                         on WAIT again
143                 4.                                                                      WAIT timer executed,
144                                                                                         transaction deleted
145         */
146         set_1timer( &Trans->wait_tl, WT_TIMER_LIST );
147 }
148
149
150
151 static int kill_transaction( struct cell *trans )
152 {
153         char err_buffer[128];
154         int sip_err;
155         int reply_ret;
156         int ret;
157
158         /*  we reply statefuly and enter WAIT state since error might
159                 have occured in middle of forking and we do not
160                 want to put the forking burden on upstream client;
161                 howver, it may fail too due to lack of memory */
162
163         ret=err2reason_phrase( ser_error, &sip_err,
164                 err_buffer, sizeof(err_buffer), "TM" );
165         if (ret>0) {
166                 reply_ret=t_reply( trans, trans->uas.request, 
167                         sip_err, err_buffer);
168                 /* t_release_transaction( T ); */
169                 return reply_ret;
170         } else {
171                 LOG(L_ERR, "ERROR: kill_transaction: err2reason failed\n");
172                 return -1;
173         }
174 }
175
176
177
178 int t_relay_to( struct sip_msg  *p_msg , struct proxy_l *proxy, int proto,
179                                 int replicate)
180 {
181         int ret;
182         int new_tran;
183         str *uri;
184         int reply_ret;
185         /* struct hdr_field *hdr; */
186         struct cell *t;
187 #ifdef ACK_FORKING_HACK
188         str ack_uri;
189         str backup_uri;
190 #endif
191
192         ret=0;
193
194         new_tran = t_newtran( p_msg );
195         
196
197         /* parsing error, memory alloc, whatever ... if via is bad
198            and we are forced to reply there, return with 0 (->break),
199            pass error status otherwise
200         */
201         if (new_tran<0) {
202                 ret = (ser_error==E_BAD_VIA && reply_to_via) ? 0 : new_tran;
203                 goto done;
204         }
205         /* if that was a retransmission, return we are happily done */
206         if (new_tran==0) {
207                 ret = 1;
208                 goto done;
209         }
210
211         /* new transaction */
212
213         /* ACKs do not establish a transaction and are fwd-ed statelessly */
214         if ( p_msg->REQ_METHOD==METHOD_ACK) {
215                 DBG( "SER: forwarding ACK  statelessly \n");
216                 if (proxy==0) {
217                         uri=(p_msg->new_uri.s==0 || p_msg->new_uri.len==0) ?
218                                 &p_msg->first_line.u.request.uri :
219                                 &p_msg->new_uri;
220                         proxy=uri2proxy( uri, proto );
221                         if (proxy==0) {
222                                         ret=E_BAD_ADDRESS;
223                                         goto done;
224                         }
225                         ret=forward_request( p_msg , proxy, proto) ;
226                         free_proxy( proxy );    
227                         free( proxy );
228 #ifdef ACK_FORKING_HACK
229                         backup_uri=p_msg->new_uri;
230                         init_branch_iterator();
231                         while((ack_uri.s=next_branch(&ack_uri.len))) {
232                                 p_msg->new_uri=ack_uri;
233                                 proxy=uri2proxy(ack_uri, proto);
234                                 if (proxy==0) continue;
235                                 forward_request(p_msg, proxy, proto);
236                                 free_proxy( proxy );    
237                                 free( proxy );
238                         }
239                         p_msg->new_uri=backup_uri;
240 #endif
241                 } else {
242                         ret=forward_request( p_msg , proxy, proto ) ;
243 #ifdef ACK_FORKING_HACK
244                         backup_uri=p_msg->new_uri;
245                         init_branch_iterator();
246                         while((ack_uri.s=next_branch(&ack_uri.len))) {
247                                 p_msg->new_uri=ack_uri;
248                                 forward_request(p_msg, proxy, proto);
249                         }
250                         p_msg->new_uri=backup_uri;
251 #endif
252                 }
253                 goto done;
254         }
255
256         /* if replication flag is set, mark the transaction as local
257            so that replies will not be relaied
258         */
259         t=get_t();
260         t->local=replicate;
261
262         /* INVITE processing might take long, partcularly because of DNS
263            look-ups -- let upstream know we're working on it */
264         if (p_msg->REQ_METHOD==METHOD_INVITE )
265         {
266                 DBG( "SER: new INVITE\n");
267                 if (!t_reply( t, p_msg , 100 ,
268                         "trying -- your call is important to us"))
269                                 DBG("SER: ERROR: t_reply (100)\n");
270         } 
271
272         /* now go ahead and forward ... */
273         ret=t_forward_nonack(t, p_msg, proxy, proto);
274         if (ret<=0) {
275                 DBG( "SER:ERROR: t_forward \n");
276                 reply_ret=kill_transaction( t );
277                 if (reply_ret>0) {
278                         /* we have taken care of all -- do nothing in
279                         script */
280                         DBG("ERROR: generation of a stateful reply "
281                                 "on error succeeded\n");
282                         ret=0;
283                 }  else {
284                         DBG("ERROR: generation of a stateful reply "
285                                 "on error failed\n");
286                 }
287         } else {
288                 DBG( "SER: new transaction fwd'ed\n");
289         }
290
291 done:
292         return ret;
293 }