... | ... |
@@ -385,6 +385,7 @@ int run_actions(struct action* a, struct sip_msg* msg) |
385 | 385 |
struct action* t; |
386 | 386 |
int ret; |
387 | 387 |
static int rec_lev=0; |
388 |
+ struct sr_module *mod; |
|
388 | 389 |
|
389 | 390 |
rec_lev++; |
390 | 391 |
if (rec_lev>ROUTE_MAX_REC_LEV){ |
... | ... |
@@ -408,6 +409,13 @@ int run_actions(struct action* a, struct sip_msg* msg) |
408 | 409 |
} |
409 | 410 |
|
410 | 411 |
rec_lev--; |
412 |
+ /* process module onbreak handlers if present */ |
|
413 |
+ if (rec_lev==0 && ret==0) |
|
414 |
+ for (mod=modules;mod;mod=mod->next) |
|
415 |
+ if (mod->exports && mod->exports->onbreak_f) { |
|
416 |
+ mod->exports->onbreak_f( msg ); |
|
417 |
+ DBG("DEBUG: %s onbreak handler called\n", mod->exports->name); |
|
418 |
+ } |
|
411 | 419 |
return ret; |
412 | 420 |
|
413 | 421 |
|
... | ... |
@@ -1,5 +1,5 @@ |
1 | 1 |
/* |
2 |
- * $Id $ |
|
2 |
+ * $Id$ |
|
3 | 3 |
*/ |
4 | 4 |
|
5 | 5 |
|
... | ... |
@@ -7,6 +7,8 @@ |
7 | 7 |
#ifndef config_h |
8 | 8 |
#define config_h |
9 | 9 |
|
10 |
+#include "types.h" |
|
11 |
+ |
|
10 | 12 |
/* default sip port if none specified */ |
11 | 13 |
#define SIP_PORT 5060 |
12 | 14 |
|
... | ... |
@@ -62,12 +64,17 @@ |
62 | 64 |
#define MAX_BUCKET 15 |
63 | 65 |
|
64 | 66 |
/* receive buffer size -- preferably set low to |
65 |
- avoid terror of excessively huge messages |
|
67 |
+ avoid terror of excessively huge messages; they are |
|
68 |
+ useless anyway |
|
66 | 69 |
*/ |
67 | 70 |
#define BUF_SIZE (MAX_FIXED_BLOCK-32) |
68 | 71 |
|
69 |
-/* forwarding */ |
|
72 |
+/* forwarding -- Via buffer dimensioning */ |
|
70 | 73 |
#define MAX_VIA_LINE_SIZE 240 |
71 | 74 |
#define MAX_RECEIVED_SIZE 57 |
72 | 75 |
|
76 |
+/* maximum number of processes is constrained by capacity of |
|
77 |
+ process bitmaps */ |
|
78 |
+#define MAX_PROCESSES (sizeof( process_bm_t) * 8 ) |
|
79 |
+ |
|
73 | 80 |
#endif |
... | ... |
@@ -1,5 +1,5 @@ |
1 | 1 |
/* |
2 |
- * $Id* |
|
2 |
+ * $Id$ |
|
3 | 3 |
* |
4 | 4 |
* global variables |
5 | 5 |
* |
... | ... |
@@ -9,6 +9,8 @@ |
9 | 9 |
#ifndef globals_h |
10 | 10 |
#define globals_h |
11 | 11 |
|
12 |
+#include "types.h" |
|
13 |
+ |
|
12 | 14 |
#define NO_DNS 0 |
13 | 15 |
#define DO_DNS 1 |
14 | 16 |
#define DO_REV_DNS 2 |
... | ... |
@@ -32,6 +34,8 @@ extern int check_via; |
32 | 34 |
extern int received_dns; |
33 | 35 |
extern int loop_checks; |
34 | 36 |
extern int process_no; |
37 |
+ |
|
38 |
+extern process_bm_t process_bit; |
|
35 | 39 |
extern int *pids; |
36 | 40 |
|
37 | 41 |
extern int cfg_errors; |
... | ... |
@@ -118,8 +118,8 @@ Options:\n\ |
118 | 118 |
/* print compile-time constants */ |
119 | 119 |
void print_ct_constants() |
120 | 120 |
{ |
121 |
- printf("MAX_RECV_BUFFER_SIZE %d, MAX_LISTEN %d, MAX_URI_SIZE %d\n", |
|
122 |
- MAX_RECV_BUFFER_SIZE, MAX_LISTEN, MAX_URI_SIZE ); |
|
121 |
+ printf("MAX_RECV_BUFFER_SIZE %d, MAX_LISTEN %d, MAX_URI_SIZE %d, MAX_PROCESSES %d\n", |
|
122 |
+ MAX_RECV_BUFFER_SIZE, MAX_LISTEN, MAX_URI_SIZE, MAX_PROCESSES ); |
|
123 | 123 |
} |
124 | 124 |
|
125 | 125 |
/* debuging function */ |
... | ... |
@@ -166,6 +166,7 @@ int addresses_no=0; /* number of names/ips */ |
166 | 166 |
|
167 | 167 |
/* ipc related globals */ |
168 | 168 |
int process_no = 0; |
169 |
+process_bm_t process_bit = 0; |
|
169 | 170 |
#ifdef ROUTE_SRV |
170 | 171 |
#endif |
171 | 172 |
|
... | ... |
@@ -261,6 +262,7 @@ int main_loop() |
261 | 262 |
if (pid==0){ |
262 | 263 |
/* child */ |
263 | 264 |
/* timer!*/ |
265 |
+ process_bit = 0; |
|
264 | 266 |
for(;;){ |
265 | 267 |
sleep(TIMER_TICK); |
266 | 268 |
timer_ticker(); |
... | ... |
@@ -272,6 +274,7 @@ int main_loop() |
272 | 274 |
/* main process, receive loop */ |
273 | 275 |
is_main=1; |
274 | 276 |
pids[0]=getpid(); |
277 |
+ process_bit = 1; |
|
275 | 278 |
process_no=0; /*main process number*/ |
276 | 279 |
udp_rcv_loop(); |
277 | 280 |
}else{ |
... | ... |
@@ -286,6 +289,7 @@ int main_loop() |
286 | 289 |
if (pid==0){ |
287 | 290 |
/* child */ |
288 | 291 |
process_no=i+1; /*0=main*/ |
292 |
+ process_bit = 1 << i; |
|
289 | 293 |
#ifdef STATS |
290 | 294 |
setstats( i ); |
291 | 295 |
#endif |
... | ... |
@@ -299,6 +303,7 @@ int main_loop() |
299 | 303 |
} |
300 | 304 |
/*this is the main process*/ |
301 | 305 |
pids[process_no]=getpid(); |
306 |
+ process_bit = 0; |
|
302 | 307 |
is_main=1; |
303 | 308 |
if (timer_list){ |
304 | 309 |
for(;;){ |
... | ... |
@@ -569,6 +574,11 @@ int main(int argc, char** argv) |
569 | 574 |
|
570 | 575 |
|
571 | 576 |
if (children_no<=0) children_no=CHILD_NO; |
577 |
+ else if (children_no >= MAX_PROCESSES ) { |
|
578 |
+ fprintf(stderr, "ERROR: too many children processes configured; maximum is %d\n", |
|
579 |
+ MAX_PROCESSES-1 ); |
|
580 |
+ goto error; |
|
581 |
+ } |
|
572 | 582 |
/*alloc pids*/ |
573 | 583 |
#ifdef SHM_MEM |
574 | 584 |
pids=shm_malloc(sizeof(int)*children_no); |
... | ... |
@@ -31,17 +31,15 @@ void free_cell( struct cell* dead_cell ) |
31 | 31 |
/* outbound requests*/ |
32 | 32 |
DBG("DEBUG: free_cell: outbound_request[%d] %p\n",i,dead_cell->outbound_request[i]); |
33 | 33 |
if ( rb=dead_cell->outbound_request[i] ) |
34 |
- { |
|
35 |
-/* |
|
36 |
- if (rb->retr_buffer) shm_free( rb->retr_buffer ); |
|
34 |
+ { |
|
35 |
+ if (rb->retr_buffer) shm_free_unsafe( rb->retr_buffer ); |
|
37 | 36 |
dead_cell->outbound_request[i] = NULL; |
38 |
-*/ |
|
39 | 37 |
shm_free_unsafe( rb ); |
40 |
- } |
|
41 |
- /* outbound requests*/ |
|
42 |
- DBG("DEBUG: free_cell: inbound_response[%d] %p\n",i,dead_cell->inbound_response[i]); |
|
43 |
- if ( dead_cell -> inbound_response[i] ) |
|
44 |
- sip_msg_free_unsafe( dead_cell->inbound_response[i] ); |
|
38 |
+ } |
|
39 |
+ /* outbound requests*/ |
|
40 |
+ DBG("DEBUG: free_cell: inbound_response[%d] %p\n",i,dead_cell->inbound_response[i]); |
|
41 |
+ if ( dead_cell -> inbound_response[i] ) |
|
42 |
+ sip_msg_free_unsafe( dead_cell->inbound_response[i] ); |
|
45 | 43 |
} |
46 | 44 |
/* mutex */ |
47 | 45 |
/* release_cell_lock( dead_cell ); */ |
... | ... |
@@ -12,6 +12,7 @@ |
12 | 12 |
#include <arpa/inet.h> |
13 | 13 |
|
14 | 14 |
#include "../../msg_parser.h" |
15 |
+#include "../../types.h" |
|
15 | 16 |
#include "config.h" |
16 | 17 |
|
17 | 18 |
struct s_table; |
... | ... |
@@ -37,18 +38,11 @@ typedef struct retrans_buff |
37 | 38 |
int bufflen; |
38 | 39 |
|
39 | 40 |
struct sockaddr_in to; |
40 |
- /* changed in favour of Solaris to size_t |
|
41 |
- socklen_t tolen; |
|
42 |
- */ |
|
43 | 41 |
size_t tolen; |
44 | 42 |
|
45 | 43 |
/* a message can be linked just to retransmission and FR list */ |
46 | 44 |
struct timer_link retr_timer; |
47 | 45 |
struct timer_link fr_timer; |
48 |
-/* |
|
49 |
- unsigned int timeout_ceiling; |
|
50 |
- unsigned int timeout_value; |
|
51 |
-*/ |
|
52 | 46 |
|
53 | 47 |
/*the cell that containes this retrans_buff*/ |
54 | 48 |
struct cell* my_T; |
... | ... |
@@ -62,43 +56,38 @@ typedef struct retrans_buff |
62 | 56 |
|
63 | 57 |
typedef struct cell |
64 | 58 |
{ |
65 |
- /* linking data */ |
|
66 |
- struct cell* next_cell; |
|
67 |
- struct cell* prev_cell; |
|
68 |
- |
|
69 |
- /*sync data */ |
|
70 |
- /* |
|
71 |
- /* we use hash table mutexes now */ |
|
72 |
- /* ser_lock_t mutex; */ |
|
73 |
- int ref_counter; |
|
74 |
- |
|
75 |
- /* cell payload data */ |
|
76 |
- /* tells in which hash table entry the cell lives */ |
|
77 |
- unsigned int hash_index; |
|
78 |
- /* sequence number within hash collision slot */ |
|
79 |
- unsigned int label; |
|
80 |
- |
|
81 |
- /* bindings to wait and delete timer */ |
|
82 |
- struct timer_link wait_tl; |
|
83 |
- struct timer_link dele_tl; |
|
84 |
- |
|
85 |
- /*the transaction that is canceled (usefull only for CANCEL req)*/ |
|
86 |
- struct cell *T_canceled; |
|
87 |
- struct cell *T_canceler; |
|
88 |
- |
|
89 |
- /* usefull data */ |
|
90 |
- /* UA Server */ |
|
91 |
- struct sip_msg *inbound_request; |
|
92 |
- struct retrans_buff outbound_response; |
|
93 |
- unsigned int status; |
|
94 |
- str* tag; |
|
95 |
- unsigned int inbound_request_isACKed; |
|
96 |
- int relaied_reply_branch; |
|
97 |
- int nr_of_outgoings; |
|
98 |
- /* UA Clients */ |
|
99 |
- struct retrans_buff *outbound_request[ MAX_FORK ]; |
|
100 |
- struct sip_msg *inbound_response[ MAX_FORK ]; |
|
101 |
- unsigned int outbound_request_isACKed[MAX_FORK]; |
|
59 |
+ /* linking data */ |
|
60 |
+ struct cell* next_cell; |
|
61 |
+ struct cell* prev_cell; |
|
62 |
+ |
|
63 |
+ /* indicates which process is currently processing this transaction */ |
|
64 |
+ process_bm_t ref_bitmap; |
|
65 |
+ /* tells in which hash table entry the cell lives */ |
|
66 |
+ unsigned int hash_index; |
|
67 |
+ /* sequence number within hash collision slot */ |
|
68 |
+ unsigned int label; |
|
69 |
+ |
|
70 |
+ /* bindings to wait and delete timer */ |
|
71 |
+ struct timer_link wait_tl; |
|
72 |
+ struct timer_link dele_tl; |
|
73 |
+ |
|
74 |
+ /*the transaction that is canceled (usefull only for CANCEL req)*/ |
|
75 |
+ struct cell *T_canceled; |
|
76 |
+ struct cell *T_canceler; |
|
77 |
+ |
|
78 |
+ /* useful data */ |
|
79 |
+ /* UA Server */ |
|
80 |
+ struct sip_msg *inbound_request; |
|
81 |
+ struct retrans_buff outbound_response; |
|
82 |
+ unsigned int status; |
|
83 |
+ str* tag; |
|
84 |
+ unsigned int inbound_request_isACKed; |
|
85 |
+ int relaied_reply_branch; |
|
86 |
+ int nr_of_outgoings; |
|
87 |
+ /* UA Clients */ |
|
88 |
+ struct retrans_buff *outbound_request[ MAX_FORK ]; |
|
89 |
+ struct sip_msg *inbound_response[ MAX_FORK ]; |
|
90 |
+ unsigned int outbound_request_isACKed[MAX_FORK]; |
|
102 | 91 |
|
103 | 92 |
#ifdef EXTRA_DEBUG |
104 | 93 |
/* scheduled for deletion ? */ |
... | ... |
@@ -174,7 +174,7 @@ int t_add_transaction( struct sip_msg* p_msg, char* foo, char* bar ) |
174 | 174 |
DBG("DEBUG: t_add_transaction: new transaction inserted, hash: %d\n", new_cell->hash_index ); |
175 | 175 |
|
176 | 176 |
T = new_cell; |
177 |
- T->ref_counter =1; |
|
177 |
+ T_REF(T); |
|
178 | 178 |
return 1; |
179 | 179 |
} |
180 | 180 |
|
... | ... |
@@ -451,7 +451,8 @@ int t_on_reply_received( struct sip_msg *p_msg ) |
451 | 451 |
msg_class=REPLY_CLASS(p_msg); |
452 | 452 |
relay = t_should_relay_response( T , msg_status ); |
453 | 453 |
if (relay && !(clone=sip_msg_cloner( p_msg ))) { |
454 |
- t_unref( p_msg, NULL, NULL ); |
|
454 |
+ T_UNREF( T ); |
|
455 |
+ /* t_unref( p_msg, NULL, NULL ); */ |
|
455 | 456 |
return 0; |
456 | 457 |
} |
457 | 458 |
|
... | ... |
@@ -481,7 +482,8 @@ int t_on_reply_received( struct sip_msg *p_msg ) |
481 | 482 |
{ |
482 | 483 |
LOG( L_ERR , "ERROR: t_on_reply_received: unable to send ACK\n" ); |
483 | 484 |
if (clone ) sip_msg_free( clone ); |
484 |
- t_unref( p_msg, NULL, NULL ); |
|
485 |
+ /* t_unref( p_msg, NULL, NULL ); */ |
|
486 |
+ T_UNREF( T ); |
|
485 | 487 |
return 0; |
486 | 488 |
} |
487 | 489 |
} |
... | ... |
@@ -493,7 +495,8 @@ int t_on_reply_received( struct sip_msg *p_msg ) |
493 | 495 |
|
494 | 496 |
/* if the incoming response code is not reliable->drop it*/ |
495 | 497 |
if (!relay) { |
496 |
- t_unref( p_msg, NULL, NULL ); |
|
498 |
+ /* t_unref( p_msg, NULL, NULL ); */ |
|
499 |
+ T_UNREF( T ); |
|
497 | 500 |
return 0; |
498 | 501 |
} |
499 | 502 |
|
... | ... |
@@ -522,11 +525,13 @@ int t_on_reply_received( struct sip_msg *p_msg ) |
522 | 525 |
} |
523 | 526 |
|
524 | 527 |
/* nothing to do for the ser core */ |
525 |
- t_unref( p_msg, NULL, NULL ); |
|
528 |
+ /* t_unref( p_msg, NULL, NULL ); */ |
|
529 |
+ T_UNREF( T ); |
|
526 | 530 |
return 0; |
527 | 531 |
|
528 | 532 |
error: |
529 |
- t_unref( p_msg, NULL, NULL ); |
|
533 |
+ /* t_unref( p_msg, NULL, NULL ); */ |
|
534 |
+ T_UNREF( T ); |
|
530 | 535 |
T->inbound_response[branch]=NULL; |
531 | 536 |
sip_msg_free( clone ); |
532 | 537 |
/* don't try to relay statelessly on error */ |
... | ... |
@@ -577,7 +582,7 @@ int t_unref( struct sip_msg* p_msg, char* foo, char* bar ) |
577 | 582 |
{ |
578 | 583 |
if (T==T_UNDEFINED || T==T_NULL) |
579 | 584 |
return -1; |
580 |
- unref_T(T); |
|
585 |
+ T_UNREF( T ); |
|
581 | 586 |
T=T_UNDEFINED; |
582 | 587 |
return 1; |
583 | 588 |
} |
... | ... |
@@ -1091,16 +1096,16 @@ void delete_cell( struct cell *p_cell ) |
1091 | 1096 |
} |
1092 | 1097 |
#endif |
1093 | 1098 |
/* still in use ... don't delete */ |
1094 |
- if ( p_cell->ref_counter ) { |
|
1099 |
+ if ( T_IS_REFED(p_cell) ) { |
|
1095 | 1100 |
#ifdef EXTRA_DEBUG |
1096 |
- if (p_cell->ref_counter>1) { |
|
1101 |
+ if (T_REFCOUNTER(p_cell)>1) { |
|
1097 | 1102 |
DBG("DEBUG: while debugging with a single process, ref_count > 1\n"); |
1098 | 1103 |
DBG("DEBUG: transaction =%p\n", p_cell ); |
1099 | 1104 |
abort(); |
1100 | 1105 |
} |
1101 | 1106 |
#endif |
1102 |
- DBG("DEBUG: delete_cell: t=%p post for delete (%d)\n", |
|
1103 |
- p_cell,p_cell->ref_counter); |
|
1107 |
+ DBG("DEBUG: delete_cell: t=%p post for delete (refbitmap %x, refcount %d)\n", |
|
1108 |
+ p_cell,p_cell->ref_bitmap, T_REFCOUNTER(p_cell)); |
|
1104 | 1109 |
/* it's added to del list for future del */ |
1105 | 1110 |
set_timer( hash_table, &(p_cell->dele_tl), DELETE_LIST ); |
1106 | 1111 |
} else { |
... | ... |
@@ -46,13 +46,54 @@ extern struct s_table* hash_table; |
46 | 46 |
__FUNCTION__, __LINE__ ); }) |
47 | 47 |
|
48 | 48 |
|
49 |
-/* to avoid too many locks/unlocks, we gave up using separate locks |
|
50 |
- for cells and use those of transaction table entries |
|
49 |
+/* |
|
50 |
+ macros for reference bitmap (lock-less process non-exclusive ownership) |
|
51 | 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 DBG_REF(_action, _t) DBG("DEBUG: XXXXX %s (%s:%d): T=%p , ref (bm=%x, cnt=%d)\n",\ |
|
66 |
+ (_action), __FUNCTION__, __LINE__, (_t),(_t)->ref_bitmap, T_REFCOUNTER(_t)); |
|
67 |
+# define T_UNREF(_T_cell) \ |
|
68 |
+ ( { \ |
|
69 |
+ DBG_REF("unref", (_T_cell)); \ |
|
70 |
+ if (!T_IS_REFED(_T_cell)) { \ |
|
71 |
+ DBG("ERROR: unrefering unrefered transaction %p from %s , %s : %d\n", \ |
|
72 |
+ (_T_cell), __FUNCTION__, __FILE__, __LINE__ ); \ |
|
73 |
+ abort(); \ |
|
74 |
+ } \ |
|
75 |
+ (_T_cell)->ref_bitmap &= ~process_bit; \ |
|
76 |
+ } ) |
|
77 |
+ |
|
78 |
+# define T_REF(_T_cell) \ |
|
79 |
+ ( { \ |
|
80 |
+ DBG_REF("ref", (_T_cell)); \ |
|
81 |
+ if (T_IS_REFED(_T_cell)) { \ |
|
82 |
+ DBG("ERROR: refering already refered transaction %p from %s , %s : %d\n", \ |
|
83 |
+ (_T_cell), __FUNCTION__, __FILE__, __LINE__ ); \ |
|
84 |
+ abort(); \ |
|
85 |
+ } \ |
|
86 |
+ (_T_cell)->ref_bitmap |= process_bit; \ |
|
87 |
+ } ) |
|
88 |
+#else |
|
89 |
+# define T_UNREF(_T_cell) ({ (_T_cell)->ref_bitmap &= ~process_bit; }) |
|
90 |
+# define T_REF(_T_cell) ({ (_T_cell)->ref_bitmap |= process_bit; }) |
|
91 |
+#endif |
|
52 | 92 |
|
53 |
-#define DBG_REF(_action, _t) DBG("DEBUG: XXXXX %s (%s:%d): T=%p , ref=%d\n",\ |
|
54 |
- (_action), __FUNCTION__, __LINE__, (_t),(_t)->ref_counter); |
|
55 | 93 |
|
94 |
+ |
|
95 |
+ |
|
96 |
+#ifdef _OLD_XX |
|
56 | 97 |
#define unref_T(_T_cell) \ |
57 | 98 |
( {\ |
58 | 99 |
lock( hash_table->entrys[(_T_cell)->hash_index].mutex );\ |
... | ... |
@@ -67,6 +108,7 @@ extern struct s_table* hash_table; |
67 | 108 |
*/ |
68 | 109 |
#define ref_T(_T_cell) ({ ((_T_cell)->ref_counter++); \ |
69 | 110 |
DBG_REF("ref", (_T_cell)); }) |
111 |
+#endif |
|
70 | 112 |
|
71 | 113 |
|
72 | 114 |
int tm_startup(); |
... | ... |
@@ -130,9 +130,10 @@ int t_lookup_request( struct sip_msg* p_msg ) |
130 | 130 |
|
131 | 131 |
found: |
132 | 132 |
T=p_cell; |
133 |
- ref_T( T ); |
|
133 |
+ /* ref_T( T ); */ |
|
134 |
+ T_REF( T ); |
|
134 | 135 |
DBG("DEBUG:XXXXXXXXXXXXXXXXXXXXX t_lookup_request: " |
135 |
- "transaction found ( T=%p , ref=%d)\n",T,T->ref_counter); |
|
136 |
+ "transaction found ( T=%p , ref=%x)\n",T,T->ref_bitmap); |
|
136 | 137 |
unlock( hash_table->entrys[hash_index].mutex ); |
137 | 138 |
return 1; |
138 | 139 |
} |
... | ... |
@@ -285,9 +286,10 @@ int t_reply_matching( struct sip_msg *p_msg , unsigned int *p_branch ) |
285 | 286 |
T = p_cell; |
286 | 287 |
*p_branch = branch_id; |
287 | 288 |
/* T->ref_counter ++; */ |
288 |
- ref_T( T ); |
|
289 |
+ /* ref_T( T ); */ |
|
290 |
+ T_REF( T ); |
|
289 | 291 |
unlock( hash_table->entrys[hash_index].mutex ); |
290 |
- DBG("DEBUG:XXXXXXXXXXXXXXXXXXXXX t_reply_matching: reply matched (T=%p, ref=%d)!\n",T,T->ref_counter); |
|
292 |
+ DBG("DEBUG:XXXXXXXXXXXXXXXXXXXXX t_reply_matching: reply matched (T=%p, ref=%x)!\n",T,T->ref_bitmap); |
|
291 | 293 |
return 1; |
292 | 294 |
} |
293 | 295 |
/* next cell */ |
... | ... |
@@ -324,8 +326,10 @@ int t_check( struct sip_msg* p_msg , int *param_branch) |
324 | 326 |
if ( p_msg->id != global_msg_id || T==T_UNDEFINED ) |
325 | 327 |
{ |
326 | 328 |
global_msg_id = p_msg->id; |
329 |
+ /* |
|
327 | 330 |
if ( T && T!=T_UNDEFINED ) |
328 | 331 |
unref_T(T); |
332 |
+ */ |
|
329 | 333 |
T = T_UNDEFINED; |
330 | 334 |
/* transaction lookup */ |
331 | 335 |
if ( p_msg->first_line.type==SIP_REQUEST ) { |
... | ... |
@@ -30,6 +30,8 @@ static int fixup_t_forward(void** param, int param_no); |
30 | 30 |
static int fixup_t_forward_def(void** param, int param_no); |
31 | 31 |
static int fixup_t_send_reply(void** param, int param_no); |
32 | 32 |
|
33 |
+static void w_onbreak(struct sip_msg* msg) { t_unref(msg, NULL, NULL); } |
|
34 |
+ |
|
33 | 35 |
static struct module_exports nm_exports= { |
34 | 36 |
"tm_module", |
35 | 37 |
(char*[]){ "t_add_transaction", |
... | ... |
@@ -77,7 +79,8 @@ static struct module_exports nm_exports= { |
77 | 79 |
}, |
78 | 80 |
9, |
79 | 81 |
(response_function) t_on_reply_received, |
80 |
- (destroy_function) tm_shutdown |
|
82 |
+ (destroy_function) tm_shutdown, |
|
83 |
+ w_onbreak |
|
81 | 84 |
}; |
82 | 85 |
|
83 | 86 |
|
... | ... |
@@ -12,6 +12,7 @@ typedef struct module_exports* (*module_register)(); |
12 | 12 |
typedef int (*cmd_function)(struct sip_msg*, char*, char*); |
13 | 13 |
typedef int (*fixup_function)(void** param, int param_no); |
14 | 14 |
typedef int (*response_function)(struct sip_msg*); |
15 |
+typedef void (*onbreak_function)(struct sip_msg*); |
|
15 | 16 |
typedef void (*destroy_function)(); |
16 | 17 |
|
17 | 18 |
struct module_exports{ |
... | ... |
@@ -29,6 +30,7 @@ struct module_exports{ |
29 | 30 |
destroy_function destroy_f; /*function called when the module should |
30 | 31 |
be "destroyed", e.g: on ser exit; |
31 | 32 |
can be null */ |
33 |
+ onbreak_function onbreak_f; |
|
32 | 34 |
}; |
33 | 35 |
|
34 | 36 |
struct sr_module{ |
... | ... |
@@ -9,7 +9,9 @@ log_stderror=yes # (cmd line: -E) |
9 | 9 |
check_via=yes # (cmd. line: -v) |
10 | 10 |
dns=on # (cmd. line: -r) |
11 | 11 |
rev_dns=yes # (cmd. line: -R) |
12 |
-fork=no # (cmd. line: -D) |
|
12 |
+fork=yes |
|
13 |
+children=4 |
|
14 |
+#fork=no # (cmd. line: -D) |
|
13 | 15 |
port=5080 |
14 | 16 |
#listen=127.0.0.1 |
15 | 17 |
listen=192.168.99.100 |
... | ... |
@@ -47,6 +49,7 @@ route[0]{ |
47 | 49 |
}; |
48 | 50 |
# t_forward("195.37.77.100", "5090" ); |
49 | 51 |
t_forward("195.37.78.146", "5060" ); |
52 |
+ break; |
|
50 | 53 |
t_unref(); |
51 | 54 |
}; |
52 | 55 |
}; |