more debugging features for ref_bitmapping
[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 #include "../../msg_parser.h"
13 #include "../../globals.h"
14 #include "../../udp_server.h"
15 #include "../../msg_translator.h"
16 #include "../../mem/mem.h"
17
18 struct s_table;
19 struct timer;
20 struct entry;
21 struct cell;
22
23 extern struct cell         *T;
24 extern unsigned int     global_msg_id;
25 extern struct s_table*  hash_table;
26
27
28 #include "sh_malloc.h"
29
30 #include "timer.h"
31 #include "lock.h"
32 #include "sip_msg.h"
33
34
35
36 /* convenience short-cut macros */
37 #define REQ_METHOD first_line.u.request.method_value
38 #define REPLY_STATUS first_line.u.reply.statuscode
39 #define REPLY_CLASS(_reply) ((_reply)->REPLY_STATUS/100)
40 #define SEND_BUFFER( _rb ) ({ if ((_rb)->retr_buffer) \
41         { udp_send( (_rb)->retr_buffer, \
42           (_rb)->bufflen, (struct sockaddr*)&((_rb)->to) , \
43           sizeof(struct sockaddr_in) ); \
44         } else \
45         DBG("ERROR: attempt to send an empty buffer from %s (%d)", \
46         __FUNCTION__, __LINE__ ); })
47
48
49 /* 
50   macros for reference bitmap (lock-less process non-exclusive ownership) 
51 */
52 #define T_IS_REFED(_T_cell) ((_T_cell)->ref_bitmap)
53 #define T_REFCOUNTER(_T_cell) \
54         ( { int _i=0; \
55                 process_bm_t _b=(_T_cell)->ref_bitmap; \
56                 while (_b) { \
57                         if ( (_b) & 1 ) _i++; \
58                         (_b) >>= 1; \
59                 } ;\
60                 (_i); \
61          } )
62                 
63
64 #ifdef EXTRA_DEBUG
65 #define T_IS_REFED_BYSELF(_T_cell) ((_T_cell)->ref_bitmap & process_bit)
66 #       define DBG_REF(_action, _t) DBG("DEBUG: XXXXX %s (%s:%d): T=%p , ref (bm=%x, cnt=%d)\n",\
67                         (_action), __FUNCTION__, __LINE__, (_t),(_t)->ref_bitmap, T_REFCOUNTER(_t));
68 #       define T_UNREF(_T_cell) \
69         ( { \
70                 DBG_REF("unref", (_T_cell)); \
71                 if (!T_IS_REFED_BYSELF(_T_cell)) { \
72                         DBG("ERROR: unrefering unrefered transaction %p from %s , %s : %d\n", \
73                                 (_T_cell), __FUNCTION__, __FILE__, __LINE__ ); \
74                         abort(); \
75                 } \
76                 (_T_cell)->ref_bitmap &= ~process_bit; \
77         } )
78
79 #       define T_REF(_T_cell) \
80         ( { \
81                 DBG_REF("ref", (_T_cell));       \
82                 if (T_IS_REFED_BYSELF(_T_cell)) { \
83                         DBG("ERROR: refering already refered transaction %p from %s , %s : %d\n", \
84                                 (_T_cell), __FUNCTION__, __FILE__, __LINE__ ); \
85                         abort(); \
86                 } \
87                 (_T_cell)->ref_bitmap |= process_bit; \
88         } )
89 #else
90 #       define T_UNREF(_T_cell) ({ (_T_cell)->ref_bitmap &= ~process_bit; })
91 #       define T_REF(_T_cell) ({ (_T_cell)->ref_bitmap |= process_bit; })
92 #endif
93
94
95         
96
97 #ifdef _OLD_XX
98 #define unref_T(_T_cell) \
99         ( {\
100                 lock( hash_table->entrys[(_T_cell)->hash_index].mutex );\
101                 (_T_cell)->ref_counter--;\
102                 DBG_REF("unref", (_T_cell)); \
103                 unlock( hash_table->entrys[(_T_cell)->hash_index].mutex );\
104         } );
105
106 /* we assume that ref_T is only called from places where
107    the associated locks are set up and we don't need to
108    lock/unlock
109 */
110 #define ref_T(_T_cell) ({ ((_T_cell)->ref_counter++); \
111                 DBG_REF("ref", (_T_cell));      })
112 #endif
113
114
115 int   tm_startup();
116 void tm_shutdown();
117
118
119 /* function returns:
120  *       1 - a new transaction was created
121  *      -1 - error, including retransmission
122  */
123 int  t_add_transaction( struct sip_msg* p_msg, char* foo, char* bar  );
124
125
126
127
128 /* function returns:
129  *      -1 - transaction wasn't found
130  *       1 - transaction found
131  */
132 int t_check( struct sip_msg* , int *branch );
133
134
135
136
137 /* Forwards the inbound request to a given IP and port.  Returns:
138  *       1 - forward successfull
139  *      -1 - error during forward
140  */
141 int t_forward( struct sip_msg* p_msg , unsigned int dst_ip ,
142                                 unsigned int dst_port);
143
144
145
146
147 /* Forwards the inbound request to dest. from via.  Returns:
148  *       1 - forward successfull
149  *      -1 - error during forward
150  */
151 int t_forward_uri( struct sip_msg* p_msg , char* foo, char* bar );
152
153
154
155 /*  This function is called whenever a reply for our module is received; we need to register
156   *  this function on module initialization;
157   *  Returns :   0 - core router stops
158   *                    1 - core router relay statelessly
159   */
160 int t_on_reply_received( struct sip_msg  *p_msg ) ;
161
162
163
164
165 /* returns 1 if everything was OK or -1 for error
166 */
167 int t_release_transaction( struct sip_msg* );
168
169
170
171
172 /* Retransmits the last sent inbound reply.
173   * Returns  -1 -error
174   *                1 - OK
175   */
176 int t_retransmit_reply( struct sip_msg *, char* , char* );
177
178
179
180
181 /* Force a new response into inbound response buffer.
182  * returns 1 if everything was OK or -1 for erro
183  */
184 int t_send_reply( struct sip_msg * , unsigned int , char *  );
185
186
187 /* releases T-context */
188 int t_unref( struct sip_msg* p_msg, char* foo, char* bar );
189
190
191
192 struct cell* t_lookupOriginalT(  struct s_table* hash_table , struct sip_msg* p_msg );
193 int t_reply_matching( struct sip_msg* , unsigned int*  );
194 int t_store_incoming_reply( struct cell* , unsigned int , struct sip_msg* );
195 int  t_lookup_request( struct sip_msg* p_msg );
196 int t_all_final( struct cell * );
197 int t_build_and_send_ACK( struct cell *Trans , unsigned int brach , struct sip_msg* rpl);
198 int t_cancel_branch(unsigned int branch); //TO DO
199 int t_should_relay_response( struct cell *Trans, int new_code );
200 int t_update_timers_after_sending_reply( struct retrans_buff *rb );
201 int t_put_on_wait(  struct cell  *Trans  );
202 int relay_lowest_reply_upstream( struct cell *Trans , struct sip_msg *p_msg );
203 int push_reply_from_uac_to_uas( struct cell* Trans , unsigned int );
204 int add_branch_label( struct cell *Trans, struct sip_msg *p_msg , int branch );
205
206 void retransmission_handler( void *);
207 void final_response_handler( void *);
208 void wait_handler( void *);
209 void delete_handler( void *);
210
211
212
213
214 #endif