Browse code

T-management hugely refurbished, fat bugs fixed; alas, the timer routing in T-mgmt core dumps now

Jiri Kuthan authored on 03/12/2001 13:07:13
Showing 16 changed files
... ...
@@ -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
 
... ...
@@ -1,6 +1,7 @@
1 1
 file ./ser
2
-set args -f debug.cfg 
2
+set args -f t_debug.cfg
3 3
 break main
4 4
 #break dump_all_statistic
5 5
 #break lock_initialize
6
+break udp_send
6 7
 run
... ...
@@ -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
 	{
... ...
@@ -12,7 +12,7 @@
12 12
 
13 13
 
14 14
 int forward_request( struct sip_msg* msg,  struct proxy_l* p);
15
-
15
+int update_sock_struct_from_via( struct sockaddr_in* to,  struct via_body* via );
16 16
 int forward_reply( struct sip_msg* msg);
17 17
 
18 18
 #endif
... ...
@@ -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);
... ...
@@ -5,6 +5,9 @@
5 5
 #ifndef  _MSG_TRANSLATOR_H
6 6
 #define _MSG_TRANSLATOR_H
7 7
 
8
+#define MY_HF_SEP ": "
9
+#define MY_HF_SEP_LEN 2
10
+
8 11
 #include "msg_parser.h"
9 12
 
10 13
 char * build_req_buf_from_sip_req (	struct sip_msg* msg, 
... ...
@@ -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 ""
... ...
@@ -1,6 +1,6 @@
1 1
 SIP/2.0 200 Ok
2 2
 Via: SIP/2.0/UDP 127.0.0.1
3
-Via: SIP/2.0/UDP 127.0.0.1:5061
3
+Via: SIP/2.0/UDP 193.175.133.195:5060
4 4
 From: <sip:x@foo.bar>
5 5
 To: <sip:y@bar.foo>
6 6
 Call-ID:9437892232b@foo.bar
... ...
@@ -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
 }