... | ... |
@@ -33,14 +33,14 @@ NAME=ser |
33 | 33 |
# PKG_MALLOC uses a faster malloc (exclusive w/ USE_SHM_MEM) |
34 | 34 |
# USE_SHM_MEM all pkg_malloc => sh_malloc (most mallocs use a common sh. mem. |
35 | 35 |
# segment); don't define PKG_MALLOC! |
36 |
-DEFS=-DNOCR -DMACROEATER -DDNS_IP_HACK -DSHM_MEM -DUSE_SHM_MEM #-DNO_DEBUG |
|
36 |
+DEFS=-DTHREAD -DNOCR -DMACROEATER -DDNS_IP_HACK -DSHM_MEM -DUSE_SHM_MEM #-DNO_DEBUG |
|
37 | 37 |
#-DPKG_MALLOC |
38 | 38 |
#-DNO_DEBUG#-DSTATS -DNO_DEBUG |
39 | 39 |
#-DNO_LOG |
40 | 40 |
|
41 | 41 |
PROFILE= # -pg #set this if you want profiling |
42 |
-#mode = debug |
|
43 |
-mode = release |
|
42 |
+mode = debug |
|
43 |
+#mode = release |
|
44 | 44 |
|
45 | 45 |
# platform dependent settings |
46 | 46 |
|
... | ... |
@@ -41,8 +41,8 @@ |
41 | 41 |
int forward_request( struct sip_msg* msg, struct proxy_l * p) |
42 | 42 |
{ |
43 | 43 |
unsigned int len; |
44 |
- char* buf; |
|
45 |
- struct sockaddr_in* to; |
|
44 |
+ char* buf=NULL; |
|
45 |
+ struct sockaddr_in* to=NULL; |
|
46 | 46 |
|
47 | 47 |
|
48 | 48 |
buf = build_req_buf_from_sip_req( msg, &len); |
... | ... |
@@ -53,12 +53,12 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p) |
53 | 53 |
|
54 | 54 |
to=(struct sockaddr_in*)malloc(sizeof(struct sockaddr)); |
55 | 55 |
if (to==0){ |
56 |
- LOG(L_ERR, "ERROR: forward_reply: out of memory\n"); |
|
56 |
+ LOG(L_ERR, "ERROR: forward_request: out of memory\n"); |
|
57 | 57 |
goto error; |
58 | 58 |
} |
59 | 59 |
|
60 | 60 |
/* send it! */ |
61 |
- DBG("Sending:\n%s.\n", buf); |
|
61 |
+ DBG("Sending:", buf); |
|
62 | 62 |
DBG("orig. len=%d, new_len=%d\n", msg->len, len ); |
63 | 63 |
|
64 | 64 |
to->sin_family = AF_INET; |
... | ... |
@@ -99,14 +99,39 @@ error: |
99 | 99 |
} |
100 | 100 |
|
101 | 101 |
|
102 |
+int update_sock_struct_from_via( struct sockaddr_in* to, struct via_body* via ) |
|
103 |
+{ |
|
104 |
+ int err; |
|
105 |
+ |
|
106 |
+ to->sin_family = AF_INET; |
|
107 |
+ to->sin_port = (via->port)?htons(via->port): htons(SIP_PORT); |
|
108 |
+ |
|
109 |
+#ifdef DNS_IP_HACK |
|
110 |
+ to->sin_addr.s_addr=str2ip(via->host.s, via->host.len, &err); |
|
111 |
+ if (err) |
|
112 |
+#endif |
|
113 |
+ { |
|
114 |
+ struct hostent* he; |
|
115 |
+ /* fork? gethostbyname will probably block... */ |
|
116 |
+ he=gethostbyname(via->host.s); |
|
117 |
+ if (he==0){ |
|
118 |
+ LOG(L_NOTICE, "ERROR:forward_reply:gethostbyname(%s) failure\n", |
|
119 |
+ via->host.s); |
|
120 |
+ return -1; |
|
121 |
+ } |
|
122 |
+ to->sin_addr.s_addr=*((long*)he->h_addr_list[0]); |
|
123 |
+ } |
|
124 |
+ return 1; |
|
125 |
+} |
|
126 |
+ |
|
102 | 127 |
|
103 | 128 |
/* removes first via & sends msg to the second */ |
104 | 129 |
int forward_reply(struct sip_msg* msg) |
105 | 130 |
{ |
106 | 131 |
int r; |
107 |
- char* new_buf; |
|
108 |
- struct hostent* he; |
|
109 |
- struct sockaddr_in* to; |
|
132 |
+ char* new_buf=NULL; |
|
133 |
+ struct hostent* he=NULL; |
|
134 |
+ struct sockaddr_in* to=NULL; |
|
110 | 135 |
unsigned int new_len; |
111 | 136 |
struct sr_module *mod; |
112 | 137 |
#ifdef DNS_IP_HACK |
... | ... |
@@ -151,34 +176,16 @@ int forward_reply(struct sip_msg* msg) |
151 | 176 |
} |
152 | 177 |
|
153 | 178 |
/* send it! */ |
179 |
+ /* moved to udp_send; -jiri |
|
180 |
+ |
|
154 | 181 |
DBG("Sending: to %s:%d, \n%s.\n", |
155 | 182 |
msg->via2->host.s, |
156 | 183 |
(unsigned short)msg->via2->port, |
157 | 184 |
new_buf); |
185 |
+ */ |
|
158 | 186 |
|
159 |
-#ifdef DNS_IP_HACK |
|
160 |
- to->sin_addr.s_addr=str2ip(msg->via2->host.s, msg->via2->host.len, &err); |
|
161 |
- if (err==0){ |
|
162 |
- to->sin_family = AF_INET; |
|
163 |
- to->sin_port = (msg->via2->port)?htons(msg->via2->port): |
|
164 |
- htons(SIP_PORT); |
|
165 |
- }else{ |
|
166 |
-#endif |
|
167 |
- /* fork? gethostbyname will probably block... */ |
|
168 |
- he=gethostbyname(msg->via2->host.s); |
|
169 |
- if (he==0){ |
|
170 |
- LOG(L_NOTICE, "ERROR:forward_reply:gethostbyname(%s) failure\n", |
|
171 |
- msg->via2->host.s); |
|
172 |
- goto error; |
|
173 |
- } |
|
174 |
- to->sin_family = AF_INET; |
|
175 |
- to->sin_port = (msg->via2->port)?htons(msg->via2->port): |
|
176 |
- htons(SIP_PORT); |
|
177 |
- to->sin_addr.s_addr=*((long*)he->h_addr_list[0]); |
|
187 |
+ if (update_sock_struct_from_via( to, msg->via2 )==-1) goto error; |
|
178 | 188 |
|
179 |
-#ifdef DNS_IP_HACK |
|
180 |
- } |
|
181 |
-#endif |
|
182 | 189 |
if (udp_send(new_buf,new_len, (struct sockaddr*) to, |
183 | 190 |
sizeof(struct sockaddr_in))==-1) |
184 | 191 |
{ |
... | ... |
@@ -8,27 +8,27 @@ void free_cell( struct cell* dead_cell ) |
8 | 8 |
{ |
9 | 9 |
int i; |
10 | 10 |
|
11 |
- /* inbound_request */ |
|
11 |
+ /* UA Server */ |
|
12 | 12 |
if ( dead_cell->inbound_request ) |
13 | 13 |
sip_msg_free( dead_cell->inbound_request ); |
14 |
- /* inbound_response */ |
|
15 |
- if ( dead_cell->inbound_response ) |
|
14 |
+ if ( dead_cell->outbound_response ) |
|
16 | 15 |
{ |
17 |
- sh_free( dead_cell->inbound_response->buffer ); |
|
18 |
- sh_free( dead_cell->inbound_response ); |
|
16 |
+ sh_free( dead_cell->outbound_response->retr_buffer ); |
|
17 |
+ sh_free( dead_cell->outbound_response ); |
|
19 | 18 |
} |
20 | 19 |
|
20 |
+ /* UA Clients */ |
|
21 | 21 |
for ( i =0 ; i<dead_cell->nr_of_outgoings; i++ ) |
22 | 22 |
{ |
23 | 23 |
/* outbound requests*/ |
24 | 24 |
if ( dead_cell->outbound_request[i] ) |
25 | 25 |
{ |
26 |
- sh_free( dead_cell->outbound_request[i]->buffer ); |
|
26 |
+ sh_free( dead_cell->outbound_request[i]->retr_buffer ); |
|
27 | 27 |
sh_free( dead_cell->outbound_request[i] ); |
28 | 28 |
} |
29 | 29 |
/* outbound requests*/ |
30 |
- if ( dead_cell -> outbound_response[i] ) |
|
31 |
- sip_msg_free( dead_cell->outbound_response[i] ); |
|
30 |
+ if ( dead_cell -> inbound_response[i] ) |
|
31 |
+ sip_msg_free( dead_cell->inbound_response[i] ); |
|
32 | 32 |
} |
33 | 33 |
/* mutex */ |
34 | 34 |
release_cell_lock( dead_cell ); |
... | ... |
@@ -105,10 +105,10 @@ struct s_table* init_hash_table() |
105 | 105 |
for( i=0 ; i<NR_OF_TIMER_LISTS ; i++ ) |
106 | 106 |
init_timerlist_lock( hash_table, i ); |
107 | 107 |
|
108 |
-//#ifdef THREAD |
|
108 |
+#ifdef THREAD |
|
109 | 109 |
/* starts the timer thread/ process */ |
110 | 110 |
pthread_create( thread, NULL, timer_routine, hash_table ); |
111 |
-//#endif |
|
111 |
+#endif |
|
112 | 112 |
|
113 | 113 |
return hash_table; |
114 | 114 |
|
... | ... |
@@ -45,10 +45,12 @@ typedef struct timer |
45 | 45 |
|
46 | 46 |
typedef struct retrans_buff |
47 | 47 |
{ |
48 |
- char *buffer; |
|
48 |
+ char *retr_buffer; |
|
49 | 49 |
int bufflen; |
50 |
+/* |
|
50 | 51 |
unsigned int dest_ip; |
51 | 52 |
unsigned int dest_port; |
53 |
+*/ |
|
52 | 54 |
|
53 | 55 |
struct sockaddr_in to; |
54 | 56 |
/* changed in favour of Solaris to size_t |
... | ... |
@@ -88,15 +90,16 @@ typedef struct cell |
88 | 90 |
struct timer_link dele_tl; |
89 | 91 |
|
90 | 92 |
/* usefull data */ |
91 |
- /* incoming request and its response*/ |
|
93 |
+ /* UA Server */ |
|
92 | 94 |
struct sip_msg *inbound_request; |
93 |
- struct retrans_buff *inbound_response; |
|
95 |
+ struct retrans_buff *outbound_response; |
|
94 | 96 |
unsigned int status; |
95 | 97 |
str* tag; |
96 | 98 |
/* array of outgoing requests and its responses */ |
97 | 99 |
int nr_of_outgoings; |
100 |
+ /* UA Clients */ |
|
98 | 101 |
struct retrans_buff *outbound_request[ MAX_FORK ]; |
99 |
- struct sip_msg *outbound_response[ MAX_FORK ]; |
|
102 |
+ struct sip_msg *inbound_response[ MAX_FORK ]; |
|
100 | 103 |
}cell_type; |
101 | 104 |
|
102 | 105 |
|
... | ... |
@@ -6,7 +6,7 @@ |
6 | 6 |
|
7 | 7 |
struct sip_msg* sip_msg_cloner( struct sip_msg *org_msg ) |
8 | 8 |
{ |
9 |
- struct sip_msg *new_msg; |
|
9 |
+ struct sip_msg *new_msg=NULL; |
|
10 | 10 |
struct hdr_field *header, *last_hdr, *new_hdr; |
11 | 11 |
|
12 | 12 |
/* clones the sip_msg structure */ |
... | ... |
@@ -127,6 +127,13 @@ struct sip_msg* sip_msg_cloner( struct sip_msg *org_msg ) |
127 | 127 |
/* repl_add_rm ( struct lump* ) -> have to be changed!!!!!!! */ |
128 | 128 |
new_msg->repl_add_rm = 0; |
129 | 129 |
|
130 |
+ return new_msg; |
|
131 |
+ |
|
132 |
+error: |
|
133 |
+ sip_msg_free( new_msg ); |
|
134 |
+ sh_free( new_msg ); |
|
135 |
+ return NULL; |
|
136 |
+ |
|
130 | 137 |
} |
131 | 138 |
|
132 | 139 |
|
... | ... |
@@ -310,12 +317,14 @@ void free_hdr_field_lst(struct hdr_field* hf) |
310 | 317 |
/*only the content*/ |
311 | 318 |
void sip_msg_free(struct sip_msg* msg) |
312 | 319 |
{ |
320 |
+ if (!msg) return; |
|
321 |
+ |
|
313 | 322 |
if (msg->new_uri.s) |
314 | 323 |
{ |
315 | 324 |
sh_free(msg->new_uri.s); |
316 | 325 |
msg->new_uri.len=0; |
317 | 326 |
} |
318 |
- DBG("DEBUG: sip_msg_free : headers\n"); |
|
327 |
+ LOG(L_ERR, "ERROR: sip_msg_free : headers and via1/via2 freeing still missing\n"); |
|
319 | 328 |
//if (msg->headers) |
320 | 329 |
// free_hdr_field_lst(msg->headers); |
321 | 330 |
DBG("DEBUG: sip_msg_free : lump\n"); |
... | ... |
@@ -323,11 +332,7 @@ void sip_msg_free(struct sip_msg* msg) |
323 | 332 |
free_lump_list(msg->add_rm); |
324 | 333 |
if (msg->repl_add_rm) |
325 | 334 |
free_lump_list(msg->repl_add_rm); |
326 |
- sh_free( msg->orig ); |
|
327 |
- sh_free( msg->buf ); |
|
335 |
+ if (msg->orig) sh_free( msg->orig ); |
|
336 |
+ if (msg->buf) sh_free( msg->buf ); |
|
337 |
+ |
|
328 | 338 |
} |
329 |
- |
|
330 |
- |
|
331 |
- |
|
332 |
- |
|
333 |
- |
... | ... |
@@ -23,7 +23,7 @@ int tm_startup() |
23 | 23 |
|
24 | 24 |
/*first msg id*/ |
25 | 25 |
global_msg_id = 0; |
26 |
- T = (struct cell*)-1; |
|
26 |
+ T = T_UNDEFINED; |
|
27 | 27 |
|
28 | 28 |
return 0; |
29 | 29 |
} |
... | ... |
@@ -54,12 +54,12 @@ int t_add_transaction( struct sip_msg* p_msg, char* foo, char* bar ) |
54 | 54 |
/* it's about the same transaction or not?*/ |
55 | 55 |
if ( global_msg_id != p_msg->id ) |
56 | 56 |
{ |
57 |
- T = (struct cell*)-1; |
|
57 |
+ T = T_UNDEFINED; |
|
58 | 58 |
global_msg_id = p_msg->id; |
59 | 59 |
} |
60 | 60 |
|
61 | 61 |
/* if the transaction is not found yet we are tring to look for it*/ |
62 |
- if ( (int)T==-1 ) |
|
62 |
+ if ( T==T_UNDEFINED ) |
|
63 | 63 |
/* if the lookup's result is not 0 means that it's a retransmission */ |
64 | 64 |
if ( t_lookup_request( p_msg, foo, bar ) ) |
65 | 65 |
{ |
... | ... |
@@ -95,12 +95,12 @@ int t_lookup_request( struct sip_msg* p_msg, char* foo, char* bar ) |
95 | 95 |
/* it's about the same transaction or not?*/ |
96 | 96 |
if ( global_msg_id != p_msg->id ) |
97 | 97 |
{ |
98 |
- T = (struct cell*)-1; |
|
98 |
+ T = T_UNDEFINED; |
|
99 | 99 |
global_msg_id = p_msg->id; |
100 | 100 |
} |
101 | 101 |
|
102 | 102 |
/* if T is previous found -> return found */ |
103 |
- if ( (int)T !=-1 && T ) { |
|
103 |
+ if ( T!=T_UNDEFINED && T ) { |
|
104 | 104 |
DBG("DEBUG: t_lookup_request: T already exists\n"); |
105 | 105 |
return 1; |
106 | 106 |
} |
... | ... |
@@ -115,7 +115,7 @@ int t_lookup_request( struct sip_msg* p_msg, char* foo, char* bar ) |
115 | 115 |
/* parse all*/ |
116 | 116 |
if (check_transaction_quadruple(p_msg)==0) { |
117 | 117 |
LOG(L_ERR, "ERROR: TM module: t_lookup_request: too few headers\n"); |
118 |
- T=0; |
|
118 |
+ T=T_NULL; |
|
119 | 119 |
return -1; |
120 | 120 |
} |
121 | 121 |
/* start searching into the table */ |
... | ... |
@@ -205,13 +205,13 @@ int t_forward( struct sip_msg* p_msg , unsigned int dest_ip_param , unsigned int |
205 | 205 |
/* it's about the same transaction or not? */ |
206 | 206 |
if ( global_msg_id != p_msg->id ) |
207 | 207 |
{ |
208 |
- T = (struct cell*)-1; |
|
208 |
+ T = T_UNDEFINED; |
|
209 | 209 |
global_msg_id = p_msg->id; |
210 | 210 |
} |
211 | 211 |
|
212 | 212 |
DBG("t_forward: 1. T=%x\n", T); |
213 | 213 |
/* if T hasn't been previous searched -> search for it */ |
214 |
- if ( (int)T ==-1 ) |
|
214 |
+ if ( T == T_UNDEFINED ) |
|
215 | 215 |
t_lookup_request( p_msg, 0 , 0 ); |
216 | 216 |
|
217 | 217 |
DBG("t_forward: 2. T=%x\n", T); |
... | ... |
@@ -246,8 +246,8 @@ int t_forward( struct sip_msg* p_msg , unsigned int dest_ip_param , unsigned int |
246 | 246 |
if ( (T2->status/100)==1 ) |
247 | 247 |
{ |
248 | 248 |
DBG("DEBUG: t_forward: it's CANCEL and I will send to the same place where INVITE went\n"); |
249 |
- dest_ip = T2->outbound_request[branch]->dest_ip; |
|
250 |
- dest_port = T2->outbound_request[branch]->dest_port; |
|
249 |
+ dest_ip = T2->outbound_request[branch]->to.sin_addr.s_addr; |
|
250 |
+ dest_port = T2->outbound_request[branch]->to.sin_port; |
|
251 | 251 |
} |
252 | 252 |
else |
253 | 253 |
{ |
... | ... |
@@ -261,6 +261,10 @@ int t_forward( struct sip_msg* p_msg , unsigned int dest_ip_param , unsigned int |
261 | 261 |
/* allocates a new retrans_buff for the outbound request */ |
262 | 262 |
DBG("DEBUG: t_forward: building outbound request\n"); |
263 | 263 |
T->outbound_request[branch] = (struct retrans_buff*)sh_malloc( sizeof(struct retrans_buff) ); |
264 |
+ if (!T->outbound_request[branch]) { |
|
265 |
+ LOG(L_ERR, "ERROR: t_forward: out of shmem\n"); |
|
266 |
+ return -1; |
|
267 |
+ } |
|
264 | 268 |
memset( T->outbound_request[branch] , 0 , sizeof (struct retrans_buff) ); |
265 | 269 |
T->outbound_request[branch]->tl[RETRASMISSIONS_LIST].payload = T->outbound_request[branch]; |
266 | 270 |
T->outbound_request[branch]->tl[FR_TIMER_LIST].payload = T->outbound_request[branch]; |
... | ... |
@@ -269,17 +273,16 @@ int t_forward( struct sip_msg* p_msg , unsigned int dest_ip_param , unsigned int |
269 | 273 |
T->nr_of_outgoings = 1; |
270 | 274 |
|
271 | 275 |
if (add_branch_label( T, p_msg , branch )==-1) return -1; |
272 |
- DBG("DEBUG: XXX: branch_size after call to add_branch_label: %d\n", p_msg->add_to_branch_len ); |
|
273 | 276 |
buf = build_req_buf_from_sip_req ( p_msg, &len); |
274 | 277 |
if (!buf) |
275 | 278 |
return -1; |
276 | 279 |
T->outbound_request[branch]->bufflen = len ; |
277 |
- if ( !(T->outbound_request[branch]->buffer = (char*)sh_malloc( len ))) { |
|
280 |
+ if ( !(T->outbound_request[branch]->retr_buffer = (char*)sh_malloc( len ))) { |
|
278 | 281 |
LOG(L_ERR, "ERROR: t_forward: shmem allocation failed\n"); |
279 | 282 |
free( buf ); |
280 | 283 |
return -1; |
281 | 284 |
} |
282 |
- memcpy( T->outbound_request[branch]->buffer , buf , len ); |
|
285 |
+ memcpy( T->outbound_request[branch]->retr_buffer , buf , len ); |
|
283 | 286 |
free( buf ) ; |
284 | 287 |
|
285 | 288 |
DBG("DEBUG: t_forward: starting timers (retrans and FR)\n"); |
... | ... |
@@ -292,15 +295,13 @@ int t_forward( struct sip_msg* p_msg , unsigned int dest_ip_param , unsigned int |
292 | 295 |
insert_into_timer_list( hash_table , &(T->outbound_request[branch]->tl[RETRASMISSIONS_LIST]), RETRASMISSIONS_LIST , RETR_T1 ); |
293 | 296 |
}/* end for the first time */ |
294 | 297 |
|
295 |
- DBG("DEBUG: t_forward: sending outbund request from buffer (%d bytes):\n%*s\n", |
|
296 |
- T->outbound_request[branch]->bufflen, T->outbound_request[branch]->bufflen, |
|
297 |
- T->outbound_request[branch]->buffer); |
|
298 | 298 |
/* send the request */ |
299 |
- T->outbound_request[branch]->dest_ip = dest_ip; |
|
300 |
- T->outbound_request[branch]->dest_port = dest_port; |
|
299 |
+ /* known to be in network order */ |
|
301 | 300 |
T->outbound_request[branch]->to.sin_port = dest_port; |
302 | 301 |
T->outbound_request[branch]->to.sin_addr.s_addr = dest_ip; |
303 |
- udp_send( T->outbound_request[branch]->buffer , T->outbound_request[branch]->bufflen , |
|
302 |
+ T->outbound_request[branch]->to.sin_family = AF_INET; |
|
303 |
+ |
|
304 |
+ udp_send( T->outbound_request[branch]->retr_buffer , T->outbound_request[branch]->bufflen , |
|
304 | 305 |
(struct sockaddr*)&(T->outbound_request[branch]->to) , sizeof(struct sockaddr_in) ); |
305 | 306 |
return 1; |
306 | 307 |
} |
... | ... |
@@ -323,13 +324,13 @@ int t_forward_uri( struct sip_msg* p_msg, char* foo, char* bar ) |
323 | 324 |
/* it's about the same transaction or not? */ |
324 | 325 |
if ( global_msg_id != p_msg->id ) |
325 | 326 |
{ |
326 |
- T = (struct cell*)-1; |
|
327 |
+ T = T_UNDEFINED; |
|
327 | 328 |
global_msg_id = p_msg->id; |
328 | 329 |
} |
329 | 330 |
|
330 | 331 |
DBG("DEBUG: t_forward_uri: 1. T=%x\n", T); |
331 | 332 |
/* if T hasn't been previous searched -> search for it */ |
332 |
- if ( (int)T ==-1 ) |
|
333 |
+ if ( T==T_UNDEFINED ) |
|
333 | 334 |
t_lookup_request( p_msg, 0 , 0 ); |
334 | 335 |
|
335 | 336 |
DBG("DEBUG: t_forward_uri: 2. T=%x\n", T); |
... | ... |
@@ -379,7 +380,7 @@ int t_on_reply_received( struct sip_msg *p_msg ) |
379 | 380 |
t_reply_matching( hash_table , p_msg , &T , &branch ); |
380 | 381 |
|
381 | 382 |
/* if no T found ->tell the core router to forward statelessly */ |
382 |
- if ( !T ) |
|
383 |
+ if ( T<=0 ) |
|
383 | 384 |
return 1; |
384 | 385 |
|
385 | 386 |
/* stop retransmission */ |
... | ... |
@@ -462,7 +463,7 @@ int t_put_on_wait( struct sip_msg *p_msg ) |
462 | 463 |
|
463 | 464 |
t_check( hash_table , p_msg ); |
464 | 465 |
/* do we have something to release? */ |
465 |
- if (T==0) |
|
466 |
+ if (T==T_NULL) |
|
466 | 467 |
return -1; |
467 | 468 |
|
468 | 469 |
if ( is_in_timer_list( (&(T->wait_tl)) , WT_TIMER_LIST) ) |
... | ... |
@@ -474,16 +475,16 @@ int t_put_on_wait( struct sip_msg *p_msg ) |
474 | 475 |
|
475 | 476 |
/**/ |
476 | 477 |
for( i=0 ; i<T->nr_of_outgoings ; i++ ) |
477 |
- if ( T->outbound_response[i] && T->outbound_response[i]->first_line.u.reply.statusclass==1) |
|
478 |
+ if ( T->inbound_response[i] && T->inbound_response[i]->first_line.u.reply.statusclass==1) |
|
478 | 479 |
t_cancel_branch(i); |
479 | 480 |
|
480 | 481 |
/* make double-sure we have finished everything */ |
481 | 482 |
/* remove from retranssmision and final response list */ |
482 | 483 |
DBG("DEBUG: t_put_on_wait: remove inboud stuff from lists\n"); |
483 |
- if ( T->inbound_response ) |
|
484 |
+ if ( T->outbound_response ) |
|
484 | 485 |
{ |
485 |
- remove_from_timer_list( hash_table , &(T->inbound_response->tl[RETRASMISSIONS_LIST]) , RETRASMISSIONS_LIST ); |
|
486 |
- remove_from_timer_list( hash_table , &(T->inbound_response->tl[FR_TIMER_LIST]) , FR_TIMER_LIST ); |
|
486 |
+ remove_from_timer_list( hash_table , &(T->outbound_response->tl[RETRASMISSIONS_LIST]) , RETRASMISSIONS_LIST ); |
|
487 |
+ remove_from_timer_list( hash_table , &(T->outbound_response->tl[FR_TIMER_LIST]) , FR_TIMER_LIST ); |
|
487 | 488 |
} |
488 | 489 |
for( i=0 ; i<T->nr_of_outgoings ; i++ ) |
489 | 490 |
{ |
... | ... |
@@ -500,6 +501,9 @@ int t_put_on_wait( struct sip_msg *p_msg ) |
500 | 501 |
|
501 | 502 |
|
502 | 503 |
/* Retransmits the last sent inbound reply. |
504 |
+ |
|
505 |
+ * input: p_msg==request for which I want to retransmit an associated |
|
506 |
+ reply |
|
503 | 507 |
* Returns -1 -error |
504 | 508 |
* 1 - OK |
505 | 509 |
*/ |
... | ... |
@@ -508,12 +512,14 @@ int t_retransmit_reply( struct sip_msg* p_msg, char* foo, char* bar ) |
508 | 512 |
t_check( hash_table, p_msg ); |
509 | 513 |
|
510 | 514 |
/* if no transaction exists or no reply to be resend -> out */ |
511 |
- if ( T && T->inbound_response ) |
|
515 |
+ if ( T && T->outbound_response ) |
|
512 | 516 |
{ |
513 |
- udp_send( T->inbound_response->buffer , T->inbound_response->bufflen , (struct sockaddr*)&(T->inbound_response->to) , sizeof(struct sockaddr_in) ); |
|
517 |
+ udp_send( T->outbound_response->retr_buffer , T->outbound_response->bufflen , |
|
518 |
+ (struct sockaddr*)&(T->outbound_response->to) , sizeof(struct sockaddr_in) ); |
|
514 | 519 |
return 1; |
515 | 520 |
} |
516 | 521 |
|
522 |
+ /* no transaction found */ |
|
517 | 523 |
return -1; |
518 | 524 |
} |
519 | 525 |
|
... | ... |
@@ -525,85 +531,88 @@ int t_retransmit_reply( struct sip_msg* p_msg, char* foo, char* bar ) |
525 | 531 |
*/ |
526 | 532 |
int t_send_reply( struct sip_msg* p_msg , unsigned int code , char * text ) |
527 | 533 |
{ |
528 |
- t_check( hash_table, p_msg ); |
|
534 |
+ unsigned int len; |
|
535 |
+ char * buf = NULL; |
|
536 |
+ struct hostent *nhost; |
|
537 |
+ unsigned int ip, port; |
|
538 |
+ char foo; |
|
539 |
+ int err; |
|
540 |
+ struct retrans_buff* rb = NULL; |
|
541 |
+ |
|
542 |
+ DBG("DEBUG: t_send_reply: entered\n"); |
|
543 |
+ t_check( hash_table, p_msg ); |
|
544 |
+ |
|
545 |
+ if (!T) { |
|
546 |
+ LOG(L_ERR, "ERROR: cannot send a t_reply to a message for which no T-state has been established\n"); |
|
547 |
+ return -1; |
|
548 |
+ } ; |
|
529 | 549 |
|
530 |
- if (T) |
|
531 |
- { |
|
532 |
- unsigned int len; |
|
533 |
- char * buf; |
|
550 |
+ buf = build_res_buf_from_sip_req( code , text , T->inbound_request , &len ); |
|
551 |
+ DBG("DEBUG: t_send_reply: after build\n"); |
|
552 |
+ if (!buf) |
|
553 |
+ { |
|
554 |
+ DBG("DEBUG: t_send_reply: response building failed\n"); |
|
555 |
+ goto error; |
|
556 |
+ } |
|
557 |
+ |
|
558 |
+ if ( T->outbound_response) { |
|
559 |
+ if ( T->outbound_response->retr_buffer ) |
|
560 |
+ { |
|
561 |
+ sh_free( T->outbound_response->retr_buffer ); |
|
562 |
+ T->outbound_response->retr_buffer = NULL; |
|
563 |
+ } |
|
564 |
+ } else { |
|
565 |
+ rb = (struct retrans_buff*)sh_malloc( sizeof(struct retrans_buff) ); |
|
566 |
+ if (!rb) { |
|
567 |
+ LOG(L_ERR, "ERROR: t_send_reply: cannot allocate shmem\n"); |
|
568 |
+ goto error; |
|
569 |
+ } |
|
570 |
+ T->outbound_response = rb; |
|
571 |
+ memset( T->outbound_response , 0 , sizeof (struct retrans_buff) ); |
|
572 |
+ } |
|
534 | 573 |
|
535 |
- buf = build_res_buf_from_sip_req( code , text , T->inbound_request , &len ); |
|
536 |
- DBG("DEBUG: t_send_reply: after build\n"); |
|
537 |
- if (!buf) |
|
538 |
- { |
|
539 |
- DBG("DEBUG: t_send_reply: response building failed\n"); |
|
540 |
- return -1; |
|
541 |
- } |
|
542 | 574 |
|
543 |
- if ( T->inbound_response ) |
|
544 |
- { |
|
545 |
- sh_free( T->inbound_response->buffer ); |
|
546 |
- } |
|
547 |
- else |
|
548 |
- { |
|
549 |
- struct hostent *nhost; |
|
550 |
- unsigned int ip, port; |
|
551 |
- char foo; |
|
552 |
- |
|
553 |
- /*some dirty trick to get the port from via */ |
|
554 |
- foo = *((p_msg->via1->host.s)+(p_msg->via1->host.len)); |
|
555 |
- *((p_msg->via1->host.s)+(p_msg->via1->host.len)) = 0; |
|
556 |
- nhost = gethostbyname( p_msg->via1->host.s ); |
|
557 |
- *((p_msg->via1->host.s)+(p_msg->via1->host.len)) = foo; |
|
558 |
- if ( !nhost ) |
|
559 |
- { |
|
560 |
- DBG("ERROR: t_send_reply: resolving host failed\n"); |
|
561 |
- free(buf); |
|
562 |
- return -1; |
|
563 |
- } |
|
564 |
- memcpy( &ip , nhost->h_addr_list[0] , sizeof(unsigned int) ); |
|
565 |
- /* port */ |
|
566 |
- if ( !(port = p_msg->via1->port) ) |
|
567 |
- port = SIP_PORT; |
|
568 |
- |
|
569 |
- /* build a retrans_buff and fill it */ |
|
570 |
- T->inbound_response = (struct retrans_buff*)sh_malloc( sizeof(struct retrans_buff) ); |
|
571 |
- memset( T->inbound_response , 0 , sizeof (struct retrans_buff) ); |
|
572 |
- T->inbound_response->tl[RETRASMISSIONS_LIST].payload = T->inbound_response; |
|
573 |
- T->inbound_response->tl[FR_TIMER_LIST].payload = T->inbound_response; |
|
574 |
- T->inbound_response->to.sin_family = AF_INET; |
|
575 |
- T->inbound_response->my_T = T; |
|
576 |
- T->inbound_response->to.sin_addr.s_addr = ip; |
|
577 |
- T->inbound_response->to.sin_port = htons(port); |
|
578 |
- T->inbound_response->dest_ip = ip; |
|
579 |
- T->inbound_response->dest_port = htons(port); |
|
580 |
- } |
|
581 |
- T->status = code; |
|
582 |
- T->inbound_response->bufflen = len ; |
|
583 |
- T->inbound_response->buffer = (char*)sh_malloc( len ); |
|
584 |
- memcpy( T->inbound_response->buffer , buf , len ); |
|
585 |
- free( buf ) ; |
|
575 |
+ /* initialize retransmission structure */ |
|
576 |
+ if (update_sock_struct_from_via( &(T->outbound_response->to), p_msg->via1 )==-1) { |
|
577 |
+ LOG(L_ERR, "ERROR: t_send_reply: cannot lookup reply dst: %s\n", |
|
578 |
+ p_msg->via1->host.s ); |
|
579 |
+ goto error; |
|
580 |
+ } |
|
581 |
+ |
|
582 |
+ T->outbound_response->tl[RETRASMISSIONS_LIST].payload = T->outbound_response; |
|
583 |
+ T->outbound_response->tl[FR_TIMER_LIST].payload = T->outbound_response; |
|
584 |
+ T->outbound_response->my_T = T; |
|
585 |
+ T->status = code; |
|
586 |
+ T->outbound_response->bufflen = len ; |
|
587 |
+ T->outbound_response->retr_buffer = (char*)sh_malloc( len ); |
|
588 |
+ if (!T->outbound_response->retr_buffer) { |
|
589 |
+ T->outbound_response->retr_buffer = NULL; |
|
590 |
+ LOG(L_ERR, "ERROR: t_send_reply: cannot allocate shmem buffer\n"); |
|
591 |
+ goto error; |
|
592 |
+ } |
|
593 |
+ memcpy( T->outbound_response->retr_buffer , buf , len ); |
|
594 |
+ free( buf ) ; |
|
586 | 595 |
|
587 | 596 |
/* make sure that if we send something final upstream, everything else will be cancelled */ |
588 |
- if ( code>=200 ) |
|
589 |
- if ( p_msg->first_line.u.request.method_value==METHOD_INVITE ) |
|
590 |
- { |
|
591 |
- T->inbound_response->timeout_ceiling = RETR_T2; |
|
592 |
- T->inbound_response->timeout_value = RETR_T1; |
|
593 |
- remove_from_timer_list( hash_table , &(T->inbound_response->tl[RETRASMISSIONS_LIST]) , RETRASMISSIONS_LIST ); |
|
594 |
- insert_into_timer_list( hash_table , &(T->inbound_response->tl[RETRASMISSIONS_LIST]) , RETRASMISSIONS_LIST , RETR_T1 ); |
|
595 |
- remove_from_timer_list( hash_table , &(T->inbound_response->tl[FR_TIMER_LIST]) , FR_TIMER_LIST ); |
|
596 |
- insert_into_timer_list( hash_table , &(T->inbound_response->tl[FR_TIMER_LIST]) , FR_TIMER_LIST , FR_TIME_OUT ); |
|
597 |
- } |
|
598 |
- else |
|
597 |
+ if ( code>=300 && p_msg->first_line.u.request.method_value==METHOD_INVITE ) |
|
599 | 598 |
{ |
600 |
- t_put_on_wait( p_msg ); |
|
599 |
+ T->outbound_response->timeout_ceiling = RETR_T2; |
|
600 |
+ T->outbound_response->timeout_value = RETR_T1; |
|
601 |
+ remove_from_timer_list( hash_table , &(T->outbound_response->tl[RETRASMISSIONS_LIST]) , RETRASMISSIONS_LIST ); |
|
602 |
+ insert_into_timer_list( hash_table , &(T->outbound_response->tl[RETRASMISSIONS_LIST]) , RETRASMISSIONS_LIST , RETR_T1 ); |
|
603 |
+ remove_from_timer_list( hash_table , &(T->outbound_response->tl[FR_TIMER_LIST]) , FR_TIMER_LIST ); |
|
604 |
+ insert_into_timer_list( hash_table , &(T->outbound_response->tl[FR_TIMER_LIST]) , FR_TIMER_LIST , FR_TIME_OUT ); |
|
601 | 605 |
} |
606 |
+ else if (code>=200) t_put_on_wait( p_msg ); |
|
602 | 607 |
|
603 |
- udp_send( T->inbound_response->buffer , T->inbound_response->bufflen , (struct sockaddr*)&(T->inbound_response->to) , sizeof(struct sockaddr_in) ); |
|
604 |
- } |
|
608 |
+ t_retransmit_reply( p_msg, 0 , 0); |
|
605 | 609 |
|
606 |
- return 1; |
|
610 |
+ return 1; |
|
611 |
+ |
|
612 |
+error: |
|
613 |
+ if (rb) { sh_free(rb); T->outbound_response = rb = NULL;} |
|
614 |
+ if ( buf ) free ( buf ); |
|
615 |
+ return -1; |
|
607 | 616 |
} |
608 | 617 |
|
609 | 618 |
|
... | ... |
@@ -712,6 +721,9 @@ int t_reply_matching( struct s_table *hash_table , struct sip_msg *p_msg , struc |
712 | 721 |
/* split the branch into pieces: loop_detection_check(ignored), |
713 | 722 |
hash_table_id, synonym_id, branch_id |
714 | 723 |
*/ |
724 |
+ if (! ( p_msg->via1 && p_msg->via1->branch && p_msg->via1->branch->value.s) ) |
|
725 |
+ goto nomatch; |
|
726 |
+ |
|
715 | 727 |
p=p_msg->via1->branch->value.s; |
716 | 728 |
scan_space=p_msg->via1->branch->value.len; |
717 | 729 |
|
... | ... |
@@ -803,11 +815,11 @@ nomatch: |
803 | 815 |
int t_store_incoming_reply( struct cell* Trans, unsigned int branch, struct sip_msg* p_msg ) |
804 | 816 |
{ |
805 | 817 |
/* if there is a previous reply, replace it */ |
806 |
- if ( Trans->outbound_response[branch] ) |
|
807 |
- free_sip_msg( Trans->outbound_response[branch] ) ; |
|
818 |
+ if ( Trans->inbound_response[branch] ) |
|
819 |
+ free_sip_msg( Trans->inbound_response[branch] ) ; |
|
808 | 820 |
/* force parsing all the needed headers*/ |
809 | 821 |
parse_headers(p_msg, HDR_VIA|HDR_TO|HDR_FROM|HDR_CALLID|HDR_CSEQ ); |
810 |
- Trans->outbound_response[branch] = sip_msg_cloner( p_msg ); |
|
822 |
+ Trans->inbound_response[branch] = sip_msg_cloner( p_msg ); |
|
811 | 823 |
} |
812 | 824 |
|
813 | 825 |
|
... | ... |
@@ -819,7 +831,7 @@ int t_store_incoming_reply( struct cell* Trans, unsigned int branch, struct sip_ |
819 | 831 |
int t_relay_reply( struct cell* Trans, unsigned int branch, struct sip_msg* p_msg ) |
820 | 832 |
{ |
821 | 833 |
t_store_incoming_reply( Trans , branch, p_msg ); |
822 |
- push_reply_from_uac_to_uas( p_msg , branch ); |
|
834 |
+ push_reply_from_uac_to_uas( Trans , branch ); |
|
823 | 835 |
} |
824 | 836 |
|
825 | 837 |
|
... | ... |
@@ -834,7 +846,7 @@ int t_check( struct s_table *hash_table , struct sip_msg* p_msg ) |
834 | 846 |
unsigned int branch; |
835 | 847 |
|
836 | 848 |
/* is T still up-to-date ? */ |
837 |
- if ( p_msg->id != global_msg_id || (int)T==-1 ) |
|
849 |
+ if ( p_msg->id != global_msg_id || T==T_UNDEFINED ) |
|
838 | 850 |
{ |
839 | 851 |
global_msg_id = p_msg->id; |
840 | 852 |
/* transaction lookup */ |
... | ... |
@@ -861,7 +873,7 @@ int t_all_final( struct cell *Trans ) |
861 | 873 |
unsigned int i; |
862 | 874 |
|
863 | 875 |
for( i=0 ; i<Trans->nr_of_outgoings ; i++ ) |
864 |
- if ( !Trans->outbound_response[i] || (Trans->outbound_response[i]) && Trans->outbound_response[i]->first_line.u.reply.statuscode<200 ) |
|
876 |
+ if ( !Trans->inbound_response[i] || (Trans->inbound_response[i]) && Trans->inbound_response[i]->first_line.u.reply.statuscode<200 ) |
|
865 | 877 |
return 0; |
866 | 878 |
|
867 | 879 |
return 1; |
... | ... |
@@ -880,14 +892,16 @@ int relay_lowest_reply_upstream( struct cell *Trans , struct sip_msg *p_msg ) |
880 | 892 |
int lowest_v = 999; |
881 | 893 |
|
882 | 894 |
for( ; i<T->nr_of_outgoings ; i++ ) |
883 |
- if ( T->outbound_response[i] && T->outbound_response[i]->first_line.u.reply.statuscode>=200 && T->outbound_response[i]->first_line.u.reply.statuscode<lowest_v ) |
|
895 |
+ if ( T->inbound_response[i] && |
|
896 |
+ T->inbound_response[i]->first_line.u.reply.statuscode>=200 && |
|
897 |
+ T->inbound_response[i]->first_line.u.reply.statuscode<lowest_v ) |
|
884 | 898 |
{ |
885 | 899 |
lowest_i =i; |
886 |
- lowest_v = T->outbound_response[i]->first_line.u.reply.statuscode; |
|
900 |
+ lowest_v = T->inbound_response[i]->first_line.u.reply.statuscode; |
|
887 | 901 |
} |
888 | 902 |
|
889 | 903 |
if ( lowest_i != -1 ) |
890 |
- push_reply_from_uac_to_uas( p_msg ,lowest_i ); |
|
904 |
+ push_reply_from_uac_to_uas( T ,lowest_i ); |
|
891 | 905 |
|
892 | 906 |
return lowest_i; |
893 | 907 |
} |
... | ... |
@@ -898,62 +912,65 @@ int relay_lowest_reply_upstream( struct cell *Trans , struct sip_msg *p_msg ) |
898 | 912 |
/* Push a previously stored reply from UA Client to UA Server |
899 | 913 |
* and send it out |
900 | 914 |
*/ |
901 |
-int push_reply_from_uac_to_uas( struct sip_msg *p_msg , unsigned int branch ) |
|
915 |
+int push_reply_from_uac_to_uas( struct cell* trans , unsigned int branch ) |
|
902 | 916 |
{ |
903 | 917 |
char *buf; |
904 | 918 |
unsigned int len; |
905 | 919 |
|
906 | 920 |
/* if there is a reply, release the buffer (everything else stays same) */ |
907 |
- if ( T->inbound_response ) |
|
921 |
+ if ( trans->outbound_response ) |
|
908 | 922 |
{ |
909 |
- sh_free( T->inbound_response->buffer ); |
|
910 |
- remove_from_timer_list( hash_table , &(T->inbound_response->tl[RETRASMISSIONS_LIST]) , RETRASMISSIONS_LIST ); |
|
923 |
+ sh_free( trans->outbound_response->retr_buffer ); |
|
924 |
+ remove_from_timer_list( hash_table , &(trans->outbound_response->tl[RETRASMISSIONS_LIST]) , RETRASMISSIONS_LIST ); |
|
911 | 925 |
} |
912 | 926 |
else |
913 | 927 |
{ |
914 | 928 |
struct hostent *nhost; |
915 | 929 |
char foo; |
916 | 930 |
|
917 |
- T->inbound_response = (struct retrans_buff*)sh_malloc( sizeof(struct retrans_buff) ); |
|
918 |
- memset( T->inbound_response , 0 , sizeof (struct retrans_buff) ); |
|
919 |
- T->inbound_response->tl[RETRASMISSIONS_LIST].payload = &(T->inbound_response); |
|
920 |
- /*some dirty trick to get the port and ip of destination */ |
|
921 |
- foo = *((p_msg->via2->host.s)+(p_msg->via2->host.len)); |
|
922 |
- *((p_msg->via2->host.s)+(p_msg->via2->host.len)) = 0; |
|
923 |
- nhost = gethostbyname( p_msg->via2->host.s ); |
|
924 |
- *((p_msg->via2->host.s)+(p_msg->via2->host.len)) = foo; |
|
925 |
- if ( !nhost ) |
|
926 |
- return -1; |
|
927 |
- memcpy( &(T->inbound_response->to.sin_addr) , &(nhost->h_addr) , nhost->h_length ); |
|
928 |
- T->inbound_response->dest_ip = htonl(T->inbound_response->to.sin_addr.s_addr); |
|
929 |
- T->inbound_response->dest_port = ntohl(T->inbound_response->to.sin_port); |
|
930 |
- T->inbound_response->to.sin_family = AF_INET; |
|
931 |
+ trans->outbound_response = (struct retrans_buff*)sh_malloc( sizeof(struct retrans_buff) ); |
|
932 |
+ if (!trans->outbound_response) { |
|
933 |
+ LOG(L_ERR, "ERROR: push_reply_from_uac_to_uas: no more shmem\n"); |
|
934 |
+ trans->outbound_response = NULL; |
|
935 |
+ return -1; |
|
936 |
+ } |
|
937 |
+ memset( trans->outbound_response , 0 , sizeof (struct retrans_buff) ); |
|
938 |
+ trans->outbound_response->tl[RETRASMISSIONS_LIST].payload = trans->outbound_response; |
|
939 |
+ if (update_sock_struct_from_via( &(trans->outbound_response->to), trans->inbound_response[branch]->via2 )==-1) { |
|
940 |
+ LOG(L_ERR, "ERROR: push_reply_from_uac_to_uas: cannot lookup reply dst: %s\n", |
|
941 |
+ trans->inbound_response[branch]->via2->host.s ); |
|
942 |
+ sh_free( T->outbound_response ); |
|
943 |
+ T->outbound_response = NULL; |
|
944 |
+ return -1; |
|
945 |
+ } |
|
931 | 946 |
} |
932 | 947 |
|
933 | 948 |
/* */ |
934 |
- buf = build_res_buf_from_sip_res ( p_msg, &len); |
|
935 |
- if (!buf) |
|
949 |
+ buf = build_res_buf_from_sip_res ( trans->inbound_response[branch], &len); |
|
950 |
+ if (!buf) { |
|
951 |
+ LOG(L_ERR, "ERROR: push_reply_from_uac_to_uas: no shmem for outbound reply buffer\n"); |
|
936 | 952 |
return -1; |
937 |
- T->inbound_response->bufflen = len ; |
|
938 |
- T->inbound_response->buffer = (char*)sh_malloc( len ); |
|
939 |
- memcpy( T->inbound_response->buffer , buf , len ); |
|
953 |
+ } |
|
954 |
+ trans->outbound_response->bufflen = len ; |
|
955 |
+ trans->outbound_response->retr_buffer = (char*)sh_malloc( len ); |
|
956 |
+ memcpy( trans->outbound_response->retr_buffer , buf , len ); |
|
940 | 957 |
free( buf ) ; |
941 | 958 |
|
942 | 959 |
/* make sure that if we send something final upstream, everything else will be cancelled */ |
943 |
- if (T->outbound_response[branch]->first_line.u.reply.statusclass>=2 ) |
|
944 |
- t_put_on_wait( p_msg ); |
|
960 |
+ if (trans->inbound_response[branch]->first_line.u.reply.statusclass>=2 ) |
|
961 |
+ t_put_on_wait( trans->inbound_request ); |
|
945 | 962 |
|
946 | 963 |
/* if the code is 3,4,5,6 class for an INVITE-> starts retrans timer*/ |
947 |
- if ( T->inbound_request->first_line.u.request.method_value==METHOD_INVITE && |
|
948 |
- T->outbound_response[branch]->first_line.u.reply.statusclass>=300) |
|
964 |
+ if ( trans->inbound_request->first_line.u.request.method_value==METHOD_INVITE && |
|
965 |
+ trans->inbound_response[branch]->first_line.u.reply.statusclass>=300) |
|
949 | 966 |
{ |
950 |
- remove_from_timer_list( hash_table , &(T->inbound_response->tl[RETRASMISSIONS_LIST]) , RETRASMISSIONS_LIST ); |
|
951 |
- remove_from_timer_list( hash_table , &(T->inbound_response->tl[FR_TIMER_LIST]) , FR_TIMER_LIST ); |
|
952 |
- insert_into_timer_list( hash_table , &(T->inbound_response->tl[RETRASMISSIONS_LIST]) , RETRASMISSIONS_LIST , RETR_T1 ); |
|
953 |
- insert_into_timer_list( hash_table , &(T->inbound_response->tl[FR_TIMER_LIST]) , FR_TIMER_LIST , FR_TIME_OUT ); |
|
967 |
+ remove_from_timer_list( hash_table , &(trans->outbound_response->tl[RETRASMISSIONS_LIST]) , RETRASMISSIONS_LIST ); |
|
968 |
+ remove_from_timer_list( hash_table , &(trans->outbound_response->tl[FR_TIMER_LIST]) , FR_TIMER_LIST ); |
|
969 |
+ insert_into_timer_list( hash_table , &(trans->outbound_response->tl[RETRASMISSIONS_LIST]) , RETRASMISSIONS_LIST , RETR_T1 ); |
|
970 |
+ insert_into_timer_list( hash_table , &(trans->outbound_response->tl[FR_TIMER_LIST]) , FR_TIMER_LIST , FR_TIME_OUT ); |
|
954 | 971 |
} |
955 | 972 |
|
956 |
- t_retransmit_reply( p_msg, 0 , 0 ); |
|
973 |
+ t_retransmit_reply( trans->inbound_request, 0 , 0 ); |
|
957 | 974 |
} |
958 | 975 |
|
959 | 976 |
|
... | ... |
@@ -1109,7 +1126,7 @@ void retransmission_handler( void *attr) |
1109 | 1126 |
|
1110 | 1127 |
/* retransmision */ |
1111 | 1128 |
DBG("DEBUG: retransmission_handler : resending\n"); |
1112 |
- udp_send( r_buf->buffer, r_buf->bufflen, (struct sockaddr*)&(r_buf->to) , sizeof(struct sockaddr_in) ); |
|
1129 |
+ udp_send( r_buf->retr_buffer, r_buf->bufflen, (struct sockaddr*)&(r_buf->to) , sizeof(struct sockaddr_in) ); |
|
1113 | 1130 |
|
1114 | 1131 |
/* re-insert into RETRASMISSIONS_LIST */ |
1115 | 1132 |
insert_into_timer_list( hash_table , &(r_buf->tl[RETRASMISSIONS_LIST]) , RETRASMISSIONS_LIST , r_buf->timeout_value ); |
... | ... |
@@ -19,6 +19,9 @@ struct cell; |
19 | 19 |
#include "lock.h" |
20 | 20 |
#include "sip_msg.h" |
21 | 21 |
|
22 |
+#define T_UNDEFINED ( (struct cell*) -1 ) |
|
23 |
+#define T_NULL ( (struct cell*) 0 ) |
|
24 |
+ |
|
22 | 25 |
#define sh_malloc( size ) malloc(size) |
23 | 26 |
#define sh_free( ptr ) free(ptr) |
24 | 27 |
/* already defined in msg_parser.h |
... | ... |
@@ -113,7 +116,7 @@ int t_check( struct s_table* , struct sip_msg* ); |
113 | 116 |
int t_all_final( struct cell * ); |
114 | 117 |
int t_build_and_send_ACK( struct cell *Trans , unsigned int brach ); |
115 | 118 |
int relay_lowest_reply_upstream( struct cell *Trans , struct sip_msg *p_msg ); |
116 |
-int push_reply_from_uac_to_uas( struct sip_msg * , unsigned int ); |
|
119 |
+int push_reply_from_uac_to_uas( struct cell* Trans , unsigned int ); |
|
117 | 120 |
int t_cancel_branch(unsigned int branch); //TO DO |
118 | 121 |
int add_branch_label( struct cell *Trans, struct sip_msg *p_msg , int branch ); |
119 | 122 |
|
... | ... |
@@ -240,8 +240,7 @@ void free_sip_msg(struct sip_msg* msg); |
240 | 240 |
( ((msg)->from || (parse_headers( (msg), HDR_FROM)!=-1 && (msg)->from)) && \ |
241 | 241 |
((msg)->to|| (parse_headers( (msg), HDR_TO)!=-1 && (msg)->to)) && \ |
242 | 242 |
((msg)->callid|| (parse_headers( (msg), HDR_CALLID)!=-1 && (msg)->callid)) &&\ |
243 |
- ((msg)->cseq|| (parse_headers( (msg), HDR_CSEQ)!=-1 && (msg)->cseq)) ) |
|
244 |
- |
|
245 |
- |
|
243 |
+ ((msg)->cseq|| (parse_headers( (msg), HDR_CSEQ)!=-1 && (msg)->cseq)) && \ |
|
244 |
+ ((msg)->via1|| (parse_headers( (msg), HDR_VIA)!=-1 && (msg)->via1)) ) |
|
246 | 245 |
|
247 | 246 |
#endif |
... | ... |
@@ -515,27 +515,41 @@ error: |
515 | 515 |
|
516 | 516 |
|
517 | 517 |
char * build_res_buf_from_sip_req( unsigned int code , |
518 |
- char *text , |
|
519 |
- struct sip_msg* msg, |
|
520 |
- unsigned int *returned_len) |
|
518 |
+ char *text , struct sip_msg* msg, unsigned int *returned_len) |
|
521 | 519 |
{ |
522 | 520 |
char *buf=0, *p; |
523 | 521 |
unsigned int len,foo; |
524 | 522 |
struct hdr_field *hdr; |
525 |
- int i; |
|
523 |
+ int first_via; |
|
524 |
+ int str_len_text; |
|
525 |
+ int i; |
|
526 |
+ |
|
527 |
+ str_len_text=strlen(text); |
|
526 | 528 |
|
527 | 529 |
/*computes the lenght of the new response buffer*/ |
528 | 530 |
len = 0; |
529 | 531 |
/* first line */ |
530 |
- len += 3/*code*/ + 1/*space*/ + strlen(text) + 1/*new line*/; |
|
531 |
- /*headers that will be copied (TO, FROM, CSEQ,CALLID,VIA)*/ |
|
532 |
- for ( hdr=msg->headers ; hdr ; hdr=hdr->next ) |
|
533 |
- if ( hdr->type==HDR_VIA || hdr->type==HDR_FROM || |
|
534 |
- hdr->type==HDR_CALLID || hdr->type==HDR_TO || |
|
535 |
- hdr->type==HDR_CSEQ ) |
|
536 |
- len += ((hdr->body.s+hdr->body.len ) - hdr->name.s ) ; |
|
532 |
+ len += 3/*code*/ + 1/*space*/ + str_len_text + CRLF_LEN/*new line*/; |
|
533 |
+ |
|
534 |
+ /* force parsing all headers -- we want to return all |
|
535 |
+ Via's in the reply and they may be scattered down to the |
|
536 |
+ end of header (non-block Vias are a really poor property |
|
537 |
+ of SIP :( ) |
|
538 |
+ */ |
|
539 |
+ parse_headers( msg, HDR_EOH ); |
|
540 |
+ /* check if I have those HFs identifying a transaction here */ |
|
541 |
+ if (!check_transaction_quadruple( msg )) |
|
542 |
+ goto error; |
|
543 |
+ |
|
544 |
+ first_via = 1; |
|
545 |
+ for ( hdr=msg->headers ; hdr ; hdr=hdr->next ) |
|
546 |
+ if ( hdr->type==HDR_FROM || |
|
547 |
+ (hdr->type==HDR_VIA ? (first_via ? first_via=0, 0: 1 ) : 0) || |
|
548 |
+ hdr->type==HDR_CALLID || hdr->type==HDR_TO || |
|
549 |
+ hdr->type==HDR_CSEQ ) |
|
550 |
+ len += hdr->body.len + hdr->name.len + MY_HF_SEP_LEN + CRLF_LEN; |
|
537 | 551 |
/* end of message */ |
538 |
- len += 1; /*new line*/ |
|
552 |
+ len += CRLF_LEN; /*new line*/ |
|
539 | 553 |
|
540 | 554 |
/*allocating mem*/ |
541 | 555 |
buf = (char*) malloc( len+1 ); |
... | ... |
@@ -545,30 +559,51 @@ char * build_res_buf_from_sip_req( unsigned int code , |
545 | 559 |
LOG(L_ERR, "ERROR: build_res_buf_from_sip_req: out of memory\n"); |
546 | 560 |
goto error; |
547 | 561 |
} |
562 |
+ p=buf; |
|
548 | 563 |
|
549 | 564 |
/* filling the buffer*/ |
550 | 565 |
/* first line */ |
551 | 566 |
for ( i=2 , foo = code ; i>=0 ; i-- , foo=foo/10 ) |
552 |
- *(p+i) = '0' + foo - ( foo/10 )*10; |
|
567 |
+ *(p+i) = '0' + foo % 10; |
|
553 | 568 |
p += 3; |
554 | 569 |
*(p++) = ' ' ; |
555 |
- memcpy( p , text , strlen(text) ); |
|
556 |
- p += strlen(text); |
|
557 |
- *(p++) = '\n'; |
|
570 |
+ memcpy( p , text , str_len_text ); |
|
571 |
+ p += str_len_text; |
|
572 |
+ memcpy( p, CRLF, CRLF_LEN ); |
|
573 |
+ p+=CRLF_LEN; |
|
574 |
+ |
|
558 | 575 |
/* headers*/ |
576 |
+ first_via=1; |
|
559 | 577 |
for ( hdr=msg->headers ; hdr ; hdr=hdr->next ) |
560 |
- if ( hdr->type==HDR_VIA || hdr->type==HDR_FROM || |
|
561 |
- hdr->type==HDR_CALLID || hdr->type==HDR_TO || hdr->type==HDR_CSEQ ) |
|
578 |
+ if ( hdr->type==HDR_FROM || |
|
579 |
+ hdr->type==HDR_CALLID || hdr->type==HDR_TO || |
|
580 |
+ (hdr->type==HDR_VIA ? (first_via ? first_via=0, 0: 1 ) : 0) || |
|
581 |
+ hdr->type==HDR_CSEQ ) |
|
562 | 582 |
{ |
563 |
- memcpy( p , msg->orig+(hdr->name.s-msg->buf) , |
|
564 |
- ((hdr->body.s+hdr->body.len ) - |
|
565 |
- hdr->name.s ) ); |
|
566 |
- p += ((hdr->body.s+hdr->body.len ) - hdr->name.s ); |
|
583 |
+ char *end; int plen; |
|
584 |
+ |
|
585 |
+ end = hdr->name.s+hdr->name.len-1; |
|
586 |
+ plen= (*end==0) ? hdr->name.len - 1 : hdr->name.len; |
|
587 |
+ memcpy( p, hdr->name.s, plen ); |
|
588 |
+ p+=plen; |
|
589 |
+ |
|
590 |
+ memcpy( p, MY_HF_SEP, MY_HF_SEP_LEN ); |
|
591 |
+ p+=MY_HF_SEP_LEN; |
|
592 |
+ |
|
593 |
+ end = hdr->body.s+hdr->body.len-1; |
|
594 |
+ plen= (*end==0) ? hdr->body.len - 1 : hdr->body.len; |
|
595 |
+ memcpy( p, hdr->body.s, plen ); |
|
596 |
+ p+=plen; |
|
597 |
+ memcpy( p, CRLF, CRLF_LEN ); |
|
598 |
+ p+=CRLF_LEN; |
|
567 | 599 |
} |
568 |
- |
|
569 |
- *(p++) = '\n'; |
|
600 |
+ memcpy( p, CRLF, CRLF_LEN ); |
|
601 |
+ p+=CRLF_LEN; |
|
570 | 602 |
*(p++) = 0; |
571 |
- *returned_len=len; |
|
603 |
+ |
|
604 |
+ |
|
605 |
+ /* *returned_len=len; */ |
|
606 |
+ *returned_len=p-buf; |
|
572 | 607 |
return buf; |
573 | 608 |
error: |
574 | 609 |
if (buf) free(buf); |
... | ... |
@@ -111,8 +111,10 @@ int receive_msg(char* buf, unsigned int len, unsigned long src_ip) |
111 | 111 |
#ifdef STATS |
112 | 112 |
skipped = 0; |
113 | 113 |
#endif |
114 |
+/* jku: skip no more used |
|
114 | 115 |
skip: |
115 | 116 |
DBG("skip:...\n"); |
117 |
+*/ |
|
116 | 118 |
free_sip_msg(msg); |
117 | 119 |
pkg_free(msg); |
118 | 120 |
#ifdef STATS |
... | ... |
@@ -5,7 +5,7 @@ rev_dns=yes # (cmd. line: -R) |
5 | 5 |
fork=no # (cmd. line: -D) |
6 | 6 |
log_stderror=yes # (cmd line: -E) |
7 | 7 |
port=5080 |
8 |
-listen=127.0.0.1 |
|
8 |
+listen=192.168.99.100 |
|
9 | 9 |
loop_checks=1 |
10 | 10 |
# for more info: sip_router -h |
11 | 11 |
|
... | ... |
@@ -21,21 +21,21 @@ route{ |
21 | 21 |
if ( t_lookup_request()) { |
22 | 22 |
if ( method=="ACK" ) { |
23 | 23 |
# XXX ... t_release not implemented yet |
24 |
- log("t_release"); |
|
24 |
+ log("SER: t_release\n"); |
|
25 | 25 |
#t_release(); |
26 | 26 |
} else { |
27 | 27 |
t_retransmit_reply(); |
28 |
- log("yet another annoying retranmission"); |
|
28 |
+ log("SER: yet another annoying retranmission\n"); |
|
29 | 29 |
}; |
30 | 30 |
} else { |
31 | 31 |
t_add_transaction(); |
32 | 32 |
if (method=="CANCEL") { |
33 |
- log("new CANCEL"); |
|
33 |
+ log("SER: new CANCEL\n"); |
|
34 | 34 |
# XXX ... it wants me to put status code in "" |
35 | 35 |
t_send_reply( "200", "glad to cancel"); |
36 | 36 |
} else { |
37 |
- log("new transaction"); |
|
38 |
- #t_send_reply("100", "trying -- your call is important to us"); |
|
37 |
+ log("SER: new transaction\n"); |
|
38 |
+ t_send_reply("100", "trying -- your call is important to us"); |
|
39 | 39 |
}; |
40 | 40 |
#rewritehost("xy.com"); |
41 | 41 |
# XXX ... it wants me to put port nr in "" |
... | ... |
@@ -8,6 +8,7 @@ |
8 | 8 |
#include <sys/socket.h> |
9 | 9 |
#include <netinet/in.h> |
10 | 10 |
#include <errno.h> |
11 |
+#include <arpa/inet.h> |
|
11 | 12 |
|
12 | 13 |
|
13 | 14 |
#include "udp_server.h" |
... | ... |
@@ -200,11 +201,50 @@ int udp_send(char *buf, unsigned len, struct sockaddr* to, unsigned tolen) |
200 | 201 |
{ |
201 | 202 |
|
202 | 203 |
int n; |
204 |
+ |
|
205 |
+/* struct sockaddr_in a2;*/ |
|
206 |
+ |
|
207 |
+#ifndef NO_DEBUG |
|
208 |
+#define MAX_IP_LENGTH 18 |
|
209 |
+ char ip_txt[MAX_IP_LENGTH]; |
|
210 |
+ char *c; |
|
211 |
+ struct sockaddr_in* a; |
|
212 |
+ unsigned short p; |
|
213 |
+ |
|
214 |
+ a=(struct sockaddr_in*) to; |
|
215 |
+ memset(ip_txt, 0, MAX_IP_LENGTH); |
|
216 |
+ c=inet_ntoa(a->sin_addr); |
|
217 |
+ strncpy( ip_txt, c, MAX_IP_LENGTH - 1 ); |
|
218 |
+ p=ntohs(a->sin_port); |
|
219 |
+ DBG("DEBUG: udp_send: "); |
|
220 |
+ |
|
221 |
+ if (tolen < sizeof(struct sockaddr_in)) |
|
222 |
+ DBG("DEBUG: tolen small\n"); |
|
223 |
+ if (a->sin_family && a->sin_family != AF_INET) |
|
224 |
+ DBG("DEBUG: to not INET\n"); |
|
225 |
+ if (a->sin_port == 0) |
|
226 |
+ DBG("DEBUG: no port\n"); |
|
227 |
+ |
|
228 |
+ DBG(" destination: IP=%s, port=%u; packet:\n", ip_txt, p); |
|
229 |
+ DBG(" destination (hex): IP=%x, port=%x;\n", a->sin_addr.s_addr, a->sin_port ); |
|
230 |
+ DBG("%*s\n", len, buf ); |
|
231 |
+#endif |
|
232 |
+/* |
|
233 |
+ memset(&a2, 0, sizeof(struct sockaddr_in)); |
|
234 |
+ a2.sin_family = a->sin_family; |
|
235 |
+ a2.sin_port = a->sin_port; |
|
236 |
+ a2.sin_addr.s_addr = a->sin_addr.s_addr; |
|
237 |
+*/ |
|
238 |
+ |
|
203 | 239 |
again: |
204 | 240 |
n=sendto(udp_sock, buf, len, 0, to, tolen); |
241 |
+/* n=sendto(udp_sock, buf, len, 0, &a2, sizeof(struct sockaddr_in) );*/ |
|
205 | 242 |
if (n==-1){ |
206 | 243 |
LOG(L_ERR, "ERROR: udp_send: sendto: %s\n", strerror(errno)); |
207 | 244 |
if (errno==EINTR) goto again; |
245 |
+ if (errno==EINVAL) LOG(L_CRIT,"CRITICAL: invalid sendtoparameters\n" |
|
246 |
+ "one possible reason is the server is bound to localhost and\n" |
|
247 |
+ "attempts to send to the net\n"); |
|
208 | 248 |
} |
209 | 249 |
return n; |
210 | 250 |
} |