62f4660cc56c42121c037840dd8dc603f873925a
[sip-router] / modules / tm / tm.c
1 /*
2  * $Id$
3  *
4  * TM module
5  *
6  */
7
8 #include <stdio.h>
9 #include <string.h>
10 #include <netdb.h>
11
12 #include "../../sr_module.h"
13 #include "../../dprint.h"
14 #include "../../error.h"
15 #include "../../ut.h"
16 #include "../../script_cb.h"
17 #include "../../fifo_server.h"
18
19 #include "sip_msg.h"
20 #include "h_table.h"
21 #include "t_funcs.h"
22 #include "t_hooks.h"
23 #include "tm_load.h"
24 #include "ut.h"
25 #include "t_reply.h"
26 #include "uac.h"
27 #include "t_fwd.h"
28 #include "t_lookup.h"
29 #include "t_stats.h"
30
31
32
33 inline static int w_t_check(struct sip_msg* msg, char* str, char* str2);
34 inline static int w_t_reply(struct sip_msg* msg, char* str, char* str2);
35 inline static int w_t_reply_unsafe(struct sip_msg* msg, char* str, char* str2);
36 inline static int w_t_release(struct sip_msg* msg, char* str, char* str2);
37 inline static int fixup_t_send_reply(void** param, int param_no);
38 inline static int fixup_str2int( void** param, int param_no);
39 inline static int w_t_retransmit_reply(struct sip_msg* p_msg, char* foo, char* bar );
40 inline static int w_t_newtran(struct sip_msg* p_msg, char* foo, char* bar );
41 inline static int w_t_newdlg( struct sip_msg* p_msg, char* foo, char* bar );
42 inline static int w_t_relay( struct sip_msg  *p_msg , char *_foo, char *_bar);
43 inline static int w_t_relay_to( struct sip_msg  *p_msg , char *proxy, char *);
44 inline static int w_t_replicate( struct sip_msg  *p_msg , 
45         char *proxy, /* struct proxy_l *proxy expected */
46         char *_foo       /* nothing expected */ );
47 inline static int w_t_forward_nonack(struct sip_msg* msg, char* str, char* );
48 inline static int fixup_hostport2proxy(void** param, int param_no);
49 inline static int w_t_on_negative( struct sip_msg* msg, char *go_to, char *foo );
50
51
52 static int mod_init(void);
53
54 static int child_init(int rank);
55
56
57 #ifdef STATIC_TM
58 struct module_exports tm_exports = {
59 #else
60 struct module_exports exports= {
61 #endif
62         "tm",
63         /* -------- exported functions ----------- */
64         (char*[]){                      
65                                 "t_newtran",
66                                 "t_lookup_request",
67                                 T_REPLY,
68                                 T_REPLY_UNSAFE,
69                                 "t_retransmit_reply",
70                                 "t_release",
71                                 T_RELAY_TO,
72                                 "t_replicate",
73                                 T_RELAY,
74                                 T_FORWARD_NONACK,
75                                 "t_on_negative",
76
77                                 /* not applicable from script ... */
78
79                                 "register_tmcb",
80                                 T_UAC,
81                                 "load_tm",
82                                 "t_newdlg"
83                         },
84         (cmd_function[]){
85                                         w_t_newtran,
86                                         w_t_check,
87                                         w_t_reply,
88                                         w_t_reply_unsafe,
89                                         w_t_retransmit_reply,
90                                         w_t_release,
91                                         w_t_relay_to,
92                                         w_t_replicate,
93                                         w_t_relay,
94                                         w_t_forward_nonack,
95                                         w_t_on_negative,
96
97                                         (cmd_function) register_tmcb,
98                                         (cmd_function) t_uac,
99                                         (cmd_function) load_tm,
100                                         w_t_newdlg,
101                                         },
102         (int[]){
103                                 0, /* t_newtran */
104                                 0, /* t_lookup_request */
105                                 2, /* t_reply */
106                                 2, /* t_reply_unsafe */
107                                 0, /* t_retransmit_reply */
108                                 0, /* t_release */
109                                 2, /* t_relay_to */
110                                 2, /* t_replicate */
111                                 0, /* t_relay */
112                                 2, /* t_forward_nonack */
113                                 1, /* t_on_negative */
114                                 NO_SCRIPT /* register_tmcb */,
115                                 NO_SCRIPT /* t_uac */,
116                                 NO_SCRIPT /* load_tm */,
117                                 0 /* t_newdlg */
118                         },
119         (fixup_function[]){
120                                 0,                                              /* t_newtran */
121                                 0,                                              /* t_lookup_request */
122                                 fixup_t_send_reply,             /* t_reply */
123                                 fixup_t_send_reply,             /* t_reply_unsafe */
124                                 0,                                              /* t_retransmit_reply */
125                                 0,                                              /* t_release */
126                                 fixup_hostport2proxy,   /* t_relay_to */
127                                 fixup_hostport2proxy,   /* t_replicate */
128                                 0,                                              /* t_relay */
129                                 fixup_hostport2proxy,   /* t_forward_nonack */
130                                 fixup_str2int,                  /* t_on_negative */
131                                 0,                                              /* register_tmcb */
132                                 0,                                              /* t_uac */
133                                 0,                                              /* load_tm */
134                                 0                                               /* t_newdlg */
135         
136                 },
137         15,
138
139         /* ------------ exported variables ---------- */
140         (char *[]) { /* Module parameter names */
141                 "fr_timer",
142                 "fr_inv_timer",
143                 "wt_timer",
144                 "delete_timer",
145                 "retr_timer1p1",
146                 "retr_timer1p2",
147                 "retr_timer1p3",
148                 "retr_timer2",
149                 "noisy_ctimer",
150                 "uac_from"
151         },
152         (modparam_t[]) { /* variable types */
153                 INT_PARAM, /* fr_timer */
154                 INT_PARAM, /* fr_inv_timer */
155                 INT_PARAM, /* wt_timer */
156                 INT_PARAM, /* delete_timer */
157                 INT_PARAM,/* retr_timer1p1 */
158                 INT_PARAM, /* retr_timer1p2 */
159                 INT_PARAM, /* retr_timer1p3 */
160                 INT_PARAM, /* retr_timer2 */
161                 INT_PARAM, /* noisy_ctimer */
162                 STR_PARAM, /* uac_from */
163         },
164         (void *[]) { /* variable pointers */
165                 &(timer_id2timeout[FR_TIMER_LIST]),
166                 &(timer_id2timeout[FR_INV_TIMER_LIST]),
167                 &(timer_id2timeout[WT_TIMER_LIST]),
168                 &(timer_id2timeout[DELETE_LIST]),
169                 &(timer_id2timeout[RT_T1_TO_1]),
170                 &(timer_id2timeout[RT_T1_TO_2]),
171                 &(timer_id2timeout[RT_T1_TO_3]),
172                 &(timer_id2timeout[RT_T2]),
173                 &noisy_ctimer,
174                 &uac_from
175         },
176         11,      /* Number of module paramers */
177
178         mod_init, /* module initialization function */
179         (response_function) t_on_reply,
180         (destroy_function) tm_shutdown,
181         0, /* w_onbreak, */
182         child_init /* per-child init function */
183 };
184
185 inline static int fixup_str2int( void** param, int param_no)
186 {
187         unsigned int go_to;
188         int err;
189
190         if (param_no==1) {
191                 go_to=str2s(*param, strlen(*param), &err );
192                 if (err==0) {
193                         free(*param);
194                         *param=(void *)go_to;
195                         return 0;
196                 } else {
197                         LOG(L_ERR, "ERROR: fixup_str2int: bad number <%s>\n",
198                                 (char *)(*param));
199                         return E_CFG;
200                 }
201         }
202         return 0;
203 }
204
205 static int w_t_unref( struct sip_msg *foo, void *bar)
206 {
207         return t_unref(foo);
208 }
209
210 static int script_init( struct sip_msg *foo, void *bar)
211 {   
212         /* we primarily reset all private memory here to make sure
213            private values left over from previous message will
214            not be used again
215     */
216
217         /* make sure the new message will not inherit previous
218            message's t_on_negative value
219         */
220         t_on_negative( 0 );
221
222         return 1;
223 }
224
225 static int mod_init(void)
226 {
227
228         DBG( "TM - initializing...\n");
229         /* checking if we have sufficient bitmap capacity for given
230            maximum number of  branches */
231         if (1<<(MAX_BRANCHES+1)>UINT_MAX) {
232                 LOG(L_CRIT, "Too many max UACs for UAC branch_bm_t bitmap: %d\n",
233                         MAX_BRANCHES );
234                 return -1;
235         }
236         if (register_fifo_cmd(fifo_uac, "t_uac", 0)<0) {
237                 LOG(L_CRIT, "cannot register fifo uac\n");
238                 return -1;
239         }
240         if (register_fifo_cmd(fifo_uac_from, "t_uac_from", 0)<0) {
241                 LOG(L_CRIT, "cannot register fifo uac\n");
242                 return -1;
243         }
244         
245         if (init_tm_stats()<0) {
246                 LOG(L_CRIT, "ERROR: mod_init: failed to init stats\n");
247                 return -1;
248         }
249
250         /* building the hash table*/
251         if (!init_hash_table()) {
252                 LOG(L_ERR, "ERROR: mod_init: initializing hash_table failed\n");
253                 return -1;
254         }
255
256         if (!tm_init_timers()) {
257                 LOG(L_ERR, "ERROR: mod_init: timer init failed\n");
258                 return -1;
259         }
260
261         /* init static hidden values */
262         init_t();
263
264         uac_init();
265         register_tmcb( TMCB_ON_NEGATIVE, on_negative_reply, 0 /* empty param */);
266     /* register the timer function */
267     register_timer( timer_routine , 0 /* empty attr */, 1 );
268     /* register post-script clean-up function */
269     register_script_cb( w_t_unref, POST_SCRIPT_CB, 0 /* empty param */ );
270     register_script_cb( script_init, PRE_SCRIPT_CB , 0 /* empty param */ );
271
272         return 0;
273 }
274
275 static int child_init(int rank) {
276         uac_child_init(rank);
277         return 1;
278 }
279
280
281 /* (char *hostname, char *port_nr) ==> (struct proxy_l *, -)  */
282
283 inline static int fixup_hostport2proxy(void** param, int param_no)
284 {
285         unsigned int port;
286         char *host;
287         int err;
288         struct proxy_l *proxy;
289         
290         DBG("TM module: fixup_t_forward(%s, %d)\n", (char*)*param, param_no);
291         if (param_no==1){
292                 DBG("TM module: fixup_t_forward: param 1.. do nothing, wait for #2\n");
293                 return 0;
294         } else if (param_no==2) {
295
296                 host=(char *) (*(param-1)); 
297                 port=str2s(*param, strlen(*param), &err);
298                 if (err!=0) {
299                         LOG(L_ERR, "TM module:fixup_t_forward: bad port number <%s>\n",
300                                 (char*)(*param));
301                          return E_UNSPEC;
302                 }
303                 proxy=mk_proxy(host, port);
304                 if (proxy==0) {
305                         LOG(L_ERR, "ERROR: fixup_t_forwardv6: bad host name in URI <%s>\n",
306                                 host );
307                         return E_BAD_ADDRESS;
308                 }
309                 /* success -- fix the first parameter to proxy now ! */
310                 free( *(param-1));
311                 *(param-1)=proxy;
312                 return 0;
313         } else {
314                 LOG(L_ERR, "ERROR: fixup_t_forwardv6 called with parameter #<>{1,2}\n");
315                 return E_BUG;
316         }
317 }
318
319
320 /* (char *code, char *reason_phrase)==>(int code, r_p as is) */
321 inline static int fixup_t_send_reply(void** param, int param_no)
322 {
323         unsigned int code;
324         int err;
325
326         if (param_no==1){
327                 code=str2s(*param, strlen(*param), &err);
328                 if (err==0){
329                         free(*param);
330                         *param=(void*)code;
331                         return 0;
332                 }else{
333                         LOG(L_ERR, "TM module:fixup_t_send_reply: bad  number <%s>\n",
334                                         (char*)(*param));
335                         return E_UNSPEC;
336                 }
337         }
338         /* second param => no conversion*/
339         return 0;
340 }
341
342
343
344
345 inline static int w_t_check(struct sip_msg* msg, char* str, char* str2)
346 {
347         return t_check( msg , 0  ) ? 1 : -1;
348 }
349
350
351
352 inline static int w_t_forward_nonack(struct sip_msg* msg, char* proxy, char* _foo)
353 {
354         struct cell *t;
355         if (t_check( msg , 0 )==-1) return -1;
356         t=get_t();
357         if ( t && t!=T_UNDEFINED ) {
358                 if (msg->REQ_METHOD==METHOD_ACK) {
359                         LOG(L_WARN,"WARNING: you don't really want to fwd hbh ACK\n");
360                         return -1;
361                 }
362                 return t_forward_nonack(t, msg, ( struct proxy_l *) proxy );
363         } else {
364                 DBG("DEBUG: t_forward_nonack: no transaction found\n");
365                 return -1;
366         }
367 }
368
369
370
371 inline static int w_t_reply(struct sip_msg* msg, char* str, char* str2)
372 {
373         struct cell *t;
374
375         if (msg->REQ_METHOD==METHOD_ACK) {
376                 LOG(L_WARN, "WARNING: t_reply: ACKs are not replied\n");
377                 return -1;
378         }
379         if (t_check( msg , 0 )==-1) return -1;
380         t=get_t();
381         if (!t) {
382                 LOG(L_ERR, "ERROR: t_reply: cannot send a t_reply to a message "
383                         "for which no T-state has been established\n");
384                 return -1;
385         }
386         return t_reply( t, msg, (unsigned int) str, str2);
387 }
388
389
390 inline static int w_t_reply_unsafe(struct sip_msg* msg, char* str, char* str2)
391 {
392         struct cell *t;
393
394         if (msg->REQ_METHOD==METHOD_ACK) {
395                 LOG(L_WARN, "WARNING: t_reply: ACKs are not replied\n");
396                 return -1;
397         }
398         if (t_check( msg , 0 )==-1) return -1;
399         t=get_t();
400         if (!t) {
401                 LOG(L_ERR, "ERROR: t_reply: cannot send a t_reply to a message "
402                         "for which no T-state has been established\n");
403                 return -1;
404         }
405         return t_reply_unsafe(t, msg, (unsigned int) str, str2);
406 }
407
408
409 inline static int w_t_release(struct sip_msg* msg, char* str, char* str2)
410 {
411         struct cell *t;
412         if (t_check( msg  , 0  )==-1) return -1;
413         t=get_t();
414         if ( t && t!=T_UNDEFINED ) 
415                 return t_release_transaction( t );
416         return 1;
417 }
418
419
420
421
422 inline static int w_t_retransmit_reply( struct sip_msg* p_msg, char* foo, char* bar)
423 {
424         struct cell *t;
425
426
427         if (t_check( p_msg  , 0 )==-1) 
428                 return 1;
429         t=get_t();
430         if (t) {
431                 if (p_msg->REQ_METHOD==METHOD_ACK) {
432                         LOG(L_WARN, "WARNING: : ACKs ansmit_replies not replied\n");
433                         return -1;
434                 }
435                 return t_retransmit_reply( t );
436         } else 
437                 return -1;
438         return 1;
439 }
440
441
442
443
444
445 inline static int w_t_newdlg( struct sip_msg* p_msg, char* foo, char* bar ) 
446 {
447         return t_newdlg( p_msg );
448 }
449
450 inline static int w_t_newtran( struct sip_msg* p_msg, char* foo, char* bar ) 
451 {
452         /* t_newtran returns 0 on error (negative value means
453            'transaction exists'
454         */
455         return t_newtran( p_msg );
456 }
457
458
459 inline static int w_t_on_negative( struct sip_msg* msg, char *go_to, char *foo )
460 {
461         return t_on_negative( (unsigned int ) go_to );
462 }
463
464 inline static int w_t_relay_to( struct sip_msg  *p_msg , 
465         char *proxy, /* struct proxy_l *proxy expected */
466         char *_foo       /* nothing expected */ )
467 {
468         return t_relay_to( p_msg, ( struct proxy_l *) proxy,
469         0 /* no replication */ );
470 }
471
472 inline static int w_t_replicate( struct sip_msg  *p_msg , 
473         char *proxy, /* struct proxy_l *proxy expected */
474         char *_foo       /* nothing expected */ )
475 {
476         return t_replicate(p_msg, ( struct proxy_l *) proxy );
477 }
478
479 inline static int w_t_relay( struct sip_msg  *p_msg , 
480                                                 char *_foo, char *_bar)
481 {
482         return t_relay_to( p_msg, 
483                 (struct proxy_l *) 0 /* no proxy */,
484                 0 /* no replication */ );
485 }
486
487