- updated to latest avp api
[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-31  200 for INVITE/UAS resent even for UDP (jiri)
33  *               info only if compiling w/ -DEXTRA_DEBUG (andrei)
34  *  2003-03-19  replaced all mallocs/frees w/ pkg_malloc/pkg_free (andrei)
35  *  2003-03-13  send_pr_buffer is called w/ file/function/line debugging
36  *  2003-03-01  start_retr changed to retransmit only for UDP
37  *  2003-02-13  modified send_pr_buffer to use msg_send & rb->dst (andrei)
38  *  2003-04-14  use protocol from uri (jiri)
39  *  2003-04-25  do it (^) really everywhere (jiri)
40  *  2003-04-26  do it (^) really really really everywhere (jiri)
41  *  2003-07-07  added get_proto calls when proxy!=0 (andrei)
42  *  2004-02-13  t->is_invite and t->local replaced with flags (bogdan)
43  *  2005-02-16  fr_*_timer acceps full AVP specifications; empty AVP
44  *              desable variable timer feature (bogdan)
45  */
46
47 #include <limits.h>
48 #include <string.h>
49 #include <stdio.h>
50 #include <errno.h>
51 #include <stdlib.h>
52
53 #include "../../dprint.h"
54 #include "../../hash_func.h"
55 #include "../../dset.h"
56 #include "../../mem/mem.h"
57 #include "defs.h"
58 #include "t_funcs.h"
59 #include "t_fwd.h"
60 #include "t_lookup.h"
61 #include "config.h"
62 #include "t_stats.h"
63
64 /* fr_timer AVP specs */
65 static int     fr_timer_avp_type = 0;
66 static int_str fr_timer_avp = {0};
67 static str     fr_timer_str;
68 static int     fr_inv_timer_avp_type = 0;
69 static int_str fr_inv_timer_avp = {0};
70 static str     fr_inv_timer_str;
71
72
73 /* ----------------------------------------------------- */
74 int send_pr_buffer(     struct retr_buf *rb, void *buf, int len
75 #ifdef EXTRA_DEBUG
76                                                 , char* file, const char *function, int line
77 #endif
78                                         )
79 {
80         if (buf && len && rb )
81                 return msg_send( rb->dst.send_sock, rb->dst.proto, &rb->dst.to,
82                                          rb->dst.proto_reserved1, buf, len);
83         else {
84 #ifdef EXTRA_DEBUG
85                 LOG(L_CRIT, "ERROR: send_pr_buffer: sending an empty buffer"
86                                 "from %s: %s (%d)\n", file, function, line );
87 #else
88                 LOG(L_CRIT, "ERROR: send_pr_buffer: attempt to send an "
89                                 "empty buffer\n");
90 #endif
91                 return -1;
92         }
93 }
94
95 void tm_shutdown()
96 {
97
98         DBG("DEBUG: tm_shutdown : start\n");
99         unlink_timer_lists();
100
101         /* destroy the hash table */
102         DBG("DEBUG: tm_shutdown : emptying hash table\n");
103         free_hash_table( );
104         DBG("DEBUG: tm_shutdown : releasing timers\n");
105         free_timer_table();
106         DBG("DEBUG: tm_shutdown : removing semaphores\n");
107         lock_cleanup();
108         DBG("DEBUG: tm_shutdown : destroying tmcb lists\n");
109         destroy_tmcb_lists();
110         free_tm_stats();
111         DBG("DEBUG: tm_shutdown : done\n");
112 }
113
114
115 /*   returns 1 if everything was OK or -1 for error
116 */
117 int t_release_transaction( struct cell *trans )
118 {
119         set_kr(REQ_RLSD);
120
121         reset_timer( & trans->uas.response.fr_timer );
122         reset_timer( & trans->uas.response.retr_timer );
123
124         cleanup_uac_timers( trans );
125         
126         put_on_wait( trans );
127         return 1;
128 }
129
130
131 /* -----------------------HELPER FUNCTIONS----------------------- */
132
133
134 /*
135   */
136 void put_on_wait(  struct cell  *Trans  )
137 {
138
139 #ifdef EXTRA_DEBUG
140         DBG("DEBUG: put on WAIT \n");
141 #endif
142
143
144         /* we put the transaction on wait timer; we do it only once
145            in transaction's timelife because putting it multiple-times
146            might result in a second instance of a wait timer to be
147            set after the first one fired; on expiration of the second
148            instance, the transaction would be re-deleted
149
150                         PROCESS1                PROCESS2                TIMER PROCESS
151                 0. 200/INVITE rx;
152                    put_on_wait
153                 1.                                      200/INVITE rx;
154                 2.                                                                      WAIT fires; transaction
155                                                                                         about to be deleted
156                 3.                                      avoid putting
157                                                         on WAIT again
158                 4.                                                                      WAIT timer executed,
159                                                                                         transaction deleted
160         */
161         set_1timer( &Trans->wait_tl, WT_TIMER_LIST, 0 );
162 }
163
164
165
166 static int kill_transaction( struct cell *trans )
167 {
168         char err_buffer[128];
169         int sip_err;
170         int reply_ret;
171         int ret;
172
173         /*  we reply statefully and enter WAIT state since error might
174                 have occurred in middle of forking and we do not
175                 want to put the forking burden on upstream client;
176                 however, it may fail too due to lack of memory */
177
178         ret=err2reason_phrase( ser_error, &sip_err,
179                 err_buffer, sizeof(err_buffer), "TM" );
180         if (ret>0) {
181                 reply_ret=t_reply( trans, trans->uas.request, 
182                         sip_err, err_buffer);
183                 /* t_release_transaction( T ); */
184                 return reply_ret;
185         } else {
186                 LOG(L_ERR, "ERROR: kill_transaction: err2reason failed\n");
187                 return -1;
188         }
189 }
190
191
192
193 int t_relay_to( struct sip_msg  *p_msg , struct proxy_l *proxy, int proto,
194                                 int replicate)
195 {
196         int ret;
197         int new_tran;
198         str *uri;
199         int reply_ret;
200         /* struct hdr_field *hdr; */
201         struct cell *t;
202
203         ret=0;
204
205         new_tran = t_newtran( p_msg );
206         
207
208         /* parsing error, memory alloc, whatever ... if via is bad
209            and we are forced to reply there, return with 0 (->break),
210            pass error status otherwise
211         */
212         if (new_tran<0) {
213                 ret = (ser_error==E_BAD_VIA && reply_to_via) ? 0 : new_tran;
214                 goto done;
215         }
216         /* if that was a retransmission, return we are happily done */
217         if (new_tran==0) {
218                 ret = 1;
219                 goto done;
220         }
221
222         /* new transaction */
223
224         /* ACKs do not establish a transaction and are fwd-ed statelessly */
225         if ( p_msg->REQ_METHOD==METHOD_ACK) {
226                 DBG( "SER: forwarding ACK  statelessly \n");
227                 if (proxy==0) {
228                         uri = GET_RURI(p_msg);
229                         proxy=uri2proxy(GET_NEXT_HOP(p_msg), proto);
230                         if (proxy==0) {
231                                         ret=E_BAD_ADDRESS;
232                                         goto done;
233                         }
234                         proto=proxy->proto; /* uri2proxy set it correctly */
235                         ret=forward_request( p_msg , proxy, proto) ;
236                         free_proxy( proxy );    
237                         pkg_free( proxy );
238                 } else {
239                         proto=get_proto(proto, proxy->proto);
240                         ret=forward_request( p_msg , proxy, proto ) ;
241                 }
242                 goto done;
243         }
244
245         /* if replication flag is set, mark the transaction as local
246            so that replies will not be relayed */
247         t=get_t();
248         if (replicate) t->flags|=T_IS_LOCAL_FLAG;
249
250         /* INVITE processing might take long, particularly because of DNS
251            look-ups -- let upstream know we're working on it */
252         if (p_msg->REQ_METHOD==METHOD_INVITE )
253         {
254                 DBG( "SER: new INVITE\n");
255                 if (!t_reply( t, p_msg , 100 ,
256                         "trying -- your call is important to us"))
257                                 DBG("SER: ERROR: t_reply (100)\n");
258         } 
259
260         /* now go ahead and forward ... */
261         ret=t_forward_nonack(t, p_msg, proxy, proto);
262         if (ret<=0) {
263                 DBG( "ERROR:tm:t_relay_to:  t_forward_nonack returned error \n");
264                 /* we don't want to pass upstream any reply regarding replicating
265                  * a request; replicated branch must stop at us*/
266                 if (!replicate) {
267                         reply_ret=kill_transaction( t );
268                         if (reply_ret>0) {
269                                 /* we have taken care of all -- do nothing in
270                                 script */
271                                 DBG("ERROR: generation of a stateful reply "
272                                         "on error succeeded\n");
273                                 ret=0;
274                         }  else {
275                                 DBG("ERROR: generation of a stateful reply "
276                                         "on error failed\n");
277                         }
278                 }
279         } else {
280                 DBG( "SER: new transaction fwd'ed\n");
281         }
282
283 done:
284         return ret;
285 }
286
287
288
289 /*
290  * Initialize parameters containing the ID of
291  * AVPs with variable timers
292  */
293 int init_avp_params(char *fr_timer_param, char *fr_inv_timer_param)
294 {
295         if (fr_timer_param && *fr_timer_param) {
296                 fr_timer_str.s = fr_timer_param;
297                 fr_timer_str.len = strlen(fr_timer_str.s);
298                 if (parse_avp_spec( &fr_timer_str, &fr_timer_avp_type,
299                 &fr_timer_avp)<0) {
300                         LOG(L_CRIT,"ERROR:tm:init_avp_params: invalid fr_timer "
301                                 "AVP specs \"%s\"\n", fr_timer_param);
302                         return -1;
303                 }
304         }
305
306         if (fr_inv_timer_param && *fr_inv_timer_param) {
307                 fr_inv_timer_str.s = fr_inv_timer_param;
308                 fr_inv_timer_str.len = strlen(fr_inv_timer_str.s);
309                 if (parse_avp_spec( &fr_inv_timer_str, &fr_inv_timer_avp_type, 
310                 &fr_inv_timer_avp)<0) {
311                         LOG(L_CRIT,"ERROR:tm:init_avp_params: invalid fr_inv_timer "
312                                 "AVP specs \"%s\"\n", fr_inv_timer_param);
313                         return -1;
314                 }
315         }
316         return 0;
317 }
318
319
320 /*
321  * Get the FR_{INV}_TIMER from corresponding AVP
322  */
323 static inline int avp2timer(unsigned int* timer, int type, int_str name)
324 {
325         struct usr_avp *avp;
326         int_str val_istr;
327         int err;
328
329         avp = search_first_avp( type | AVP_TRACK_TO, name, &val_istr, 0);
330         if (!avp) {
331                 /*
332                  DBG("avp2timer: AVP '%.*s' not found\n", param.s->len, ZSW(param.s->s));
333                  */
334                 return 1;
335         }
336         
337         if (avp->flags & AVP_VAL_STR) {
338                 *timer = str2s(val_istr.s.s, val_istr.s.len, &err);
339                 if (err) {
340                         LOG(L_ERR, "avp2timer: Error while converting string to integer\n");
341                         return -1;
342                 }
343         } else {
344                 *timer = val_istr.n;
345         }
346
347         return 0;
348 }
349
350
351 int fr_avp2timer(unsigned int* timer)
352 {
353         if (fr_timer_avp.n!=0)
354                 return avp2timer( timer, fr_timer_avp_type, fr_timer_avp);
355         else
356                 return 1;
357 }
358
359
360 int fr_inv_avp2timer(unsigned int* timer)
361 {
362         if (fr_inv_timer_avp.n!=0)
363                 return avp2timer( timer, fr_inv_timer_avp_type, fr_inv_timer_avp);
364         else
365                 return 1;
366 }
367
368