3985b6abc0571d724e6473e1cdb4b0ad0ef26eac
[sip-router] / modules / tm / t_funcs.h
1 /*
2  * $Id$
3  */
4
5
6 #ifndef _T_FUNCS_H
7 #define _T_FUNCS_H
8
9 #include <errno.h>
10 #include <netinet/in.h>
11 #include <netdb.h>
12
13 #include "../../parser/msg_parser.h"
14 #include "../../globals.h"
15 #include "../../udp_server.h"
16 #include "../../msg_translator.h"
17 #include "../../timer.h"
18 #include "../../forward.h"
19 #include "../../mem/mem.h"
20
21 #include "../../md5utils.h"
22
23 #include "config.h"
24 #include "lock.h"
25 #include "timer.h"
26
27
28 struct s_table;
29 struct timer;
30 struct entry;
31 struct cell;
32
33 struct fork
34 {
35         unsigned int  ip,port;
36         unsigned char free_flag;
37         str           uri;
38
39 };
40
41
42 extern struct cell      *T;
43 extern unsigned int     global_msg_id;
44 extern struct s_table*  hash_table;
45 extern struct fork      t_forks[ NR_OF_CLIENTS ];
46 extern unsigned int     nr_forks;
47
48
49 #include "sh_malloc.h"
50
51 #include "timer.h"
52 #include "lock.h"
53 #include "sip_msg.h"
54
55
56 #define LOCK_REPLIES(_t) lock(&(_t)->reply_mutex )
57 #define UNLOCK_REPLIES(_t) unlock(&(_t)->reply_mutex )
58 #define LOCK_ACK(_t) lock(&(_t)->ack_mutex )
59 #define UNLOCK_ACK(_t) unlock(&(_t)->ack_mutex )
60 #define LOCK_WAIT(_t) lock(&(_t)->wait_mutex )
61 #define UNLOCK_WAIT(_t) unlock(&(_t)->wait_mutex )
62
63
64 /* send a private buffer: utilize a retransmission structure
65    but take a separate buffer not refered by it; healthy
66    for reducing time spend in REPLIES locks
67 */
68
69 #define SEND_PR_BUFFER(_rb,_bf,_le ) \
70         {\
71                 if ((_bf) && (_le) && (_bf) ) {\
72                         udp_send( (_bf), (_le), (struct sockaddr*)&((_rb)->to) , \
73                                 sizeof(struct sockaddr_in) ); \
74                 }else{ \
75                         LOG(L_CRIT,"ERROR: sending an empty buffer from %s (%d)\n",\
76                                 __FUNCTION__, __LINE__ );\
77                 }\
78         }
79
80 #define SEND_ACK_BUFFER( _rb ) \
81         SEND_PR_BUFFER( (_rb) , (_rb)->ack , (_rb)->ack_len )
82
83 #define SEND_CANCEL_BUFFER( _rb ) \
84         SEND_PR_BUFFER( (_rb) , (_rb)->cancel , (_rb)->cancel_len )
85
86 #define SEND_BUFFER( _rb ) \
87         SEND_PR_BUFFER( (_rb) , (_rb)->buffer , (_rb)->buffer_len )
88
89
90 /*
91   macros for reference bitmap (lock-less process non-exclusive ownership) 
92 */
93 #define T_IS_REFED(_T_cell) ((_T_cell)->ref_bitmap)
94 #define T_REFCOUNTER(_T_cell) \
95         ( { int _i=0; \
96                 process_bm_t _b=(_T_cell)->ref_bitmap; \
97                 while (_b) { \
98                         if ( (_b) & 1 ) _i++; \
99                         (_b) >>= 1; \
100                 } ;\
101                 (_i); \
102          } )
103                 
104
105 #ifdef EXTRA_DEBUG
106 #define T_IS_REFED_BYSELF(_T_cell) ((_T_cell)->ref_bitmap & process_bit)
107 #       define DBG_REF(_action, _t) DBG("DEBUG: XXXXX %s (%s:%d): T=%p , ref (bm=%x, cnt=%d)\n",\
108                         (_action), __FUNCTION__, __LINE__, (_t),(_t)->ref_bitmap, T_REFCOUNTER(_t));
109 #       define T_UNREF(_T_cell) \
110         ( { \
111                 DBG_REF("unref", (_T_cell)); \
112                 if (!T_IS_REFED_BYSELF(_T_cell)) { \
113                         DBG("ERROR: unrefering unrefered transaction %p from %s , %s : %d\n", \
114                                 (_T_cell), __FUNCTION__, __FILE__, __LINE__ ); \
115                         abort(); \
116                 } \
117                 (_T_cell)->ref_bitmap &= ~process_bit; \
118         } )
119
120 #       define T_REF(_T_cell) \
121         ( { \
122                 DBG_REF("ref", (_T_cell));       \
123                 if (T_IS_REFED_BYSELF(_T_cell)) { \
124                         DBG("ERROR: refering already refered transaction %p from %s,%s :"\
125                                 " %d\n",(_T_cell), __FUNCTION__, __FILE__, __LINE__ ); \
126                         abort(); \
127                 } \
128                 (_T_cell)->ref_bitmap |= process_bit; \
129         } )
130 #else
131 #       define T_UNREF(_T_cell) ({ (_T_cell)->ref_bitmap &= ~process_bit; })
132 #       define T_REF(_T_cell) ({ (_T_cell)->ref_bitmap |= process_bit; })
133 #endif
134
135
136
137
138 enum addifnew_status { AIN_ERROR, AIN_RETR, AIN_NEW, AIN_NEWACK,
139         AIN_OLDACK, AIN_RTRACK } ;
140
141
142 int   tm_startup();
143 void tm_shutdown();
144
145
146 /* function returns:
147  *       1 - a new transaction was created
148  *      -1 - error, including retransmission
149  */
150 int  t_add_transaction( struct sip_msg* p_msg  );
151
152
153
154
155 /* function returns:
156  *      -1 - transaction wasn't found
157  *       1 - transaction found
158  */
159 int t_check( struct sip_msg* , int *branch , int* is_cancel);
160
161
162
163
164 /* Forwards the inbound request to a given IP and port.  Returns:
165  *       1 - forward successfull
166  *      -1 - error during forward
167  */
168 int t_forward( struct sip_msg* p_msg , unsigned int dst_ip ,
169                                                                                 unsigned int dst_port);
170
171
172
173
174 /* Forwards the inbound request to dest. from via.  Returns:
175  *       1 - forward successfull
176  *      -1 - error during forward
177  */
178 int t_forward_uri( struct sip_msg* p_msg  );
179
180
181
182
183 /* This function is called whenever a reply for our module is received;
184  * we need to register this function on module initialization;
185  * Returns :   0 - core router stops
186  *             1 - core router relay statelessly
187  */
188 int t_on_reply( struct sip_msg  *p_msg ) ;
189
190
191
192
193 /* This function is called whenever a request for our module is received;
194  * we need to register this function on module initialization;
195  * Returns :   0 - core router stops
196  *             1 - core router relay statelessly
197  */
198 int t_on_request_received( struct sip_msg  *p_msg , unsigned int ip, unsigned int port) ;
199
200
201
202
203 /* This function is called whenever a request for our module is received;
204  * we need to register this function on module initialization;
205  * Returns :   0 - core router stops
206  *             1 - core router relay statelessly
207  */
208 int t_on_request_received_uri( struct sip_msg  *p_msg ) ;
209
210
211
212
213 /* returns 1 if everything was OK or -1 for error
214  */
215 int t_release_transaction( struct sip_msg* );
216
217
218
219
220 /* Retransmits the last sent inbound reply.
221  * Returns  -1 - error
222  *           1 - OK
223  */
224 int t_retransmit_reply( /* struct sip_msg * */  );
225
226
227
228
229 /* Force a new response into inbound response buffer.
230  * returns 1 if everything was OK or -1 for erro
231  */
232 int t_send_reply( struct sip_msg * , unsigned int , char *  , unsigned int);
233
234
235
236
237 /* releases T-context */
238 int t_unref( /* struct sip_msg* p_msg */ );
239
240
241
242
243 int t_forward_nonack( struct sip_msg* p_msg , unsigned int dest_ip_param ,
244         unsigned int dest_port_param );
245 int t_forward_ack( struct sip_msg* p_msg , unsigned int dest_ip_param ,
246         unsigned int dest_port_param );
247 int forward_serial_branch(struct cell* Trans,int branch);
248 struct cell* t_lookupOriginalT(  struct s_table* hash_table,
249         struct sip_msg* p_msg );
250 int t_reply_matching( struct sip_msg* , int* ,  int* );
251 int t_store_incoming_reply( struct cell* , unsigned int , struct sip_msg* );
252 int t_lookup_request( struct sip_msg* p_msg , int leave_new_locked );
253 int t_all_final( struct cell * );
254 int t_build_and_send_ACK( struct cell *Trans , unsigned int brach ,
255         struct sip_msg* rpl);
256 int t_should_relay_response( struct cell *Trans, int new_code, int branch,
257         int *should_store );
258 int t_update_timers_after_sending_reply( struct retr_buf *rb );
259 int t_put_on_wait(  struct cell  *Trans  );
260 int relay_lowest_reply_upstream( struct cell *Trans , struct sip_msg *p_msg );
261 int add_branch_label( struct cell *Trans, struct sip_msg *p_msg , int branch );
262 int get_ip_and_port_from_uri( str* uri , unsigned int *param_ip,
263         unsigned int *param_port);
264 int t_build_and_send_CANCEL(struct cell *Trans, unsigned int branch);
265 char *build_ack( struct sip_msg* rpl, struct cell *trans, int branch ,
266         int *ret_len);
267 enum addifnew_status t_addifnew( struct sip_msg* p_msg );
268 int t_add_fork( unsigned int ip , unsigned int port, char* uri_s,
269         unsigned int uri_len, enum fork_type type, unsigned char free_flag);
270 int t_clear_forks( );
271
272
273
274 inline int static attach_ack(  struct cell *t, int branch,
275                                                                         char *ack, int ack_len )
276 {
277         LOCK_ACK( t );
278         if (t->uac[branch].request.ack) {
279                 UNLOCK_ACK(t);
280                 shm_free( ack );
281                 LOG(L_WARN, "attach_ack: Warning: ACK already sent out\n");
282                 return 0;
283         }
284         t->uac[branch].request.ack = ack;
285         t->uac[branch].request.ack_len = ack_len;
286         UNLOCK_ACK( t );
287         return 1;
288 }
289
290
291
292
293 /* remove from timer list */
294 static inline void reset_timer( struct s_table *hash_table,
295                                                                                                         struct timer_link* tl )
296 {
297         /* lock(timer_group_lock[ tl->tg ]); */
298         /* hack to work arround this timer group thing*/
299         lock(hash_table->timers[timer_group[tl->tg]].mutex);
300         remove_timer_unsafe( tl );
301         unlock(hash_table->timers[timer_group[tl->tg]].mutex);
302         /*unlock(timer_group_lock[ tl->tg ]);*/
303 }
304
305
306
307
308 /* determine timer length and put on a correct timer list */
309 static inline void set_timer( struct s_table *hash_table,
310                                                         struct timer_link *new_tl, enum lists list_id )
311 {
312         unsigned int timeout;
313         struct timer* list;
314
315
316         if (list_id<FR_TIMER_LIST || list_id>=NR_OF_TIMER_LISTS) {
317                 LOG(L_CRIT, "ERROR: set_timer: unkown list: %d\n", list_id);
318 #ifdef EXTRA_DEBUG
319                 abort();
320 #endif
321                 return;
322         }
323         timeout = timer_id2timeout[ list_id ];
324         list= &(hash_table->timers[ list_id ]);
325
326         lock(list->mutex);
327         /* make sure I'm not already on a list */
328         remove_timer_unsafe( new_tl );
329         add_timer_unsafe( list, new_tl, get_ticks()+timeout);
330         unlock(list->mutex);
331 }
332
333
334
335
336 static inline void reset_retr_timers( struct s_table *h_table,
337                                                                                                         struct cell *p_cell )
338 {
339         int ijk;
340
341         /* lock the first timer list of the FR group -- all other
342            lists share the same lock*/
343         lock(hash_table->timers[RT_T1_TO_1].mutex);
344         remove_timer_unsafe( & p_cell->uas.response.retr_timer );
345         for( ijk=0 ; ijk<(p_cell)->nr_of_outgoings ; ijk++ )  {
346                 remove_timer_unsafe( & p_cell->uac[ijk].request.retr_timer );
347         }
348         unlock(hash_table->timers[RT_T1_TO_1].mutex);
349
350         lock(hash_table->timers[FR_TIMER_LIST].mutex);
351         remove_timer_unsafe( & p_cell->uas.response.fr_timer );
352         for( ijk=0 ; ijk<(p_cell)->nr_of_outgoings ; ijk++ )  {
353                 remove_timer_unsafe( & p_cell->uac[ijk].request.fr_timer );
354         }
355         unlock(hash_table->timers[FR_TIMER_LIST].mutex);
356         DBG("DEBUG:stop_RETR_and_FR_timers : timers stopped\n");
357 }
358
359
360
361 #endif
362