489be9e5fbc89c3fcf8bfce67bdb1ca1aa5b3d95
[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
23
24
25 static int w_t_check(struct sip_msg* msg, char* str, char* str2);
26 static int w_t_send_reply(struct sip_msg* msg, char* str, char* str2);
27 static int w_t_release(struct sip_msg* msg, char* str, char* str2);
28 static int fixup_t_forward(void** param, int param_no);
29 static int fixup_t_send_reply(void** param, int param_no);
30 static int w_t_unref( struct sip_msg* p_msg, char* foo, char* bar );
31 static int w_t_retransmit_reply(struct sip_msg* p_msg, char* foo, char* bar );
32 static int w_t_add_transaction(struct sip_msg* p_msg, char* foo, char* bar );
33 static int t_relay_to( struct sip_msg *p_msg, char *str_ip, char *str_port);
34 static int t_relay( struct sip_msg  *p_msg ,  char* foo, char* bar  );
35 static int w_t_forward_ack(struct sip_msg* msg, char* str, char* str2);
36 static int w_t_forward_nonack(struct sip_msg* msg, char* str, char* str2);
37 static int w_t_add_fork_ip(struct sip_msg* msg, char* str, char* str2);
38 static int w_t_add_fork_uri(struct sip_msg* msg, char* str, char* str2);
39 static int fixup_t_add_fork_uri(void** param, int param_no);
40 static int w_t_add_fork_on_no_rpl(struct sip_msg* msg,char* str,char* str2);
41 static int w_t_clear_forks(struct sip_msg* msg, char* str, char* str2);
42 static void w_onbreak(struct sip_msg* msg) { t_unref(); }
43
44 static int mod_init(void);
45
46 #ifdef STATIC_TM
47 struct module_exports tm_exports = {
48 #else
49 struct module_exports exports= {
50 #endif
51         "tm",
52         /* -------- exported functions ----------- */
53         (char*[]){                      
54                                 "t_add_transaction",
55                                 "t_lookup_request",
56                                 "t_send_reply",
57                                 "t_retransmit_reply",
58                                 "t_release",
59                                 "t_unref",
60                                 "t_relay_to",
61                                 "t_relay",
62                                 "t_forward_nonack",
63                                 "t_forward_ack",
64                                 "t_fork_to_ip",
65                                 "t_fork_to_uri",
66                                 "t_clear_forks",
67                                 "t_fork_on_no_response",
68                                 "register_tmcb",
69                                 "load_tm"
70                         },
71         (cmd_function[]){
72                                         w_t_add_transaction,
73                                         w_t_check,
74                                         w_t_send_reply,
75                                         w_t_retransmit_reply,
76                                         w_t_release,
77                                         w_t_unref,
78                                         t_relay_to,
79                                         t_relay,
80                                         w_t_forward_nonack,
81                                         w_t_forward_ack,
82                                         w_t_add_fork_ip,
83                                         w_t_add_fork_uri,
84                                         w_t_clear_forks,
85                                         w_t_add_fork_on_no_rpl,
86                                         (cmd_function) register_tmcb,
87                                         (cmd_function) load_tm
88                                         },
89         (int[]){
90                                 0, /* t_add_transaction */
91                                 0, /* t_lookup_request */
92                                 2, /* t_send_reply */
93                                 0, /* t_retransmit_reply */
94                                 0, /* t_release */
95                                 0, /* t_unref */
96                                 2, /* t_relay_to */
97                                 0, /* t_relay */
98                                 2, /* t_forward_nonack */
99                                 2, /* t_forward_ack */
100                                 2, /* t_fork_to_ip */
101                                 1, /* t_fork_to_uri */
102                                 0, /* t_clear_forks */
103                                 1,  /* t_add_fork_on_no_response */
104                                 2 /* register_tmcb */,
105                                 1 /* load_tm */
106                         },
107         (fixup_function[]){
108                                 0,                                              /* t_add_transaction */
109                                 0,                                              /* t_lookup_request */
110                                 fixup_t_send_reply,             /* t_send_reply */
111                                 0,                                              /* t_retransmit_reply */
112                                 0,                                              /* t_release */
113                                 0,                                              /* t_unref */
114                                 fixup_t_forward,                /* t_relay_to */
115                                 0,                                              /* t_relay */
116                                 fixup_t_forward,                /* t_forward_nonack */
117                                 fixup_t_forward,                /* t_forward_ack */
118                                 fixup_t_forward,                /* t_fork_to_ip */
119                                 fixup_t_add_fork_uri,   /* t_fork_to_uri */
120                                 0,                                              /* t_clear_forks */
121                                 fixup_t_add_fork_uri,   /* t_add_fork_on_no_response */
122                                 0,                                              /* register_tmcb */
123                                 0                                               /* load_tm */
124         
125                 },
126         16,
127
128         /* ------------ exported variables ---------- */
129         (char *[]) { /* Module parameter names */
130                 "fr_timer",
131                 "fr_inv_timer",
132                 "wt_timer",
133                 "delete_timer",
134                 "retr_timer1p1",
135                 "retr_timer1p2",
136                 "retr_timer1p3",
137                 "retr_timer2"
138         },
139         (modparam_t[]) { /* variable types */
140                 INT_PARAM,
141                 INT_PARAM,
142                 INT_PARAM,
143                 INT_PARAM,
144                 INT_PARAM,
145                 INT_PARAM,
146                 INT_PARAM,
147                 INT_PARAM
148         },
149         (void *[]) { /* variable pointers */
150                 &(timer_id2timeout[FR_TIMER_LIST]),
151                 &(timer_id2timeout[FR_INV_TIMER_LIST]),
152                 &(timer_id2timeout[WT_TIMER_LIST]),
153                 &(timer_id2timeout[DELETE_LIST]),
154                 &(timer_id2timeout[RT_T1_TO_1]),
155                 &(timer_id2timeout[RT_T1_TO_2]),
156                 &(timer_id2timeout[RT_T1_TO_3]),
157                 &(timer_id2timeout[RT_T2])
158         },
159         8,      /* Number of module paramers */
160
161         mod_init, /* module initialization function */
162         (response_function) t_on_reply,
163         (destroy_function) tm_shutdown,
164         w_onbreak,
165         0  /* per-child init function */
166 };
167
168
169
170 static int mod_init(void)
171 {
172
173         DBG( "TM - initializing...\n");
174         if (tm_startup()==-1) return -1;
175         return 0;
176 }
177
178
179
180
181 static int fixup_t_forward(void** param, int param_no)
182 {
183         char* name;
184         struct hostent* he;
185         unsigned int port;
186         int err;
187 #ifdef DNS_IP_HACK
188         unsigned int ip;
189         int len;
190 #endif
191
192         DBG("TM module: fixup_t_forward(%s, %d)\n", (char*)*param, param_no);
193         if (param_no==1){
194                 name=*param;
195 #ifdef DNS_IP_HACK
196                 len=strlen(name);
197                 ip=str2ip((unsigned char*)name, len, &err);
198                 if (err==0){
199                         goto copy;
200                 }
201 #endif
202                 /* fail over to normal lookup */
203                 he=gethostbyname(name);
204                 if (he==0){
205                         LOG(L_CRIT, "ERROR: mk_proxy: could not resolve hostname:"
206                                                 " \"%s\"\n", name);
207                         return E_BAD_ADDRESS;
208                 }
209                 memcpy(&ip, he->h_addr_list[0], sizeof(unsigned int));
210         copy:
211                 free(*param);
212                 *param=(void*)ip;
213                 return 0;
214         }else if (param_no==2){
215                 port=htons(str2s(*param, strlen(*param), &err));
216                 if (err==0){
217                         free(*param);
218                         *param=(void*)port;
219                         return 0;
220                 }else{
221                         LOG(L_ERR, "TM module:fixup_t_forward: bad port number <%s>\n",
222                                         (char*)(*param));
223                         return E_UNSPEC;
224                 }
225         }
226         return 0;
227 }
228
229
230
231
232 static int fixup_t_send_reply(void** param, int param_no)
233 {
234         unsigned int code;
235         int err;
236
237         if (param_no==1){
238                 code=str2s(*param, strlen(*param), &err);
239                 if (err==0){
240                         free(*param);
241                         *param=(void*)code;
242                         return 0;
243                 }else{
244                         LOG(L_ERR, "TM module:fixup_t_send_reply: bad  number <%s>\n",
245                                         (char*)(*param));
246                         return E_UNSPEC;
247                 }
248         }
249         /* second param => no conversion*/
250         return 0;
251 }
252
253
254
255
256 static int w_t_check(struct sip_msg* msg, char* str, char* str2)
257 {
258         return t_check( msg , 0 , 0 ) ? 1 : -1;
259 }
260
261
262
263
264 static int w_t_forward_ack(struct sip_msg* msg, char* str, char* str2)
265 {
266         if (t_check( msg , 0 , 0 )==-1) return -1;
267         if (!T) {
268                 DBG("DEBUG: t_forward_ack: no transaction found \n");
269                 return -1;
270         }
271         return t_forward_ack(msg, (unsigned int) str, (unsigned int) str2);
272 }
273
274
275
276
277 static int w_t_forward_nonack(struct sip_msg* msg, char* str, char* str2)
278 {
279         if (t_check( msg , 0 , 0)==-1) return -1;
280         if (!T) {
281                 DBG("DEBUG: t_forward_nonack: no transaction found\n");
282                 return -1;
283         }
284         return t_forward_nonack(msg, (unsigned int) str, (unsigned int) str2);
285 }
286
287
288
289 static int w_t_send_reply(struct sip_msg* msg, char* str, char* str2)
290 {
291         if (t_check( msg , 0 , 0)==-1) return -1;
292         if (!T) {
293                 LOG(L_ERR, "ERROR: t_send_reply: cannot send a t_reply to a message "
294                         "for which no T-state has been established\n");
295                 return -1;
296         }
297         return t_send_reply(msg, (unsigned int) str, str2, 0);
298 }
299
300
301
302
303 static int w_t_release(struct sip_msg* msg, char* str, char* str2)
304 {
305         if (t_check( msg  , 0 , 0 )==-1) return 1;
306         if ( T && T!=T_UNDEFINED ) 
307                 return t_put_on_wait( T );
308         return 1;
309 }
310
311
312
313
314 static int w_t_unref( struct sip_msg* p_msg, char* foo, char* bar )
315 {
316         if (T==T_UNDEFINED || T==T_NULL)
317                 return -1;
318     return t_unref( /* p_msg */ );
319 }
320
321
322
323
324 static int w_t_retransmit_reply( struct sip_msg* p_msg, char* foo, char* bar)
325 {
326         if (t_check( p_msg  , 0 , 0 )==-1) 
327                 return 1;
328         if (T)
329                 return t_retransmit_reply( p_msg );
330         else 
331                 return -1;
332         return 1;
333 }
334
335
336
337
338 static int w_t_add_transaction( struct sip_msg* p_msg, char* foo, char* bar ) {
339         if (t_check( p_msg , 0 , 0 )==-1) return -1;
340         if (T) {
341                 LOG(L_ERR,"ERROR: t_add_transaction: won't add a retransmission\n");
342                 return -1;
343         }
344         return t_add_transaction( p_msg );
345 }
346
347
348
349
350 static int w_t_add_fork_ip(struct sip_msg* msg, char* str, char* str2)
351 {
352         return t_add_fork((unsigned int)str, (unsigned int)str2, 0,0,DEFAULT,0);
353 }
354
355
356
357
358 static int fixup_t_add_fork_uri(void** param, int param_no)
359 {
360         unsigned int ip, port;
361         struct fork* fork_pack;
362
363         if (param_no==1)
364         {
365                 fork_pack = (struct fork*)pkg_malloc(sizeof(struct fork));
366                 if (!fork_pack)
367                 {
368                         LOG(L_ERR, "TM module:fixup_t_add_fork_uri: \
369                                 cannot allocate memory!\n");
370                         return E_UNSPEC;
371                 }
372                 fork_pack->uri.len = strlen(*param);
373                 fork_pack->uri.s = *param;
374                 if ( get_ip_and_port_from_uri(&(fork_pack->uri), &ip, &port)==0 )
375                 {
376                         fork_pack->ip = ip;
377                         fork_pack->port = port;
378                         *param=(void*)fork_pack;
379                         return 0;
380                 }else{
381                         LOG(L_ERR, "TM module:fixup_t_add_fork_uri: bad uri <%s>\n",
382                         (char*)(*param));
383                         return E_UNSPEC;
384                 }
385         }
386         /* second param => no conversion*/
387         return 0;
388 }
389
390
391
392
393 static int w_t_add_fork_uri(struct sip_msg* msg, char* str, char* str2)
394 {
395         return t_add_fork( ((struct fork*)str)->ip, ((struct fork*)str)->port,
396                 ((struct fork*)str)->uri.s, ((struct fork*)str)->uri.len, DEFAULT,0);
397 }
398
399
400
401
402 static int w_t_clear_forks(struct sip_msg* msg, char* str, char* str2)
403 {
404         return t_clear_forks();
405 }
406
407
408
409
410 static int w_t_add_fork_on_no_rpl(struct sip_msg* msg, char* str, char* str2)
411 {
412         return t_add_fork( ((struct fork*)str)->ip, ((struct fork*)str)->port,
413                 ((struct fork*)str)->uri.s,((struct fork*)str)->uri.len,NO_RESPONSE,0);
414 }
415
416
417
418
419 static int t_relay_to( struct sip_msg  *p_msg , char *str_ip , char *str_port)
420 {
421         struct proxy_l *proxy;
422         enum addifnew_status status;
423         int ret=0;
424
425         status = t_addifnew( p_msg );
426
427         switch( status ) {
428                 case AIN_ERROR:         /*  fatal error (e.g, parsing) occured */
429                         ret = 0;
430                         break;
431                 case AIN_RETR:          /* it's a retransmission */
432                         ret=t_retransmit_reply( p_msg );
433                         /* look at ret for better debugging output ... */
434                         if (ret>0) DBG("DEBUG: reply retransmitted (status %d)\n", ret);
435                         else if (ret==-1) DBG("DEBUG: no reply to retransmit; "
436                                 "probably a non-INVITE transaction which was not replied\n");
437                         else LOG(L_ERR, "ERROR: reply retranmission failed\n");
438                         /* eventually, do not worry and proceed whatever happened to you...*/
439                         ret = 1;
440                         break;
441                 case AIN_NEW:           /* it's a new request */
442                         if (!t_forward_nonack(p_msg,(unsigned int)str_ip,
443                         (unsigned int) str_port ))
444                         {
445                                 DBG( "SER:ERROR: t_forward \n");
446                                 ret = 0;
447                         } else { /* let upstream know, I forwarded downstream */
448                                 if ( p_msg->REQ_METHOD==METHOD_CANCEL)
449                                 {
450                                         DBG( "SER: new CANCEL\n");
451                                         if ( !t_send_reply( p_msg , 200, "glad to cancel", 0) )
452                                                 DBG( "SER:ERROR: t_send_reply\n");
453                                 } else if (p_msg->REQ_METHOD==METHOD_INVITE)
454                                 {
455                                         DBG( "SER: new INVITE\n");
456                                         if (!t_send_reply( p_msg , 100 ,
457                                         "trying -- your call is important to us",0))
458                                                 DBG("SER: ERROR: t_send_reply (100)\n");
459                                 } else {
460                                         DBG( "SER: new transaction\n");
461                                 }
462                                 ret = 1;
463                         }
464                         break;
465                 case AIN_NEWACK:        /* it's an ACK for which no transaction exists */
466                         DBG( "SER: forwarding ACK  statelessly \n");
467                         proxy = mk_proxy_from_ip( (unsigned int)str_ip,
468                                 ntohs((unsigned int)str_port) );
469                         forward_request( p_msg , proxy ) ;
470                         free_proxy(proxy);
471                         free(proxy);
472                         ret=1;
473                         break;
474                 case AIN_OLDACK:        /* it's an ACK for an existing transaction */
475                         DBG( "SER: ACK received -> t_release\n");
476                         if ( !t_release_transaction( p_msg ) )
477                         {
478                                 DBG( "SER: WARNING: bad t_release\n");
479                         }
480                         /* t_forward decides whether to forward (2xx) 
481                            or not (anything else) */
482                         if ( !t_forward_ack( p_msg , (unsigned int) str_ip ,
483                         (unsigned int) str_port ) )
484                                 DBG( "SER: WARNING: bad ACK forward\n");
485                         ret = 1;
486                         break;
487                 case AIN_RTRACK:        /* ACK retransmission */
488                         DBG( "SER: ACK retransmission\n");
489                         ret = 1;
490                         break;
491                 default:
492                         LOG(L_CRIT, "ERROR: unexpected addifnew return value: %d\n", ret);
493                         abort();
494         };
495         if (T!=T_UNDEFINED && T!=T_NULL) {
496                 T_UNREF( T );
497         }
498         return ret;
499 }
500
501
502
503
504 static int t_relay( struct sip_msg  *p_msg , char* foo, char* bar)
505 {
506         unsigned int  ip, port;
507         str           *uri;
508
509         /* the original uri has been changed? */
510         if (p_msg->new_uri.s==0 || p_msg->new_uri.len==0)
511                 uri = &(p_msg->first_line.u.request.uri);
512         else
513                 uri = &(p_msg->new_uri);
514         /* extracts ip and port from uri */             
515         if ( get_ip_and_port_from_uri( uri , &ip, &port)<0 )
516         {
517                 LOG( L_ERR , "ERROR: t_on_request_received_uri: unable"
518                         " to extract ip and port from uri!\n" );
519                 return -1;
520         }
521         return t_relay_to( p_msg , ( char *) ip , (char *) port );
522 }
523
524
525