Browse code

new structures + forking

Bogdan-Andrei Iancu authored on 25/03/2002 16:26:34
Showing 13 changed files
... ...
@@ -84,11 +84,12 @@ DEFS+= -DNAME='"$(NAME)"' -DVERSION='"$(RELEASE)"' -DARCH='"$(ARCH)"' \
84 84
 	 -DF_MALLOC  -DUSE_SYNONIM\
85 85
 	 -DSHM_MEM  -DSHM_MMAP \
86 86
 	 -DADAPTIVE_WAIT -DADAPTIVE_WAIT_LOOPS=1024 \
87
+	 -DWAIT -DNEW_HNAME -DBOGDAN_TRIFLE \
87 88
 	 -DWAIT -DNEW_HNAME \
88 89
 	 -DSILENT_FR \
89
-	 -DNO_DEBUG \
90
-	 #-DVERY_NOISY_REPLIES\
90
+	 #-DNO_DEBUG \
91 91
 	 #-DNOISY_REPLIES \
92
+	 #-DBOGDAN_TRIFLE \
92 93
 	 #-DADAPTIVE_WAIT -DADAPTIVE_WAIT_LOOPS=0 \
93 94
 	 #-DNOSMP \
94 95
 	 #-DEXTRA_DEBUG 
... ...
@@ -11,7 +11,7 @@
11 11
 #define TABLE_ENTRIES  		(1 << (T_TABLE_POWER))
12 12
 
13 13
 /* maximum number of forks per transaction */
14
-#define MAX_FORK		2
14
+#define MAX_FORK		4
15 15
 
16 16
 /* maximumum length of localy generated acknowledgement */
17 17
 #define MAX_ACK_LEN 		1024
... ...
@@ -8,127 +8,57 @@
8 8
 #include "sh_malloc.h"
9 9
 #include "../../md5utils.h"
10 10
 
11
-/* containes of a cell and the cell's body itself */
11
+
12
+
13
+
12 14
 void free_cell( struct cell* dead_cell )
13 15
 {
14
-	int i;
15
-	struct retrans_buff* rb;
16 16
 	char *b;
17
+	int i;
17 18
 
18
-	/* UA Server */
19 19
 	release_cell_lock( dead_cell );
20 20
 	shm_lock();
21
-	if ( dead_cell->inbound_request )
22
-		sip_msg_free_unsafe( dead_cell->inbound_request );
23
-	if ((b=dead_cell->outbound_response.retr_buffer))
24
-		shm_free_unsafe( b );
21
+
22
+	/* UA Server */
23
+	if ( dead_cell->uas.request )
24
+		sip_msg_free_unsafe( dead_cell->uas.request );
25
+	if ( dead_cell->uas.response.buffer )
26
+		shm_free_unsafe( dead_cell->uas.response.buffer );
25 27
 
26 28
 	/* UA Clients */
27 29
 	for ( i =0 ; i<dead_cell->nr_of_outgoings;  i++ )
28 30
 	{
29
-		/* outbound requests*/
30
-		if ( (rb=dead_cell->outbound_request[i]) )
31
+		/* retransmission buffer */
32
+		if ( (b=dead_cell->uac[i].request.buffer) )
33
+		{
34
+			shm_free_unsafe( b );
35
+			b = 0;
36
+		}
37
+		if ( (b=dead_cell->uac[i].request.ack) )
38
+		{
39
+			shm_free_unsafe( b );
40
+			b = 0;
41
+		}
42
+		if ( (b=dead_cell->uac[i].request.cancel) )
31 43
 		{
32
-			if (rb->retr_buffer) shm_free_unsafe( rb->retr_buffer );
33
-			dead_cell->outbound_request[i] = NULL;
34
-			shm_free_unsafe( rb );
44
+			shm_free_unsafe( b );
45
+			b = 0;
35 46
 		}
36
-		/* outbound ACKs, if any */
37
-		if ( (rb=dead_cell->outbound_ack[i]) )
38
-			shm_free_unsafe( rb );
39
-		/* local cancel , if any */
40
-		if ( (rb=dead_cell->outbound_cancel[i]) )
41
-			shm_free_unsafe( rb );
42
-		/* inbound response */
43
-		if ( dead_cell -> inbound_response[i] )
44
-			sip_msg_free_unsafe( dead_cell->inbound_response[i] );
45 47
 	}
46
-	/* mutex */
47
-	/* release_cell_lock( dead_celle ); */
48
+
48 49
 	/* the cell's body */
49 50
 	shm_free_unsafe( dead_cell );
50
-	shm_unlock();
51
-}
52
-
53
-
54
-
55 51
 
56
-/* Release all the data contained by the hash table. All the aux. structures
57
-  *  as sems, lists, etc, are also released
58
-  */
59
-void free_hash_table( struct s_table *hash_table )
60
-{
61
-   struct cell* p_cell;
62
-   struct cell* tmp_cell;
63
-   int   i;
64
-
65
-   if (hash_table)
66
-   {
67
-      /* remove the data contained by each entry */
68
-      for( i = 0 ; i<TABLE_ENTRIES; i++)
69
-      {
70
-         release_entry_lock( (hash_table->entrys)+i );
71
-         /* delete all synonyms at hash-collision-slot i */
72
-         for( p_cell = hash_table->entrys[i].first_cell; p_cell; p_cell = tmp_cell )
73
-         {
74
-            tmp_cell = p_cell->next_cell;
75
-            free_cell( p_cell );
76
-         }
77
-      }
78
-
79
-      /* the mutexs for sync the lists are released*/
80
-      for ( i=0 ; i<NR_OF_TIMER_LISTS ; i++ )
81
-         release_timerlist_lock( &(hash_table->timers[i]) );
82
-
83
-      sh_free( hash_table );
84
-   }
52
+	shm_unlock();
85 53
 }
86 54
 
87 55
 
88 56
 
89 57
 
90
-/*
91
-  */
92
-struct s_table* init_hash_table()
93
-{
94
-   struct s_table*  hash_table;
95
-   int       i;
96
-
97
-   /*allocs the table*/
98
-   hash_table = (struct s_table*)sh_malloc( sizeof( struct s_table ) );
99
-   if ( !hash_table )
100
-      goto error;
101
-
102
-   memset( hash_table, 0, sizeof (struct s_table ) );
103
-
104
-   /* try first allocating all the structures needed for syncing */
105
-   if (lock_initialize()==-1)
106
-     goto error;
107
-
108
-   /* inits the entrys */
109
-   for(  i=0 ; i<TABLE_ENTRIES; i++ )
110
-   {
111
-      init_entry_lock( hash_table , (hash_table->entrys)+i );
112
-      hash_table->entrys[i].next_label = rand();
113
-   }
114
-
115
-   /* inits the timers*/
116
-   for(  i=0 ; i<NR_OF_TIMER_LISTS ; i++ )
117
-      init_timer_list( hash_table, i );
118
-
119
-   return  hash_table;
120
-
121
-error:
122
-   free_hash_table( hash_table );
123
-   lock_cleanup();
124
-   return 0;
125
-}
126
-
127
-
128
-
129 58
 struct cell*  build_cell( struct sip_msg* p_msg )
130 59
 {
131 60
 	struct cell* new_cell;
61
+	unsigned int i;
132 62
 #ifndef USE_SYNONIM
133 63
 	str          src[5];
134 64
 #endif
... ...
@@ -145,25 +75,37 @@ struct cell*  build_cell( struct sip_msg* p_msg )
145 75
 	/* filling with 0 */
146 76
 	memset( new_cell, 0, sizeof( struct cell ) );
147 77
 
148
-	new_cell->outbound_response.retr_timer.tg=TG_RT;
149
-	new_cell->outbound_response.fr_timer.tg=TG_FR;
150
-	new_cell->wait_tl.tg=TG_WT;
151
-	new_cell->dele_tl.tg=TG_DEL;
78
+	/* UAS */
79
+	new_cell->uas.response.retr_timer.tg=TG_RT;
80
+	new_cell->uas.response.fr_timer.tg=TG_FR;
81
+	new_cell->uas.response.fr_timer.payload =
82
+		new_cell->uas.response.retr_timer.payload = &(new_cell->uas.response);
83
+	new_cell->uas.request = sip_msg_cloner(p_msg);
84
+	if (!new_cell->uas.request)
85
+		goto error;
86
+	new_cell->uas.tag = &( get_to(new_cell->uas.request)->tag_value );
87
+	new_cell->uas.response.my_T = new_cell;
152 88
 
153
-	/* hash index of the entry */
89
+	/* UAC */
90
+	for(i=0;i<MAX_FORK;i++)
91
+	{
92
+		new_cell->uac[i].request.my_T = new_cell;
93
+		new_cell->uac[i].request.branch = i;
94
+		new_cell->uac[i].request.fr_timer.tg = TG_FR;
95
+		new_cell->uac[i].request.retr_timer.tg = TG_RT;
96
+		new_cell->uac[i].request.retr_timer.payload = 
97
+			new_cell->uac[i].request.fr_timer.payload =
98
+			&(new_cell->uac[i].request);
99
+	}
100
+
101
+	/* global data for transaction */
154 102
 	new_cell->hash_index = p_msg->hash_index;
155
-	/* mutex */
156
-	/* ref counter is 0 */
157
-	/* all pointers from timers list tl are NULL */
158 103
 	new_cell->wait_tl.payload = new_cell;
159 104
 	new_cell->dele_tl.payload = new_cell;
160
-
161
-	new_cell->inbound_request =  sip_msg_cloner(p_msg) ;
162
-	if (!new_cell->inbound_request)
163
-		goto error;
164 105
 	new_cell->relaied_reply_branch   = -1;
165 106
 	new_cell->T_canceled = T_UNDEFINED;
166
-	new_cell->tag=&(get_to(new_cell->inbound_request)->tag_value);
107
+	new_cell->wait_tl.tg=TG_WT;
108
+	new_cell->dele_tl.tg=TG_DEL;
167 109
 #ifndef USE_SYNONIM
168 110
 	src[0]= p_msg->from->body;
169 111
 	src[1]= p_msg->to->body;
... ...
@@ -174,7 +116,6 @@ struct cell*  build_cell( struct sip_msg* p_msg )
174 116
 #endif
175 117
 
176 118
 	init_cell_lock(  new_cell );
177
-
178 119
 	return new_cell;
179 120
 
180 121
 error:
... ...
@@ -185,10 +126,84 @@ error:
185 126
 
186 127
 
187 128
 
129
+/* Release all the data contained by the hash table. All the aux. structures
130
+ *  as sems, lists, etc, are also released */
131
+void free_hash_table( struct s_table *hash_table )
132
+{
133
+	struct cell* p_cell;
134
+	struct cell* tmp_cell;
135
+	int    i;
136
+
137
+	if (hash_table)
138
+	{
139
+		/* remove the data contained by each entry */
140
+		for( i = 0 ; i<TABLE_ENTRIES; i++)
141
+		{
142
+			release_entry_lock( (hash_table->entrys)+i );
143
+			/* delete all synonyms at hash-collision-slot i */
144
+			p_cell=hash_table->entrys[i].first_cell;
145
+			for( ; p_cell; p_cell = tmp_cell )
146
+			{
147
+				tmp_cell = p_cell->next_cell;
148
+				free_cell( p_cell );
149
+			}
150
+		}
151
+
152
+		/* the mutexs for sync the lists are released*/
153
+		for ( i=0 ; i<NR_OF_TIMER_LISTS ; i++ )
154
+			release_timerlist_lock( &(hash_table->timers[i]) );
155
+
156
+		sh_free( hash_table );
157
+	}
158
+}
159
+
160
+
161
+
162
+
163
+/*
164
+ */
165
+struct s_table* init_hash_table()
166
+{
167
+	struct s_table*  hash_table;
168
+	int              i;
169
+
170
+	/*allocs the table*/
171
+	hash_table = (struct s_table*)sh_malloc( sizeof( struct s_table ) );
172
+	if ( !hash_table )
173
+		goto error;
174
+
175
+	memset( hash_table, 0, sizeof (struct s_table ) );
176
+
177
+	/* try first allocating all the structures needed for syncing */
178
+	if (lock_initialize()==-1)
179
+		goto error;
180
+
181
+	/* inits the entrys */
182
+	for(  i=0 ; i<TABLE_ENTRIES; i++ )
183
+	{
184
+		init_entry_lock( hash_table , (hash_table->entrys)+i );
185
+		hash_table->entrys[i].next_label = rand();
186
+	}
187
+
188
+	/* inits the timers*/
189
+	for(  i=0 ; i<NR_OF_TIMER_LISTS ; i++ )
190
+		init_timer_list( hash_table, i );
191
+
192
+	return  hash_table;
193
+
194
+error:
195
+	free_hash_table( hash_table );
196
+	lock_cleanup();
197
+	return 0;
198
+}
199
+
200
+
201
+
202
+
188 203
 /*  Takes an already created cell and links it into hash table on the
189
-  *  appropiate entry.
190
-  */
191
-void    insert_into_hash_table_unsafe( struct s_table *hash_table,  struct cell * p_cell )
204
+ *  appropiate entry. */
205
+void insert_into_hash_table_unsafe( struct s_table *hash_table,
206
+											struct cell * p_cell )
192 207
 {
193 208
 	struct entry* p_entry;
194 209
 
... ...
@@ -205,7 +220,10 @@ void    insert_into_hash_table_unsafe( struct s_table *hash_table,  struct cell
205 220
 	p_entry->last_cell = p_cell;
206 221
 }
207 222
 
208
-void insert_into_hash_table( struct s_table *hash_table,  struct cell * p_cell )
223
+
224
+
225
+
226
+void insert_into_hash_table(struct s_table *hash_table,  struct cell * p_cell)
209 227
 {
210 228
 	lock( &(hash_table->entrys[ p_cell->hash_index ].mutex) );
211 229
 	insert_into_hash_table_unsafe( hash_table,  p_cell );
... ...
@@ -215,30 +233,25 @@ void insert_into_hash_table( struct s_table *hash_table,  struct cell * p_cell )
215 233
 
216 234
 
217 235
 
218
-/*  Un-link a  cell from hash_table, but the cell itself is not released
219
-  */
220
-void remove_from_hash_table( struct s_table *hash_table,  struct cell * p_cell )
236
+/*  Un-link a  cell from hash_table, but the cell itself is not released */
237
+void remove_from_hash_table(struct s_table *hash_table,  struct cell * p_cell)
221 238
 {
222
-   struct entry*  p_entry  = &(hash_table->entrys[p_cell->hash_index]);
239
+	struct entry*  p_entry  = &(hash_table->entrys[p_cell->hash_index]);
223 240
 
224
-   /* unlink the cell from entry list */
225
-   lock( &(p_entry->mutex) );
241
+	/* unlink the cell from entry list */
242
+	lock( &(p_entry->mutex) );
226 243
 
227
-   if ( p_cell->prev_cell )
228
-      p_cell->prev_cell->next_cell = p_cell->next_cell;
229
-   else
230
-      p_entry->first_cell = p_cell->next_cell;
244
+	if ( p_cell->prev_cell )
245
+		p_cell->prev_cell->next_cell = p_cell->next_cell;
246
+	else
247
+		p_entry->first_cell = p_cell->next_cell;
231 248
 
232
-   if ( p_cell->next_cell )
233
-      p_cell->next_cell->prev_cell = p_cell->prev_cell;
234
-   else
235
-      p_entry->last_cell = p_cell->prev_cell;
249
+	if ( p_cell->next_cell )
250
+		p_cell->next_cell->prev_cell = p_cell->prev_cell;
251
+	else
252
+		p_entry->last_cell = p_cell->prev_cell;
236 253
 
237
-   unlock( &(p_entry->mutex) );
254
+	unlock( &(p_entry->mutex) );
238 255
 }
239 256
 
240 257
 
241
-
242
-
243
-
244
-
... ...
@@ -31,17 +31,26 @@ struct timer;
31 31
 #define T_NULL       ( (struct cell*) 0 )
32 32
 
33 33
 
34
-#define NO_CANCEL       ( (struct retrans_buff*) 0 )
35
-#define EXTERNAL_CANCEL ( (struct retrans_buff*) -1)
34
+#define NO_CANCEL       ( (char*) 0 )
35
+#define EXTERNAL_CANCEL ( (char*) -1)
36 36
 
37
-#define STATUS_LOCAL_CANCEL -1
38
-#define STATUS_REQUEST       0
37
+#define TYPE_LOCAL_CANCEL -1
38
+#define TYPE_REQUEST       0
39 39
 
40 40
 
41
-typedef struct retrans_buff
41
+
42
+typedef struct retr_buf
42 43
 {
43
-	char *retr_buffer;
44
-	int   bufflen;
44
+	int activ_type;
45
+	/* set to status code if the buffer is a reply,
46
+	0 if request or -1 if local CANCEL */
47
+
48
+	char *buffer;
49
+	int   buffer_len;
50
+	char *ack;
51
+	int   ack_len;
52
+	char *cancel;
53
+	int   cancel_len;
45 54
 
46 55
 	struct sockaddr_in to;
47 56
 	size_t tolen;
... ...
@@ -49,18 +58,39 @@ typedef struct retrans_buff
49 58
 	/* a message can be linked just to retransmission and FR list */
50 59
 	struct timer_link retr_timer;
51 60
 	struct timer_link fr_timer;
61
+	enum lists retr_list;
52 62
 
53 63
 	/*the cell that containes this retrans_buff*/
54 64
 	struct cell* my_T;
55 65
 	unsigned int branch;
56 66
 
57
-	enum lists retr_list;
67
+}retr_buf_type;
68
+
69
+
70
+
71
+/* User Agent Server content */
72
+
73
+typedef struct ua_server
74
+{
75
+	struct sip_msg   *request;
76
+	struct retr_buf  response;
77
+	unsigned int     status;
78
+	str              *tag;
79
+	unsigned int     isACKed;
80
+}ua_server_type;
58 81
 
59
-	/* set to status code if the buffer is a reply, 
60
-	0 if request or -1 if local CANCEL */
61
-	int status;
62 82
 
63
-}retrans_buff_type;
83
+
84
+/* User Agent Client content */
85
+
86
+typedef struct ua_client
87
+{
88
+	struct retr_buf  request;
89
+	unsigned int     status;
90
+	str              tag;
91
+	unsigned int     rpl_received;
92
+}ua_client_type;
93
+
64 94
 
65 95
 
66 96
 /* transaction context */
... ...
@@ -82,23 +112,17 @@ typedef struct cell
82 112
 	struct timer_link wait_tl;
83 113
 	struct timer_link dele_tl;
84 114
 
85
-	/*the transaction that is canceled (usefull only for CANCEL req)*/
86
-	struct cell *T_canceled;
87
-
88 115
 	/* useful data */
116
+	/* number of forks */
117
+	int nr_of_outgoings;
118
+	/* nr of replied branch */
119
+	int relaied_reply_branch;
120
+	/* transaction that is canceled (usefull only for CANCEL req) */
121
+	struct cell *T_canceled;
89 122
 	/* UA Server */
90
-	struct sip_msg       *inbound_request;
91
-	struct retrans_buff   outbound_response;
92
-	unsigned int          status;
93
-	str                  *tag;
94
-	unsigned int          inbound_request_isACKed;
95
-	int                   relaied_reply_branch;
96
-	int                   nr_of_outgoings;
123
+	struct ua_server  uas;
97 124
 	/* UA Clients */
98
-	struct retrans_buff   *outbound_request[ MAX_FORK ];
99
-	struct sip_msg        *inbound_response[ MAX_FORK ];
100
-	struct retrans_buff   *outbound_ack[ MAX_FORK ];
101
-	struct retrans_buff   *outbound_cancel[ MAX_FORK ];
125
+	struct ua_client  uac[ MAX_FORK ];
102 126
 
103 127
 	/* protection against concurrent reply processing */
104 128
 	ser_lock_t   reply_mutex;
... ...
@@ -131,12 +155,12 @@ typedef struct cell
131 155
 /* double-linked list of cells with hash synonyms */
132 156
 typedef struct entry
133 157
 {
134
-   struct cell*       first_cell;
135
-   struct cell*       last_cell;
136
-   /* currently highest sequence number in a synonym list */
137
-   unsigned int    next_label;
138
-   /* sync mutex */
139
-   ser_lock_t                 mutex;
158
+	struct cell*    first_cell;
159
+	struct cell*    last_cell;
160
+	/* currently highest sequence number in a synonym list */
161
+	unsigned int    next_label;
162
+	/* sync mutex */
163
+	ser_lock_t      mutex;
140 164
 }entry_type;
141 165
 
142 166
 
... ...
@@ -144,19 +168,23 @@ typedef struct entry
144 168
 /* transaction table */
145 169
 struct s_table
146 170
 {
147
-   /* table of hash entries; each of them is a list of synonyms  */
148
-   struct entry   entrys[ TABLE_ENTRIES ];
149
-   /* table of timer lists */
150
-   struct timer   timers[ NR_OF_TIMER_LISTS ];
171
+	/* table of hash entries; each of them is a list of synonyms  */
172
+	struct entry   entrys[ TABLE_ENTRIES ];
173
+	/* table of timer lists */
174
+	struct timer   timers[ NR_OF_TIMER_LISTS ];
151 175
 };
152 176
 
153 177
 
178
+
154 179
 struct s_table* init_hash_table();
155
-void free_hash_table( struct s_table* hash_table );
156
-void free_cell( struct cell* dead_cell );
180
+void   free_hash_table( struct s_table* hash_table );
181
+void   free_cell( struct cell* dead_cell );
157 182
 struct cell*  build_cell( struct sip_msg* p_msg );
158
-void remove_from_hash_table( struct s_table *hash_table, struct cell * p_cell );
159
-void insert_into_hash_table( struct s_table *hash_table, struct cell * p_cell );
160
-void insert_into_hash_table_unsafe( struct s_table *hash_table, struct cell * p_cell );
183
+void   remove_from_hash_table(struct s_table *hash_table,struct cell * p_cell);
184
+void   insert_into_hash_table(struct s_table *hash_table,struct cell * p_cell);
185
+void   insert_into_hash_table_unsafe( struct s_table *hash_table,
186
+		struct cell * p_cell );
161 187
 
162 188
 #endif
189
+
190
+
... ...
@@ -23,9 +23,12 @@
23 23
 
24 24
 
25 25
 
26
-struct cell         *T;
26
+struct cell      *T;
27 27
 unsigned int     global_msg_id;
28 28
 struct s_table*  hash_table;
29
+unsigned int     nr_forks;
30
+unsigned int     t_forks[MAX_FORK+1][2];
31
+
29 32
 
30 33
 void timer_routine(unsigned int, void*);
31 34
 
... ...
@@ -51,6 +54,9 @@ int tm_startup()
51 54
 	/* register the timer function */
52 55
 	register_timer( timer_routine , hash_table , 1 );
53 56
 
57
+	/* fork table */
58
+	nr_forks = 0;
59
+
54 60
 	/*first msg id*/
55 61
 	global_msg_id = 0;
56 62
 	T = T_UNDEFINED;
... ...
@@ -157,28 +163,28 @@ int t_unref( /* struct sip_msg* p_msg */ )
157 163
 /* ----------------------------HELPER FUNCTIONS-------------------------------- */
158 164
 
159 165
 
160
-int t_update_timers_after_sending_reply( struct retrans_buff *rb )
166
+int t_update_timers_after_sending_reply( struct retr_buf *rb )
161 167
 {
162 168
 	struct cell *Trans = rb->my_T;
163 169
 
164 170
 	/* make sure that if we send something final upstream, everything else
165 171
 	   will be cancelled */
166
-	if (Trans->status>=300&&Trans->inbound_request->REQ_METHOD==METHOD_INVITE)
172
+	if (Trans->uas.status>=300&&Trans->uas.request->REQ_METHOD==METHOD_INVITE)
167 173
 	{
168 174
 		rb->retr_list = RT_T1_TO_1;
169 175
 		set_timer( hash_table, &(rb->retr_timer), RT_T1_TO_1 );
170 176
 		set_timer( hash_table, &(rb->fr_timer), FR_TIMER_LIST );
171
-	} else if ( Trans->inbound_request->REQ_METHOD==METHOD_CANCEL ) {
177
+	} else if ( Trans->uas.request->REQ_METHOD==METHOD_CANCEL ) {
172 178
 		if ( Trans->T_canceled==T_UNDEFINED )
173 179
 			Trans->T_canceled = t_lookupOriginalT( hash_table ,
174
-				Trans->inbound_request );
180
+				Trans->uas.request );
175 181
 		if ( Trans->T_canceled==T_NULL )
176 182
 			return 1;
177 183
 		/* put CANCEL transaction on wait only if canceled transaction already
178 184
 		    is in final status and there is nothing to cancel; */
179
-		if ( Trans->T_canceled->status>=200)
185
+		if ( Trans->T_canceled->uas.status>=200)
180 186
 			t_put_on_wait( Trans );
181
-	} else if (Trans->status>=200)
187
+	} else if (Trans->uas.status>=200)
182 188
 		t_put_on_wait( Trans );
183 189
    return 1;
184 190
 }
... ...
@@ -192,13 +198,13 @@ int t_update_timers_after_sending_reply( struct retrans_buff *rb )
192 198
  * Returns 	- branch number (0,1,...) which should be relayed
193 199
  *         -1 if nothing to be relayed
194 200
  */
195
-int t_should_relay_response( struct cell *Trans , int new_code, 
196
-	int branch , int *should_store )
201
+int t_should_relay_response( struct cell *Trans , int new_code,
202
+									int branch , int *should_store )
197 203
 {
198 204
 	int T_code;
199 205
 	int b, lowest_b, lowest_s;
200 206
 
201
-	T_code = Trans->status;
207
+	T_code = Trans->uac[branch].status;
202 208
 
203 209
 	/* note: this code never lets replies to CANCEL go through;
204 210
 	   we generate always a local 200 for CANCEL; 200s are
... ...
@@ -208,9 +214,9 @@ int t_should_relay_response( struct cell *Trans , int new_code,
208 214
 	*/
209 215
 
210 216
 	/* if final response sent out, allow only INVITE 2xx  */
211
-	if ( T_code >= 200 ) { 
217
+	if ( T_code >= 200 ) {
212 218
 		if (new_code>=200 && new_code < 300  && 
213
-			Trans->inbound_request->REQ_METHOD==METHOD_INVITE) {
219
+			Trans->uas.request->REQ_METHOD==METHOD_INVITE) {
214 220
 			DBG("DBG: t_should_relay: 200 INV after final sent\n");
215 221
 			*should_store=1;
216 222
 			return branch;
... ...
@@ -234,13 +240,12 @@ int t_should_relay_response( struct cell *Trans , int new_code,
234 240
 					continue;
235 241
 				}
236 242
 				/* there is still an unfinished UAC transaction; wait now! */
237
-				if ( !Trans->inbound_response[b] ||
238
-					Trans->inbound_response[b]->REPLY_STATUS<200 )
243
+				if ( Trans->uac[b].status<200 )
239 244
 					return -1;
240
-				if ( Trans->inbound_response[b]->REPLY_STATUS<lowest_s )
245
+				if ( Trans->uac[b].status<lowest_s )
241 246
 				{
242 247
 					lowest_b =b;
243
-					lowest_s = T->inbound_response[b]->REPLY_STATUS;
248
+					lowest_s = T->uac[b].status;
244 249
 				}
245 250
 			}
246 251
 			return lowest_b;
... ...
@@ -251,9 +256,10 @@ int t_should_relay_response( struct cell *Trans , int new_code,
251 256
 		}
252 257
 		/* 100 won't be relayed */
253 258
 		else {
254
-			if (!T->inbound_response[branch]) *should_store=1;
259
+			if (!T->uac[branch].rpl_received) *should_store=1;
255 260
 			else *should_store=0;
256
-			return -1;
261
+			if (T_code==0) return branch;
262
+				else return -1;
257 263
 		}
258 264
 	}
259 265
 
... ...
@@ -299,9 +305,8 @@ int t_put_on_wait(  struct cell  *Trans  )
299 305
 
300 306
 	/* cancel pending client transactions, if any */
301 307
 	for( i=0 ; i<Trans->nr_of_outgoings ; i++ )
302
-		if ( Trans->inbound_response[i] && 
303
-		REPLY_CLASS(Trans->inbound_response[i])==1)
304
-			t_cancel_branch(i);
308
+		if ( Trans->uac[i].rpl_received && Trans->uac[i].status<200 )
309
+			t_build_and_send_CANCEL(Trans , i);
305 310
 
306 311
 
307 312
 	/* we don't need outbound requests anymore -- let's save
... ...
@@ -329,155 +334,6 @@ int t_put_on_wait(  struct cell  *Trans  )
329 334
 
330 335
 
331 336
 
332
-/*
333
-  */
334
-int t_cancel_branch(unsigned int branch)
335
-{
336
-	LOG(L_ERR, "ERROR: t_cancel_branch: NOT IMPLEMENTED YET\n");
337
-	return 1;
338
-}
339
-
340
-
341
-
342
-#ifdef _REALLY_TOO_OLD
343
-/* Builds an ACK request based on an INVITE request. ACK is send
344
-  * to same address */
345
-int t_build_and_send_ACK(struct cell *Trans,unsigned int branch,
346
-														struct sip_msg* rpl)
347
-{
348
-	struct sip_msg      *p_msg , *r_msg;
349
-	struct hdr_field    *hdr;
350
-	char                *ack_buf, *p, *via;
351
-	unsigned int         len, via_len;
352
-	int                  n;
353
-	struct retrans_buff *srb;
354
-
355
-	ack_buf = 0;
356
-	via =0;
357
-	p_msg = Trans->inbound_request;
358
-	r_msg = rpl;
359
-
360
-	if ( parse_headers(rpl,HDR_TO)==-1 || !rpl->to )
361
-	{
362
-		LOG(L_ERR, "ERROR: t_build_and_send_ACK: "
363
-			"cannot generate a HBH ACK if key HFs in reply missing\n");
364
-		goto error;
365
-	}
366
-
367
-	len = 0;
368
-	/*first line's len */
369
-	len += 4/*reply code and one space*/+
370
-		p_msg->first_line.u.request.version.len+CRLF_LEN;
371
-	/*uri's len*/
372
-	if (p_msg->new_uri.s)
373
-		len += p_msg->new_uri.len +1;
374
-	else
375
-		len += p_msg->first_line.u.request.uri.len +1;
376
-	/*via*/
377
-	via = via_builder( p_msg , &via_len );
378
-	if (!via)
379
-	{
380
-		LOG(L_ERR, "ERROR: t_build_and_send_ACK: "
381
-			"no via header got from builder\n");
382
-		goto error;
383
-	}
384
-	len+= via_len;
385
-	/*headers*/
386
-	for ( hdr=p_msg->headers ; hdr ; hdr=hdr->next )
387
-		if (hdr->type==HDR_FROM||hdr->type==HDR_CALLID||hdr->type==HDR_CSEQ)
388
-			len += ((hdr->body.s+hdr->body.len ) - hdr->name.s ) + CRLF_LEN ;
389
-		else if ( hdr->type==HDR_TO )
390
-			len += ((r_msg->to->body.s+r_msg->to->body.len ) -
391
-				r_msg->to->name.s ) + CRLF_LEN ;
392
-	/* CSEQ method : from INVITE-> ACK */
393
-	len -= 3  ;
394
-	/* end of message */
395
-	len += CRLF_LEN; /*new line*/
396
-
397
-	srb=(struct retrans_buff*)sh_malloc(sizeof(struct retrans_buff)+len+1);
398
-	if (!srb)
399
-	{
400
-		LOG(L_ERR, "ERROR: t_build_and_send_ACK: cannot allocate memory\n");
401
-		goto error1;
402
-	}
403
-	ack_buf = (char *) srb + sizeof(struct retrans_buff);
404
-	p = ack_buf;
405
-
406
-	/* first line */
407
-	memcpy( p , "ACK " , 4);
408
-	p += 4;
409
-	/* uri */
410
-	if ( p_msg->new_uri.s )
411
-	{
412
-		memcpy(p,p_msg->orig+(p_msg->new_uri.s-p_msg->buf),p_msg->new_uri.len);
413
-		p +=p_msg->new_uri.len;
414
-	}else{
415
-		memcpy(p,p_msg->orig+(p_msg->first_line.u.request.uri.s-p_msg->buf),
416
-			p_msg->first_line.u.request.uri.len );
417
-		p += p_msg->first_line.u.request.uri.len;
418
-	}
419
-	/* SIP version */
420
-	*(p++) = ' ';
421
-	memcpy(p,p_msg->orig+(p_msg->first_line.u.request.version.s-p_msg->buf),
422
-		p_msg->first_line.u.request.version.len );
423
-	p += p_msg->first_line.u.request.version.len;
424
-	memcpy( p, CRLF, CRLF_LEN );
425
-	p+=CRLF_LEN;
426
-
427
-	/* insert our via */
428
-	memcpy( p , via , via_len );
429
-	p += via_len;
430
-
431
-	/*other headers*/
432
-	for ( hdr=p_msg->headers ; hdr ; hdr=hdr->next )
433
-	{
434
-		if ( hdr->type==HDR_FROM || hdr->type==HDR_CALLID  )
435
-		{
436
-			memcpy( p , p_msg->orig+(hdr->name.s-p_msg->buf) ,
437
-				((hdr->body.s+hdr->body.len ) - hdr->name.s ) );
438
-			p += ((hdr->body.s+hdr->body.len ) - hdr->name.s );
439
-			memcpy( p, CRLF, CRLF_LEN );
440
-			p+=CRLF_LEN;
441
-		}
442
-		else if ( hdr->type==HDR_TO )
443
-		{
444
-			memcpy( p , r_msg->orig+(r_msg->to->name.s-r_msg->buf) ,
445
-				((r_msg->to->body.s+r_msg->to->body.len)-r_msg->to->name.s));
446
-			p+=((r_msg->to->body.s+r_msg->to->body.len)-r_msg->to->name.s);
447
-			memcpy( p, CRLF, CRLF_LEN );
448
-			p+=CRLF_LEN;
449
-		}
450
-		else if ( hdr->type==HDR_CSEQ )
451
-		{
452
-			memcpy( p , p_msg->orig+(hdr->name.s-p_msg->buf) ,
453
-				((((struct cseq_body*)hdr->parsed)->method.s)-hdr->name.s));
454
-			p+=((((struct cseq_body*)hdr->parsed)->method.s)-hdr->name.s);
455
-			memcpy( p , "ACK" CRLF, 3+CRLF_LEN );
456
-			p += 3+CRLF_LEN;
457
-		}
458
-	}
459
-
460
-	/* end of message */
461
-	memcpy( p , CRLF , CRLF_LEN );
462
-	p += CRLF_LEN;
463
-
464
-	send_ack( T, branch, srb, p-ack_buf );
465
-	pkg_free( via );
466
-	DBG("DEBUG: t_build_and_send_ACK: ACK sent\n");
467
-	return 0;
468
-
469
-error1:
470
-	pkg_free(via );
471
-error:
472
-	return -1;
473
-}
474
-
475
-#endif /* _REALLY_TOO_OLD */
476
-
477
-
478
-
479
-
480
-
481 337
 /* Builds a CANCEL request based on an INVITE request. CANCEL is send
482 338
  * to same address as the INVITE */
483 339
 int t_build_and_send_CANCEL(struct cell *Trans,unsigned int branch)
... ...
@@ -486,26 +342,24 @@ int t_build_and_send_CANCEL(struct cell *Trans,unsigned int branch)
486 342
 	struct hdr_field    *hdr;
487 343
 	char                *cancel_buf, *p, *via;
488 344
 	unsigned int         len, via_len;
489
-	struct retrans_buff *srb;
490
-
491 345
 
492
-	if ( !Trans->inbound_response[branch] )
346
+	if ( !Trans->uac[branch].rpl_received )
493 347
 	{
494 348
 		DBG("DEBUG: t_build_and_send_CANCEL: no response ever received"
495 349
 			" : dropping local cancel! \n");
496 350
 		return 1;
497 351
 	}
498 352
 
499
-	if (Trans->outbound_cancel[branch]!=NO_CANCEL)
353
+	if (Trans->uac[branch].request.cancel!=NO_CANCEL)
500 354
 	{
501
-		DBG("DEBUG: t_build_and_send_CANCEL: this branch was already canceled"
502
-			" : dropping local cancel! \n");
355
+		DBG("DEBUG: t_build_and_send_CANCEL: branch (%d)was already canceled"
356
+			" : dropping local cancel! \n",branch);
503 357
 		return 1;
504 358
 	}
505 359
 
506 360
 	cancel_buf = 0;
507 361
 	via = 0;
508
-	p_msg = Trans->inbound_request;
362
+	p_msg = Trans->uas.request;
509 363
 
510 364
 	len = 0;
511 365
 	/*first line's len - CANCEL and INVITE has the same lenght */
... ...
@@ -515,6 +369,8 @@ int t_build_and_send_CANCEL(struct cell *Trans,unsigned int branch)
515 369
 	if (p_msg->new_uri.s)
516 370
 		len += p_msg->new_uri.len - req_line(p_msg).uri.len;
517 371
 	/*via*/
372
+	if ( add_branch_label(Trans,p_msg,branch)==-1 )
373
+		goto error;
518 374
 	via = via_builder( p_msg , &via_len );
519 375
 	if (!via)
520 376
 	{
... ...
@@ -535,13 +391,12 @@ int t_build_and_send_CANCEL(struct cell *Trans,unsigned int branch)
535 391
 	/* end of message */
536 392
 	len += CRLF_LEN;
537 393
 
538
-	srb=(struct retrans_buff*)sh_malloc(sizeof(struct retrans_buff)+len+1);
539
-	if (!srb)
394
+	cancel_buf=sh_malloc( len+1 );
395
+	if (!cancel_buf)
540 396
 	{
541 397
 		LOG(L_ERR, "ERROR: t_build_and_send_CANCEL: cannot allocate memory\n");
542 398
 		goto error;
543 399
 	}
544
-	cancel_buf = (char*) srb + sizeof(struct retrans_buff);
545 400
 	p = cancel_buf;
546 401
 
547 402
 	/* first line -> do we have a new URI? */
... ...
@@ -590,30 +445,23 @@ int t_build_and_send_CANCEL(struct cell *Trans,unsigned int branch)
590 445
 	append_mem_block(p,CRLF,CRLF_LEN);
591 446
 	*p=0;
592 447
 
593
-	memset( srb, 0, sizeof( struct retrans_buff ) );
594
-	memcpy( & srb->to, & Trans->outbound_request[branch]->to,
595
-		sizeof (struct sockaddr_in));
596
-	srb->tolen = sizeof (struct sockaddr_in);
597
-	srb->my_T = Trans;
598
-	srb->fr_timer.payload = srb->retr_timer.payload = srb;
599
-	srb->branch = branch;
600
-	srb->status = STATUS_LOCAL_CANCEL;
601
-	srb->retr_buffer = (char *) srb + sizeof( struct retrans_buff );
602
-	srb->bufflen = len;
603
-	if (Trans->outbound_cancel[branch]) {
604
-		shm_free( srb );	
448
+	if (Trans->uac[branch].request.cancel) {
449
+		shm_free( cancel_buf );
605 450
 		LOG(L_WARN, "send_cancel: Warning: CANCEL already sent out\n");
606 451
 		goto error;
607 452
 	}
608
-	Trans->outbound_cancel[branch] = srb;
609
-	/*sets and starts the FINAL RESPONSE timer */
610
-	set_timer( hash_table, &(srb->fr_timer), FR_TIMER_LIST );
611 453
 
454
+	Trans->uac[branch].request.activ_type = TYPE_LOCAL_CANCEL;
455
+	Trans->uac[branch].request.cancel = cancel_buf;
456
+	Trans->uac[branch].request.cancel_len = len;
457
+
458
+	/*sets and starts the FINAL RESPONSE timer */
459
+	set_timer(hash_table,&(Trans->uac[branch].request.fr_timer),FR_TIMER_LIST);
612 460
 	/* sets and starts the RETRANS timer */
613
-	srb->retr_list = RT_T1_TO_1;
614
-	set_timer( hash_table, &(srb->retr_timer), RT_T1_TO_1 );
461
+	Trans->uac[branch].request.retr_list = RT_T1_TO_1;
462
+	set_timer(hash_table,&(Trans->uac[branch].request.retr_timer),RT_T1_TO_1);
615 463
 	DBG("DEBUG: T_build_and_send_CANCEL : sending cancel...\n");
616
-	SEND_BUFFER( srb );
464
+	SEND_CANCEL_BUFFER( &(Trans->uac[branch].request) );
617 465
 
618 466
 	pkg_free(via);
619 467
 	return 1;
... ...
@@ -692,12 +540,12 @@ void delete_cell( struct cell *p_cell )
692 540
 int get_ip_and_port_from_uri( struct sip_msg* p_msg , unsigned int *param_ip, unsigned int *param_port)
693 541
 {
694 542
 	struct hostent  *nhost;
695
-	unsigned int      ip, port;
696
-	struct sip_uri    parsed_uri;
697
-	str                      uri;
698
-	int                      err;
543
+	unsigned int    ip, port;
544
+	struct sip_uri  parsed_uri;
545
+	str             uri;
546
+	int             err;
699 547
 #ifdef DNS_IP_HACK
700
-	int                      len;
548
+	int             len;
701 549
 #endif
702 550
 
703 551
 	/* the original uri has been changed? */
... ...
@@ -763,6 +611,34 @@ error:
763 611
 
764 612
 
765 613
 
614
+int t_add_fork( unsigned int ip , unsigned int port)
615
+{
616
+	if (nr_forks+1>=MAX_FORK)
617
+	{
618
+		LOG(L_ERR,"ERROR:t_add_fork: trying to add new fork ->"
619
+			" MAX_FORK exceded\n");
620
+		return -1;
621
+	}
622
+
623
+	nr_forks++;
624
+	t_forks[nr_forks][0] = ip;
625
+	t_forks[nr_forks][1] = port;
626
+
627
+	return 1;
628
+}
629
+
630
+
631
+
632
+
633
+int t_clear_forks( )
634
+{
635
+	nr_forks = 0;
636
+	return 1;
637
+}
638
+
639
+
640
+
641
+
766 642
 
767 643
 
768 644
 /*---------------------------TIMERS FUNCTIONS-------------------------------*/
... ...
@@ -773,10 +649,10 @@ error:
773 649
 
774 650
 inline void retransmission_handler( void *attr)
775 651
 {
776
-	struct retrans_buff* r_buf ;
652
+	struct retr_buf* r_buf ;
777 653
 	enum lists id;
778
-	DBG("DEBUG: entering retransmisson with attr = %p\n",attr);
779
-	r_buf = (struct retrans_buff*)attr;
654
+
655
+	r_buf = (struct retr_buf*)attr;
780 656
 #ifdef EXTRA_DEBUG
781 657
 	if (r_buf->my_T->damocles) {
782 658
 		LOG( L_ERR, "ERROR: transaction %p scheduled for deletion and"
... ...
@@ -788,11 +664,17 @@ inline void retransmission_handler( void *attr)
788 664
 	/*the transaction is already removed from RETRANSMISSION_LIST by timer*/
789 665
 	/* retransmision */
790 666
 	DBG("DEBUG: retransmission_handler : resending (t=%p)\n", r_buf->my_T);
791
-	if (r_buf->status!=STATUS_LOCAL_CANCEL && r_buf->status!=STATUS_REQUEST){
792
-		T=r_buf->my_T;
793
-		t_retransmit_reply();
794
-	}else{
795
-		SEND_BUFFER( r_buf );
667
+	switch ( r_buf->activ_type )
668
+	{
669
+		case (TYPE_REQUEST):
670
+			SEND_BUFFER( r_buf );
671
+			break;
672
+		case (TYPE_LOCAL_CANCEL):
673
+			SEND_CANCEL_BUFFER( r_buf );
674
+			break;
675
+		default:
676
+			T=r_buf->my_T;
677
+			t_retransmit_reply();
796 678
 	}
797 679
 
798 680
 	id = r_buf->retr_list;
... ...
@@ -808,7 +690,7 @@ inline void retransmission_handler( void *attr)
808 690
 
809 691
 inline void final_response_handler( void *attr)
810 692
 {
811
-	struct retrans_buff* r_buf = (struct retrans_buff*)attr;
693
+	struct retr_buf* r_buf = (struct retr_buf*)attr;
812 694
 
813 695
 #ifdef EXTRA_DEBUG
814 696
 	if (r_buf->my_T->damocles) 
... ...
@@ -820,16 +702,16 @@ inline void final_response_handler( void *attr)
820 702
 #endif
821 703
 
822 704
 	/* the transaction is already removed from FR_LIST by the timer */
823
-	if (r_buf->status==STATUS_LOCAL_CANCEL)
705
+	if (r_buf->activ_type==TYPE_LOCAL_CANCEL)
824 706
 	{
825 707
 		DBG("DEBUG: FR_handler: stop retransmission for Local Cancel\n");
826 708
 		reset_timer( hash_table , &(r_buf->retr_timer) );
827 709
 		return;
828 710
 	}
829 711
 	/* send a 408 */
830
-	if ( r_buf->my_T->status<200
712
+	if ( r_buf->my_T->uac[r_buf->branch].status<200
831 713
 #ifdef SILENT_FR
832
-	&& (0)
714
+	&& (r_buf->my_T->nr_of_outgoings>1)
833 715
 	/*should be fork==yes, but we don't have forking yet - bogdan */
834 716
 #endif
835 717
 	)
... ...
@@ -843,9 +725,10 @@ inline void final_response_handler( void *attr)
843 725
 		FR timer; thus I fake the values now to avoid recalculating T
844 726
 		and refcount++ JKU */
845 727
 		T=r_buf->my_T;
846
-		global_msg_id=T->inbound_request->id;
728
+		global_msg_id=T->uas.request->id;
847 729
 		DBG("DEBUG: FR_handler: send 408 (%p)\n", r_buf->my_T);
848
-		t_send_reply( r_buf->my_T->inbound_request,408,"Request Timeout" );
730
+		t_send_reply( r_buf->my_T->uas.request, 408, "Request Timeout",
731
+			r_buf->branch);
849 732
 	}else{
850 733
 		/* put it on WT_LIST - transaction is over */
851 734
 		DBG("DEBUG: final_response_handler:-> put on wait"
... ...
@@ -966,26 +849,23 @@ void timer_routine(unsigned int ticks , void * attr)
966 849
 
967 850
 
968 851
 
969
-#ifndef _REALLY_TOO_OLD
970
-
971 852
 /* Builds an ACK request based on an INVITE request. ACK is send
972
-  * to same address */
973
-struct retrans_buff *build_ack( struct sip_msg* rpl, struct cell *trans, int branch )
853
+ * to same address */
854
+char *build_ack(struct sip_msg* rpl,struct cell *trans,int branch,int *ret_len)
974 855
 {
975 856
 	struct sip_msg      *p_msg , *r_msg;
976 857
 	struct hdr_field    *hdr;
977 858
 	char                *ack_buf, *p, *via;
978 859
 	unsigned int         len, via_len;
979
-	struct retrans_buff *srb;
980 860
 
981 861
 	ack_buf = 0;
982 862
 	via =0;
983
-	p_msg = trans->inbound_request;
863
+	p_msg = trans->uas.request;
984 864
 	r_msg = rpl;
985 865
 
986 866
 	if ( parse_headers(rpl,HDR_TO)==-1 || !rpl->to )
987 867
 	{
988
-		LOG(L_ERR, "ERROR: t_build_and_send_ACK: "
868
+		LOG(L_ERR, "ERROR: t_build_ACK: "
989 869
 			"cannot generate a HBH ACK if key HFs in reply missing\n");
990 870
 		goto error;
991 871
 	}
... ...
@@ -999,11 +879,14 @@ struct retrans_buff *build_ack( struct sip_msg* rpl, struct cell *trans, int bra
999 879
 		len += p_msg->new_uri.len +1;
1000 880
 	else
1001 881
 		len += p_msg->first_line.u.request.uri.len +1;
882
+	/*adding branch param*/
883
+	if ( add_branch_label( trans , trans->uas.request , branch)==-1 )
884
+		goto error;
1002 885
 	/*via*/
1003 886
 	via = via_builder( p_msg , &via_len );
1004 887
 	if (!via)
1005 888
 	{
1006
-		LOG(L_ERR, "ERROR: t_build_and_send_ACK: "
889
+		LOG(L_ERR, "ERROR: t_build_ACK: "
1007 890
 			"no via header got from builder\n");
1008 891
 		goto error;
1009 892
 	}
... ...
@@ -1020,13 +903,12 @@ struct retrans_buff *build_ack( struct sip_msg* rpl, struct cell *trans, int bra
1020 903
 	/* end of message */
1021 904
 	len += CRLF_LEN; /*new line*/
1022 905
 
1023
-	srb=(struct retrans_buff*)sh_malloc(sizeof(struct retrans_buff)+len+1);
1024
-	if (!srb)
906
+	ack_buf = sh_malloc(len+1);
907
+	if (!ack_buf)
1025 908
 	{
1026
-		LOG(L_ERR, "ERROR: t_build_and_send_ACK: cannot allocate memory\n");
909
+		LOG(L_ERR, "ERROR: t_build_and_ACK: cannot allocate memory\n");
1027 910
 		goto error1;
1028 911
 	}
1029
-	ack_buf = (char *) srb + sizeof(struct retrans_buff);
1030 912
 	p = ack_buf;
1031 913
 
1032 914
 	/* first line */
... ...
@@ -1087,16 +969,11 @@ struct retrans_buff *build_ack( struct sip_msg* rpl, struct cell *trans, int bra
1087 969
 	memcpy( p , CRLF , CRLF_LEN );
1088 970
 	p += CRLF_LEN;
1089 971
 
1090
-	/* fill in the structure */
1091
-	srb->bufflen = p-ack_buf;
1092
-	srb->tolen = sizeof( struct sockaddr_in );
1093
-	srb->my_T = trans;
1094
-	srb->retr_buffer = (char *) srb + sizeof( struct retrans_buff );
1095
-	memcpy( &srb->to, & trans->outbound_request[ branch ]->to, sizeof (struct sockaddr_in));
1096
-
1097 972
 	pkg_free( via );
1098
-	DBG("DEBUG: t_build_and_send_ACK: ACK sent\n");
1099
-	return srb;
973
+	DBG("DEBUG: t_build_ACK: ACK generated\n");
974
+
975
+	*(ret_len) = p-ack_buf;
976
+	return ack_buf;
1100 977
 
1101 978
 error1:
1102 979
 	pkg_free(via );
... ...
@@ -1104,6 +981,5 @@ error:
1104 981
 	return 0;
1105 982
 }
1106 983
 
1107
-#endif
1108 984
 
1109 985
 
... ...
@@ -22,10 +22,11 @@ struct timer;
22 22
 struct entry;
23 23
 struct cell;
24 24
 
25
-extern struct cell         *T;
25
+extern struct cell      *T;
26 26
 extern unsigned int     global_msg_id;
27 27
 extern struct s_table*  hash_table;
28
-
28
+extern unsigned int     t_forks[MAX_FORK+1][2];
29
+extern unsigned int     nr_forks;
29 30
 
30 31
 #include "sh_malloc.h"
31 32
 
... ...
@@ -54,31 +55,26 @@ extern struct s_table*  hash_table;
54 55
 
55 56
 #define SEND_PR_BUFFER(_rb,_bf,_le ) \
56 57
 	{\
57
-		if ((_rb) && (_bf) && (_le) ) \
58
-		{\
58
+		if ((_bf) && (_le) && (_bf) ) {\
59 59
 			udp_send( (_bf), (_le), (struct sockaddr*)&((_rb)->to) , \
60 60
 				sizeof(struct sockaddr_in) ); \
61
-		} else { \
62
-			LOG(L_CRIT,"ERROR:attempt to send an empty buffer from %s (%d)"\
63
-				"(%p,%p,%d)\n",__FUNCTION__, __LINE__,(_rb),(_bf),(_le));\
61
+		}else{ \
62
+			LOG(L_CRIT,"ERROR: sending an empty buffer from %s (%d)\n",\
63
+				__FUNCTION__, __LINE__ );\
64 64
 		}\
65
-	}\
65
+	}
66 66
 
67
-#define SEND_BUFFER( _rb ) SEND_PR_BUFFER( \
68
-	_rb,(_rb)->retr_buffer, (_rb)->bufflen )
67
+#define SEND_ACK_BUFFER( _rb ) \
68
+	SEND_PR_BUFFER( (_rb) , (_rb)->ack , (_rb)->ack_len )
69 69
 
70
-/*
71
-#define SEND_BUFFER( _rb ) ({ if ((_rb)->retr_buffer) \
72
-	{ udp_send( (_rb)->retr_buffer, \
73
-	  (_rb)->bufflen, (struct sockaddr*)&((_rb)->to) , \
74
-	  sizeof(struct sockaddr_in) ); \
75
-	} else \
76
-	DBG("ERROR: attempt to send an empty buffer from %s (%d)", \
77
-	__FUNCTION__, __LINE__ ); })
78
-*/
70
+#define SEND_CANCEL_BUFFER( _rb ) \
71
+	SEND_PR_BUFFER( (_rb) , (_rb)->cancel , (_rb)->cancel_len )
72
+
73
+#define SEND_BUFFER( _rb ) \
74
+	SEND_PR_BUFFER( (_rb) , (_rb)->buffer , (_rb)->buffer_len )
79 75
 
80 76
 
81
-/* 
77
+/*
82 78
   macros for reference bitmap (lock-less process non-exclusive ownership) 
83 79
 */
84 80
 #define T_IS_REFED(_T_cell) ((_T_cell)->ref_bitmap)
... ...
@@ -124,24 +120,7 @@ extern struct s_table*  hash_table;
124 120
 #endif
125 121
 
126 122
 
127
-	
128
-
129
-#ifdef _OLD_XX
130
-#define unref_T(_T_cell) \
131
-	( {\
132
-		lock( &(hash_table->entrys[(_T_cell)->hash_index].mutex) );\
133
-		(_T_cell)->ref_counter--;\
134
-		DBG_REF("unref", (_T_cell)); \
135
-		unlock( &(hash_table->entrys[(_T_cell)->hash_index].mutex) );\
136
-	} );
137 123
 
138
-/* we assume that ref_T is only called from places where
139
-   the associated locks are set up and we don't need to
140
-   lock/unlock
141
-*/
142
-#define ref_T(_T_cell) ({ ((_T_cell)->ref_counter++); \
143
-		DBG_REF("ref", (_T_cell));	})
144
-#endif
145 124
 
146 125
 enum addifnew_status { AIN_ERROR, AIN_RETR, AIN_NEW, AIN_NEWACK,
147 126
 	AIN_OLDACK, AIN_RTRACK } ;
... ...
@@ -187,12 +166,12 @@ int t_forward_uri( struct sip_msg* p_msg  );
187 166
 
188 167
 
189 168
 
169
+
190 170
 /* This function is called whenever a reply for our module is received;
191 171
  * we need to register this function on module initialization;
192 172
  * Returns :   0 - core router stops
193 173
  *             1 - core router relay statelessly
194 174
  */
195
-
196 175
 int t_on_reply( struct sip_msg  *p_msg ) ;
197 176
 
198 177
 
... ...
@@ -219,7 +198,7 @@ int t_on_request_received_uri( struct sip_msg  *p_msg ) ;
219 198
 
220 199
 
221 200
 /* returns 1 if everything was OK or -1 for error
222
-*/
201
+ */
223 202
 int t_release_transaction( struct sip_msg* );
224 203
 
225 204
 
... ...
@@ -237,7 +216,7 @@ int t_retransmit_reply( /* struct sip_msg * */  );
237 216
 /* Force a new response into inbound response buffer.
238 217
  * returns 1 if everything was OK or -1 for erro
239 218
  */
240
-int t_send_reply( struct sip_msg * , unsigned int , char *  );
219
+int t_send_reply( struct sip_msg * , unsigned int , char *  , unsigned int);
241 220
 
242 221
 
243 222
 
... ...
@@ -260,42 +239,44 @@ int t_lookup_request( struct sip_msg* p_msg , int leave_new_locked );
260 239
 int t_all_final( struct cell * );
261 240
 int t_build_and_send_ACK( struct cell *Trans , unsigned int brach ,
262 241
 	struct sip_msg* rpl);
263
-int t_cancel_branch(unsigned int branch); //TO DO
264 242
 int t_should_relay_response( struct cell *Trans, int new_code, int branch,
265 243
 	int *should_store );
266
-int t_update_timers_after_sending_reply( struct retrans_buff *rb );
244
+int t_update_timers_after_sending_reply( struct retr_buf *rb );
267 245
 int t_put_on_wait(  struct cell  *Trans  );
268 246
 int relay_lowest_reply_upstream( struct cell *Trans , struct sip_msg *p_msg );
269 247
 int add_branch_label( struct cell *Trans, struct sip_msg *p_msg , int branch );
270 248
 int get_ip_and_port_from_uri( struct sip_msg* p_msg , unsigned int *param_ip,
271 249
 	unsigned int *param_port);
272
-struct retrans_buff *build_ack( struct sip_msg* rpl, struct cell *trans,
273
-	int branch );
250
+int t_build_and_send_CANCEL(struct cell *Trans, unsigned int branch);
251
+char *build_ack( struct sip_msg* rpl, struct cell *trans, int branch ,
252
+	int *ret_len);
274 253
 enum addifnew_status t_addifnew( struct sip_msg* p_msg );
275
-
254
+int t_add_fork( unsigned int ip , unsigned int port);
255
+int t_clear_forks( );
276 256
 
277 257
 
278 258
 
279 259
 inline int static attach_ack(  struct cell *t, int branch,
280
-    struct retrans_buff *srb )
260
+									char *ack, int ack_len )
281 261
 {
282 262
 	LOCK_ACK( t );
283
-	if (t->outbound_ack[branch]) {
263
+	if (t->uac[branch].request.ack) {
284 264
 		UNLOCK_ACK(t);
285
-		shm_free( srb );
265
+		shm_free( ack );
286 266
 		LOG(L_WARN, "attach_ack: Warning: ACK already sent out\n");
287 267
 		return 0;
288 268
 	}
289
-	t->outbound_ack[branch] = srb;
269
+	t->uac[branch].request.ack = ack;
270
+	t->uac[branch].request.ack_len = ack_len;
290 271
 	UNLOCK_ACK( t );
291 272
 	return 1;
292 273
 }
293 274
 
294 275
 
295 276
 
296
-
297
-inline int static relay_ack( struct cell *t, int branch, 
298
-	struct retrans_buff *srb, int len )
277
+/*
278
+inline int static relay_ack( struct cell *t, int branch,
279
+						struct retrans_buff *srb, int len )
299 280
 {
300 281
 	memset( srb, 0, sizeof( struct retrans_buff ) );
301 282
 	memcpy( & srb->to, & t->ack_to, sizeof (struct sockaddr_in));
... ...
@@ -306,7 +287,7 @@ inline int static relay_ack( struct cell *t, int branch,
306 287
 	srb->bufflen = len;
307 288
 	SEND_BUFFER( srb );
308 289
 	return attach_ack( t, branch, srb );
309
-}
290
+}*/
310 291
 
311 292
 
312 293
 
... ...
@@ -360,27 +341,20 @@ static inline void reset_retr_timers( struct s_table *h_table,
360 341
 													struct cell *p_cell )
361 342
 {
362 343
 	int ijk;
363
-	struct retrans_buff *rb;
364 344
 
365 345
 	/* lock the first timer list of the FR group -- all other
366 346
 	   lists share the same lock*/
367 347
 	lock(hash_table->timers[RT_T1_TO_1].mutex);
368
-	remove_timer_unsafe( & p_cell->outbound_response.retr_timer );
348
+	remove_timer_unsafe( & p_cell->uas.response.retr_timer );
369 349
 	for( ijk=0 ; ijk<(p_cell)->nr_of_outgoings ; ijk++ )  {
370
-		if ( (rb = p_cell->outbound_request[ijk]) )
371
-			remove_timer_unsafe( & rb->retr_timer );
372
-		if ( (rb = p_cell->outbound_cancel[ijk]) )
373
-			remove_timer_unsafe( & rb->retr_timer );
350
+		remove_timer_unsafe( & p_cell->uac[ijk].request.retr_timer );
374 351
 	}
375 352
 	unlock(hash_table->timers[RT_T1_TO_1].mutex);
376 353
 
377 354
 	lock(hash_table->timers[FR_TIMER_LIST].mutex);
378
-	remove_timer_unsafe( & p_cell->outbound_response.fr_timer );
355
+	remove_timer_unsafe( & p_cell->uas.response.fr_timer );
379 356
 	for( ijk=0 ; ijk<(p_cell)->nr_of_outgoings ; ijk++ )  {
380
-		if ( (rb = p_cell->outbound_request[ijk]) )
381
-			remove_timer_unsafe( & rb->fr_timer );
382
-		if ( (rb = p_cell->outbound_cancel[ijk]) )
383
-			remove_timer_unsafe( & rb->fr_timer );
357
+		remove_timer_unsafe( & p_cell->uac[ijk].request.fr_timer );
384 358
 	}
385 359
 	unlock(hash_table->timers[FR_TIMER_LIST].mutex);
386 360
 	DBG("DEBUG:stop_RETR_and_FR_timers : timers stopped\n");
... ...
@@ -16,170 +16,161 @@
16 16
  *      -1 - error during forward
17 17
  */
18 18
 int t_forward_nonack( struct sip_msg* p_msg , unsigned int dest_ip_param ,
19
-	unsigned int dest_port_param )
19
+											unsigned int dest_port_param )
20 20
 {
21
-	unsigned int        dest_ip = dest_ip_param;
22
-	unsigned int        dest_port = dest_port_param;
23
-	int                  branch;
24
-	unsigned int         len;
25
-	char                *buf, *shbuf;
26
-	struct retrans_buff *rb = 0;
27
-	struct cell         *T_source = T;
28
-
29
-
30
-	buf=NULL;
31
-	shbuf = NULL;
32
-	branch = 0;	/* we don't do any forking right now */
21
+	int          branch,i;
22
+	unsigned int len;
23
+	char         *buf, *shbuf;
24
+	struct cell  *T_source = T;
25
+	struct lump  *a,*b,*b1,*c;
26
+
27
+
28
+	buf    = 0;
29
+	shbuf  = 0;
30
+	t_forks[0][0] = dest_ip_param;
31
+	t_forks[0][1] = dest_port_param;
32
+
33
+	/* are we forwarding for the first time? */
34
+	if ( T->uac[0].request.buffer )
35
+	{	/* rewriting a request should really not happen -- retransmission
36
+		   does not rewrite, whereas a new request should be written
37
+		   somewhere else */
38
+		LOG( L_CRIT, "ERROR: t_forward_nonack: attempt to rewrite"
39
+			" request structures\n");
40
+		return 0;
41
+	}
33 42
 
34
-	if ( T->outbound_request[branch]==NULL )
43
+	DBG("DEBUG: t_forward_nonack: first time forwarding\n");
44
+	/* special case : CANCEL */
45
+	if ( p_msg->REQ_METHOD==METHOD_CANCEL  )
35 46
 	{
36
-		DBG("DEBUG: t_forward_nonack: first time forwarding\n");
37
-		/* special case : CANCEL */
38
-		if ( p_msg->REQ_METHOD==METHOD_CANCEL  )
47
+		DBG("DEBUG: t_forward_nonack: it's CANCEL\n");
48
+		/* find original cancelled transaction; if found, use its
49
+		   next-hops; otherwise use those passed by script */
50
+		if ( T->T_canceled==T_UNDEFINED )
51
+			T->T_canceled = t_lookupOriginalT( hash_table , p_msg );
52
+		/* if found */
53
+		if ( T->T_canceled!=T_NULL )
39 54
 		{
40
-			DBG("DEBUG: t_forward_nonack: it's CANCEL\n");
41
-			/* find original cancelled transaction; if found, use its
42
-			   next-hops; otherwise use those passed by script */
43
-			if ( T->T_canceled==T_UNDEFINED )
44
-				T->T_canceled = t_lookupOriginalT( hash_table , p_msg );
45
-			/* if found */
46