ser_error processing, ipv6-ization of TM, new TM callbacks;
[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
17 #include "sip_msg.h"
18 #include "h_table.h"
19 #include "t_funcs.h"
20 #include "t_hooks.h"
21 #include "tm_load.h"
22 #include "t_fork.h"
23 #include "ut.h"
24
25
26
27 inline static int w_t_check(struct sip_msg* msg, char* str, char* str2);
28 inline static int w_t_send_reply(struct sip_msg* msg, char* str, char* str2);
29 inline static int w_t_release(struct sip_msg* msg, char* str, char* str2);
30 inline static int fixup_t_send_reply(void** param, int param_no);
31 inline static int w_t_unref( struct sip_msg* p_msg, char* foo, char* bar );
32 inline static int w_t_retransmit_reply(struct sip_msg* p_msg, char* foo, char* bar );
33 /*
34 inline static int w_t_add_transaction(struct sip_msg* p_msg, char* foo, char* bar );
35 */
36
37 inline static int w_t_newtran(struct sip_msg* p_msg, char* foo, char* bar );
38
39 inline static int t_relay( struct sip_msg  *p_msg ,  char* , char* );
40 inline static int w_t_relay_to( struct sip_msg  *p_msg , char *proxy, char *);
41 static int t_relay_to( struct sip_msg  *p_msg , struct proxy_l *proxy );
42 /*
43 inline static int w_t_forward_ack(struct sip_msg* msg, char* proxy, char* );
44 */
45 inline static int w_t_forward_nonack(struct sip_msg* msg, char* str, char* );
46 inline static int fixup_hostport2proxy(void** param, int param_no);
47
48 inline static int w_t_add_fork_ip(struct sip_msg* msg, char* proxy, char* );
49 inline static int w_t_add_fork_uri(struct sip_msg* msg, char* str, char* );
50 inline static int w_t_add_fork_on_no_rpl(struct sip_msg* msg,char* str,char* );
51 inline static int w_t_clear_forks(struct sip_msg* msg, char* , char* );
52
53 inline static int fixup_uri2fork(void** param, int param_no);
54
55 inline static void w_onbreak(struct sip_msg* msg) { t_unref(); }
56
57 static int mod_init(void);
58
59 #ifdef STATIC_TM
60 struct module_exports tm_exports = {
61 #else
62 struct module_exports exports= {
63 #endif
64         "tm",
65         /* -------- exported functions ----------- */
66         (char*[]){                      
67 /*              - obsoleted by atomic t_newtran 
68                                 "t_add_transaction",
69 */
70                                 "t_newtran",
71                                 "t_lookup_request",
72                                 "t_send_reply",
73                                 "t_retransmit_reply",
74                                 "t_release",
75                                 "t_unref",
76                                 "t_relay_to",
77                                 "t_relay",
78                                 "t_forward_nonack",
79 /*
80                                 "t_forward_ack",
81 */
82                                 "t_fork_to_ip",
83                                 "t_fork_to_uri",
84                                 "t_clear_forks",
85                                 "t_fork_on_no_response",
86                                 "register_tmcb",
87                                 "load_tm"
88                         },
89         (cmd_function[]){
90 /*
91                                         w_t_add_transaction,
92 */                                      w_t_newtran,
93                                         w_t_check,
94                                         w_t_send_reply,
95                                         w_t_retransmit_reply,
96                                         w_t_release,
97                                         w_t_unref,
98                                         w_t_relay_to,
99                                         t_relay,
100                                         w_t_forward_nonack,
101 /*
102                                         w_t_forward_ack,
103 */
104                                         w_t_add_fork_ip,
105                                         w_t_add_fork_uri,
106                                         w_t_clear_forks,
107                                         w_t_add_fork_on_no_rpl,
108                                         (cmd_function) register_tmcb,
109                                         (cmd_function) load_tm
110                                         },
111         (int[]){
112                                 0, /* t_newtran */
113                                 0, /* t_lookup_request */
114                                 2, /* t_send_reply */
115                                 0, /* t_retransmit_reply */
116                                 0, /* t_release */
117                                 0, /* t_unref */
118                                 2, /* t_relay_to */
119                                 0, /* t_relay */
120                                 2, /* t_forward_nonack */
121 /*                              2,*/ /* t_forward_ack */
122
123                                 2, /* t_fork_to_ip */
124                                 1, /* t_fork_to_uri */
125                                 0, /* t_clear_forks */
126                                 1,  /* t_add_fork_on_no_response */
127                                 2 /* register_tmcb */,
128                                 1 /* load_tm */
129                         },
130         (fixup_function[]){
131                                 0,                                              /* t_newtran */
132                                 0,                                              /* t_lookup_request */
133                                 fixup_t_send_reply,             /* t_send_reply */
134                                 0,                                              /* t_retransmit_reply */
135                                 0,                                              /* t_release */
136                                 0,                                              /* t_unref */
137                                 fixup_hostport2proxy,   /* t_relay_to */
138                                 0,                                              /* t_relay */
139                                 fixup_hostport2proxy,   /* t_forward_nonack */
140                                 /* fixup_hostport2proxy,        */ /* t_forward_ack */
141                                 fixup_hostport2proxy,   /* t_fork_to_ip */
142                                 fixup_uri2fork,                 /* t_fork_to_uri */
143                                 0,                                              /* t_clear_forks */
144                                 fixup_uri2fork,         /* t_add_fork_on_no_response */
145                                 0,                                              /* register_tmcb */
146                                 0                                               /* load_tm */
147         
148                 },
149         15,
150
151         /* ------------ exported variables ---------- */
152         (char *[]) { /* Module parameter names */
153                 "fr_timer",
154                 "fr_inv_timer",
155                 "wt_timer",
156                 "delete_timer",
157                 "retr_timer1p1",
158                 "retr_timer1p2",
159                 "retr_timer1p3",
160                 "retr_timer2"
161         },
162         (modparam_t[]) { /* variable types */
163                 INT_PARAM,
164                 INT_PARAM,
165                 INT_PARAM,
166                 INT_PARAM,
167                 INT_PARAM,
168                 INT_PARAM,
169                 INT_PARAM,
170                 INT_PARAM
171         },
172         (void *[]) { /* variable pointers */
173                 &(timer_id2timeout[FR_TIMER_LIST]),
174                 &(timer_id2timeout[FR_INV_TIMER_LIST]),
175                 &(timer_id2timeout[WT_TIMER_LIST]),
176                 &(timer_id2timeout[DELETE_LIST]),
177                 &(timer_id2timeout[RT_T1_TO_1]),
178                 &(timer_id2timeout[RT_T1_TO_2]),
179                 &(timer_id2timeout[RT_T1_TO_3]),
180                 &(timer_id2timeout[RT_T2])
181         },
182         8,      /* Number of module paramers */
183
184         mod_init, /* module initialization function */
185         (response_function) t_on_reply,
186         (destroy_function) tm_shutdown,
187         w_onbreak,
188         0  /* per-child init function */
189 };
190
191
192
193 static int mod_init(void)
194 {
195
196         DBG( "TM - initializing...\n");
197         if (tm_startup()==-1) return -1;
198         return 0;
199 }
200
201
202 /* (char *hostname, char *port_nr) ==> (struct proxy_l *, -)  */
203
204 inline static int fixup_hostport2proxy(void** param, int param_no)
205 {
206         unsigned int port;
207         char *host;
208         int err;
209         struct proxy_l *proxy;
210         
211         DBG("TM module: fixup_t_forward(%s, %d)\n", (char*)*param, param_no);
212         if (param_no==1){
213                 DBG("TM module: fixup_t_forward: param 1.. do nothing, wait for #2\n");
214                 return 0;
215         } else if (param_no==2) {
216
217                 host=(char *) (*(param-1)); 
218                 port=str2s(*param, strlen(*param), &err);
219                 if (err!=0) {
220                         LOG(L_ERR, "TM module:fixup_t_forward: bad port number <%s>\n",
221                                 (char*)(*param));
222                          return E_UNSPEC;
223                 }
224                 proxy=mk_proxy(host, port);
225                 if (proxy==0) {
226                         LOG(L_ERR, "ERROR: fixup_t_forwardv6: bad host name in URI <%s>\n",
227                                 host );
228                         return E_BAD_ADDRESS;
229                 }
230                 /* success -- fix the first parameter to proxy now ! */
231                 free( *(param-1));
232                 *(param-1)=proxy;
233                 return 0;
234         } else {
235                 LOG(L_ERR, "ERROR: fixup_t_forwardv6 called with parameter #<>{1,2}\n");
236                 return E_BUG;
237         }
238 }
239
240
241 /* (char *code, char *reason_phrase)==>(int code, r_p as is) */
242
243
244 inline static int fixup_t_send_reply(void** param, int param_no)
245 {
246         unsigned int code;
247         int err;
248
249         if (param_no==1){
250                 code=str2s(*param, strlen(*param), &err);
251                 if (err==0){
252                         free(*param);
253                         *param=(void*)code;
254                         return 0;
255                 }else{
256                         LOG(L_ERR, "TM module:fixup_t_send_reply: bad  number <%s>\n",
257                                         (char*)(*param));
258                         return E_UNSPEC;
259                 }
260         }
261         /* second param => no conversion*/
262         return 0;
263 }
264
265
266
267
268 inline static int w_t_check(struct sip_msg* msg, char* str, char* str2)
269 {
270         return t_check( msg , 0 , 0 ) ? 1 : -1;
271 }
272
273
274
275 #ifdef _TOO_OLD
276 inline static int w_t_forward_ack(struct sip_msg* msg, char* proxy, char* _foo)
277 {
278         if (t_check( msg , 0 , 0 )==-1) return -1;
279         if (!T) {
280                 DBG("DEBUG: t_forward_ack: no transaction found \n");
281                 return -1;
282         }
283         return t_forward_ack(msg /*, ( struct proxy_l *) proxy */ );
284 }
285
286 #endif
287
288
289 inline static int w_t_forward_nonack(struct sip_msg* msg, char* proxy, char* _foo)
290 {
291         if (t_check( msg , 0 , 0)==-1) return -1;
292         if (!T) {
293                 DBG("DEBUG: t_forward_nonack: no transaction found\n");
294                 return -1;
295         }
296         return t_forward_nonack(msg, ( struct proxy_l *) proxy );
297 }
298
299
300
301 inline static int w_t_send_reply(struct sip_msg* msg, char* str, char* str2)
302 {
303         if (t_check( msg , 0 , 0)==-1) return -1;
304         if (!T) {
305                 LOG(L_ERR, "ERROR: t_send_reply: cannot send a t_reply to a message "
306                         "for which no T-state has been established\n");
307                 return -1;
308         }
309         return t_send_reply(msg, (unsigned int) str, str2, 0);
310 }
311
312
313
314
315 inline static int w_t_release(struct sip_msg* msg, char* str, char* str2)
316 {
317         if (t_check( msg  , 0 , 0 )==-1) return 1;
318         if ( T && T!=T_UNDEFINED ) 
319                 return t_put_on_wait( T );
320         return 1;
321 }
322
323
324
325
326 inline static int w_t_unref( struct sip_msg* p_msg, char* foo, char* bar )
327 {
328         if (T==T_UNDEFINED || T==T_NULL)
329                 return -1;
330     return t_unref( /* p_msg */ );
331 }
332
333
334
335
336 inline static int w_t_retransmit_reply( struct sip_msg* p_msg, char* foo, char* bar)
337 {
338         if (t_check( p_msg  , 0 , 0 )==-1) 
339                 return 1;
340         if (T)
341                 return t_retransmit_reply( p_msg );
342         else 
343                 return -1;
344         return 1;
345 }
346
347
348
349
350 /* inline static int w_t_add_transaction( struct sip_msg* p_msg, 
351         char* foo, char* bar ) {
352 */
353 inline static int w_t_newtran( struct sip_msg* p_msg, char* foo, char* bar ) {
354         if (t_check( p_msg , 0 , 0 )==-1) return -1;
355         if (T) {
356                 LOG(L_ERR,"ERROR: t_add_transaction: won't add a retransmission\n");
357                 return -1;
358         }
359         return t_newtran( p_msg );
360 }
361
362
363
364
365 inline static int w_t_add_fork_ip(struct sip_msg* msg, char* proxy, char* _foo )
366 {
367         struct proxy_l *p;
368         union sockaddr_union to;
369
370         p=(struct proxy_l *) proxy;
371         hostent2su(&to, &p->host, p->addr_idx, (p->port)?htons(p->port):htons(SIP_PORT));
372         return t_add_fork( to, 0,0,DEFAULT,0);
373 }
374
375
376
377
378 inline static int fixup_uri2fork (void** param, int param_no)
379 {
380         struct fork* fork_pack;
381         struct proxy_l *p;
382
383         if (param_no==1)
384         {
385                 fork_pack = (struct fork*)pkg_malloc(sizeof(struct fork));
386                 if (!fork_pack)
387                 {
388                         LOG(L_ERR, "TM module:fixup_t_add_fork_uri: \
389                                 cannot allocate memory!\n");
390                         return E_UNSPEC;
391                 }
392                 fork_pack->uri.len = strlen(*param);
393                 fork_pack->uri.s = *param;
394
395                 p=uri2proxy( & fork_pack->uri );
396                 if (p==0) {
397                         pkg_free( fork_pack );
398                         return E_CFG;
399                 }
400                 hostent2su(&fork_pack->to, &p->host, p->addr_idx,
401                 (p->port)?htons(p->port):htons(SIP_PORT));
402
403                 free_proxy(p); free(p);
404                 *param=(void*)fork_pack;
405                 return 0;
406         } else {
407                 LOG(L_ERR, "Error: URI should not be followed by another parameter\n");
408                 /* second param => no conversion*/
409                 return E_BUG;
410         }
411 }
412
413
414
415
416 inline static int w_t_add_fork_uri(struct sip_msg* msg, char* str, char* _foo)
417 {
418         struct fork *fp;
419         fp=(struct fork *) str;
420         return t_add_fork( fp->to, fp->uri.s, fp->uri.len, DEFAULT, 0);
421 }
422
423 inline static int w_t_add_fork_on_no_rpl(struct sip_msg* msg, char* str, char* _foo )
424 {
425         struct fork *fp;
426         fp=(struct fork *) str;
427         return t_add_fork(  fp->to, fp->uri.s, fp->uri.len, NO_RESPONSE, 0);
428 }
429
430 inline static int w_t_clear_forks(struct sip_msg* msg, char* _foo, char* _bar )
431 {
432         return t_clear_forks();
433 }
434
435
436 inline static int w_t_relay_to( struct sip_msg  *p_msg , 
437                                                  char *proxy, /* struct proxy_l *proxy expected */
438                                                  char *_foo       /* nothing expected */ )
439 {
440         return t_relay_to( p_msg, ( struct proxy_l *) proxy );
441 }
442
443 static int t_relay_to( struct sip_msg  *p_msg , struct proxy_l *proxy )
444 {
445         int ret;
446         int new_tran;
447         char err_buffer[128];
448         int sip_err;
449         int reply_ret;
450
451         ret=0;
452
453         new_tran = t_newtran( p_msg );
454
455         /* parsing error, memory alloc, whatever ... return -1;
456            note -- this is a difference to writing a real script --
457            we translate t_newtran 0 error to a negative value allowign
458            some error handling; a script breaks on 0
459     */
460         if (new_tran==0) {
461                 ret=E_UNSPEC;
462                 goto done;
463         }
464
465         /* nothing new -- it is an existing transaction */
466         if (new_tran==-1) {
467                 if ( p_msg->REQ_METHOD==METHOD_ACK) {
468                         DBG( "SER: ACK received -> t_release\n");
469                         if ( !t_release_transaction( p_msg ) )
470                         {
471                                 DBG( "SER: WARNING: bad t_release\n");
472                         }
473                         /* ack fwd-ing not needed -- only hbh ACK
474                            match (new_tran==1) and do not need to
475                            be fwd-ed */
476                         ret = 1;
477                 } else { /* non-ACK -- retransmit */
478                         ret=t_retransmit_reply( p_msg );
479                         /* look at ret for better debugging output ... */
480                         if (ret>0) DBG("DEBUG: reply retransmitted (status %d)\n", ret);
481                         else if (ret==-1) DBG("DEBUG: no reply to retransmit; "
482                                 "probably a non-INVITE transaction which was not replied\n");
483                         else LOG(L_ERR, "ERROR: reply retranmission failed\n");
484                         /* do not worry and proceed whatever happened to you...*/
485                         ret = 1;
486                 }
487         } else { /* it is a new transaction */
488                 if ( p_msg->REQ_METHOD==METHOD_ACK) {
489                         /* ACKs does not establish a transaction and is
490                            fwd-ed statelessly */
491                         DBG( "SER: forwarding ACK  statelessly \n");
492                         ret=forward_request( p_msg , proxy ) ;
493                 } else {
494                         ret=t_forward_nonack(p_msg, proxy);
495                         if (ret<=0)
496                         {
497                                 DBG( "SER:ERROR: t_forward \n");
498                                 /* we reply statefuly and enter WAIT state since error might 
499                                    have occured in middle of forking and we do not 
500                                    want to put the forking burden on upstream client;
501                                    howver, it may fail too due to lack of memory */
502                                 err2reason_phrase( ser_error, &sip_err,
503                                         err_buffer, sizeof(err_buffer), "TM" );
504                                 reply_ret=t_send_reply( p_msg , sip_err, err_buffer,0);
505                                 t_release_transaction( p_msg );
506                                 if (reply_ret>0) {
507                                         /* we have taken care of all -- do nothing in
508                                         script */
509                                         DBG("ERROR: generation of a stateful reply "
510                                                 "on error succeeded\n");
511                                         ret=0;
512                                 }  else {
513                                         DBG("ERROR: generation of a stateful reply "
514                                                 "on error failed\n");
515                                 };
516                         } else { /* let upstream know, I forwarded downstream */
517                                 if ( p_msg->REQ_METHOD==METHOD_CANCEL)
518                                 {
519                                         DBG( "SER: new CANCEL\n");
520                                         if ( !t_send_reply( p_msg , 200, "glad to cancel", 0) )
521                                                 DBG( "SER:ERROR: t_send_reply\n");
522                                 } else if (p_msg->REQ_METHOD==METHOD_INVITE)
523                                 {
524                                         DBG( "SER: new INVITE\n");
525                                         if (!t_send_reply( p_msg , 100 ,
526                                         "trying -- your call is important to us",0))
527                                                 DBG("SER: ERROR: t_send_reply (100)\n");
528                                 } else {
529                                         DBG( "SER: new transaction\n");
530                                 }
531                         } /* forward_nonack succeeded */
532                 } /* a new non-ACK trancation */
533         } /* a new transaction */
534
535
536 done:
537         if (T!=T_UNDEFINED && T!=T_NULL) {
538                 T_UNREF( T );
539         }
540         return ret;
541 }
542
543
544 static int t_relay( struct sip_msg  *p_msg , char* _foo , char* _bar )
545 {
546         str           *uri;
547         struct proxy_l *p;
548         int ret;
549
550         /* the original uri has been changed? */
551         if (p_msg->new_uri.s==0 || p_msg->new_uri.len==0)
552                 uri = &(p_msg->first_line.u.request.uri);
553         else
554                 uri = &(p_msg->new_uri);
555
556         p=uri2proxy( uri );
557         if (p==0) return E_BAD_ADDRESS;
558
559         /* relay now */
560         ret=t_relay_to( p_msg, p );
561         free_proxy( p );
562         free( p );
563         return ret;
564 }
565