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 151
 	}
152 152
 
153 153
 	 /* send it! */
154
+	/* moved to udp_send; -jiri
155
+
154 156
 	DBG("Sending: to %s:%d, \n%s.\n",
155 157
 			msg->via2->host.s,
156 158
 			(unsigned short)msg->via2->port,
157 159
 			new_buf);
160
+	*/
158 161
 
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]);
162
+	if (update_sock_struct_from_via( to, msg->via2 )==-1) goto error;
178 163
 
179
-#ifdef DNS_IP_HACK
180
-	}
181
-#endif
182 164
 	if (udp_send(new_buf,new_len, (struct sockaddr*) to,
183 165
 					sizeof(struct sockaddr_in))==-1)
184 166
 	{
... ...
@@ -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 88
    struct timer_link dele_tl;
89 89
 
90 90
    /* usefull data */
91
-   /* incoming request and its response*/
91
+   /* UA Server */
92 92
    struct sip_msg         *inbound_request;
93
-   struct retrans_buff   *inbound_response;
93
+   struct retrans_buff   *outbound_response;
94 94
    unsigned int             status;
95 95
    str*                             tag;
96 96
    /* array of outgoing requests and its responses */
97 97
    int                               nr_of_outgoings;
98
+   /* UA Clients */
98 99
    struct retrans_buff   *outbound_request[ MAX_FORK ];
99
-   struct sip_msg          *outbound_response[ MAX_FORK ];
100
+   struct sip_msg          *inbound_response[ MAX_FORK ];
100 101
 }cell_type;
101 102
 
102 103
 
... ...
@@ -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 310
 /*only the content*/
311 311
 void sip_msg_free(struct sip_msg* msg)
312 312
 {
313
+   if (!msg) return;
314
+
313 315
    if (msg->new_uri.s)
314 316
    {
315 317
       sh_free(msg->new_uri.s);
316 318
       msg->new_uri.len=0;
317 319
    }
318
-   DBG("DEBUG: sip_msg_free : headers\n");
320
+   LOG(L_ERR, "ERROR: sip_msg_free : headers and via1/via2 freeing still missing\n");
319 321
    //if (msg->headers)
320 322
     //  free_hdr_field_lst(msg->headers);
321 323
    DBG("DEBUG: sip_msg_free : lump\n");
... ...
@@ -323,11 +332,7 @@ void sip_msg_free(struct sip_msg* msg)
323 323
       free_lump_list(msg->add_rm);
324 324
    if (msg->repl_add_rm)
325 325
       free_lump_list(msg->repl_add_rm);
326
-   sh_free( msg->orig );
327
-   sh_free( msg->buf );
326
+   if (msg->orig) sh_free( msg->orig );
327
+   if (msg->buf) sh_free( msg->buf );
328
+   
328 329
 }
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 269
       T->nr_of_outgoings = 1;
270 270
 
271 271
       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 272
       buf = build_req_buf_from_sip_req  ( p_msg, &len);
274 273
       if (!buf)
275 274
          return -1;
276 275
       T->outbound_request[branch]->bufflen = len ;
277
-      if ( !(T->outbound_request[branch]->buffer   = (char*)sh_malloc( len ))) {
276
+      if ( !(T->outbound_request[branch]->retr_buffer   = (char*)sh_malloc( len ))) {
278 277
 	LOG(L_ERR, "ERROR: t_forward: shmem allocation failed\n");
279 278
 	free( buf );
280 279
 	return -1;
281 280
       }
282
-      memcpy( T->outbound_request[branch]->buffer , buf , len );
281
+      memcpy( T->outbound_request[branch]->retr_buffer , buf , len );
283 282
       free( buf ) ;
284 283
 
285 284
       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 292
       insert_into_timer_list( hash_table , &(T->outbound_request[branch]->tl[RETRASMISSIONS_LIST]), RETRASMISSIONS_LIST , RETR_T1 );
293 293
    }/* end for the first time */
294 294
 
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 295
    /* send the request */
299
-   T->outbound_request[branch]->dest_ip         = dest_ip;
300
-   T->outbound_request[branch]->dest_port      = dest_port;
296
+   /* known to be in network order */
301 297
    T->outbound_request[branch]->to.sin_port     =  dest_port;
302 298
    T->outbound_request[branch]->to.sin_addr.s_addr =  dest_ip;
303
-   udp_send( T->outbound_request[branch]->buffer , T->outbound_request[branch]->bufflen ,
299
+   T->outbound_request[branch]->to.sin_family = AF_INET;
300
+
301
+   udp_send( T->outbound_request[branch]->retr_buffer , T->outbound_request[branch]->bufflen ,
304 302
                     (struct sockaddr*)&(T->outbound_request[branch]->to) , sizeof(struct sockaddr_in) );
305 303
    return 1;
306 304
 }
... ...
@@ -323,13 +324,13 @@ int t_forward_uri( struct sip_msg* p_msg, char* foo, char* bar  )
323 323
    /* it's about the same transaction or not? */
324 324
    if ( global_msg_id != p_msg->id )
325 325
    {
326
-      T = (struct cell*)-1;
326
+      T = T_UNDEFINED;
327 327
       global_msg_id = p_msg->id;
328 328
    }
329 329
 
330 330
    DBG("DEBUG: t_forward_uri: 1. T=%x\n", T);
331 331
    /* if  T hasn't been previous searched -> search for it */
332
-   if ( (int)T ==-1 )
332
+   if ( T==T_UNDEFINED )
333 333
       t_lookup_request( p_msg, 0 , 0 );
334 334
 
335 335
    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 379
    t_reply_matching( hash_table , p_msg , &T , &branch  );
380 380
 
381 381
    /* if no T found ->tell the core router to forward statelessly */
382
-   if ( !T )
382
+   if ( T<=0 )
383 383
       return 1;
384 384
 
385 385
    /* stop retransmission */
... ...
@@ -462,7 +463,7 @@ int t_put_on_wait(  struct sip_msg  *p_msg  )
462 462
 
463 463
    t_check( hash_table , p_msg );
464 464
    /* do we have something to release? */
465
-   if (T==0)
465
+   if (T==T_NULL)
466 466
       return -1;
467 467
 
468 468
   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 474
 
475 475
   /**/
476 476
   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)
477
+      if ( T->inbound_response[i] && T->inbound_response[i]->first_line.u.reply.statusclass==1)
478 478
           t_cancel_branch(i);
479 479
 
480 480
    /* make double-sure we have finished everything */
481 481
    /* remove from  retranssmision  and  final response   list */
482 482
    DBG("DEBUG: t_put_on_wait: remove inboud stuff from lists\n");
483
-   if ( T->inbound_response )
483
+   if ( T->outbound_response )
484 484
    {
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 );
485
+      remove_from_timer_list( hash_table , &(T->outbound_response->tl[RETRASMISSIONS_LIST]) , RETRASMISSIONS_LIST );
486
+      remove_from_timer_list( hash_table , &(T->outbound_response->tl[FR_TIMER_LIST]) , FR_TIMER_LIST );
487 487
    }
488 488
    for( i=0 ; i<T->nr_of_outgoings ; i++ )
489 489
    {
... ...
@@ -500,6 +501,9 @@ int t_put_on_wait(  struct sip_msg  *p_msg  )
500 500
 
501 501
 
502 502
 /* Retransmits the last sent inbound reply.
503
+
504
+  * input: p_msg==request for which I want to retransmit an associated
505
+    reply
503 506
   * Returns  -1 -error
504 507
   *                1 - OK
505 508
   */
... ...
@@ -508,12 +512,14 @@ int t_retransmit_reply( struct sip_msg* p_msg, char* foo, char* bar  )
508 508
    t_check( hash_table, p_msg );
509 509
 
510 510
    /* if no transaction exists or no reply to be resend -> out */
511
-   if ( T  && T->inbound_response )
511
+   if ( T  && T->outbound_response )
512 512
    {
513
-      udp_send( T->inbound_response->buffer , T->inbound_response->bufflen , (struct sockaddr*)&(T->inbound_response->to) , sizeof(struct sockaddr_in) );
513
+      udp_send( T->outbound_response->retr_buffer , T->outbound_response->bufflen , 
514
+	(struct sockaddr*)&(T->outbound_response->to) , sizeof(struct sockaddr_in) );
514 515
       return 1;
515 516
    }
516 517
 
518
+  /* no transaction found */
517 519
    return -1;
518 520
 }
519 521
 
... ...
@@ -525,85 +531,88 @@ int t_retransmit_reply( struct sip_msg* p_msg, char* foo, char* bar  )
525 525
   */
526 526
 int t_send_reply(  struct sip_msg* p_msg , unsigned int code , char * text )
527 527
 {
528
-   t_check( hash_table, p_msg );
528
+      	unsigned int len;
529
+      	char * buf = NULL;
530
+        struct hostent  *nhost;
531
+        unsigned int      ip, port;
532
+        char foo;
533
+	int err;
534
+        struct retrans_buff* rb = NULL;
535
+
536
+   	DBG("DEBUG: t_send_reply: entered\n");
537
+   	t_check( hash_table, p_msg );
538
+
539
+   	if (!T) {
540
+		LOG(L_ERR, "ERROR: cannot send a t_reply to a message for which no T-state has been established\n");
541
+		return -1;
542
+   	} ;
529 543
 
530
-   if (T)
531
-   {
532
-      unsigned int len;
533
-      char * buf;
544
+      	buf = build_res_buf_from_sip_req( code , text , T->inbound_request , &len );
545
+        DBG("DEBUG: t_send_reply: after build\n");
546
+      	if (!buf)
547
+      	{
548
+         	DBG("DEBUG: t_send_reply: response building failed\n");
549
+		goto error;
550
+      	}
551
+
552
+     	if ( T->outbound_response) {
553
+		if (  T->outbound_response->retr_buffer )
554
+      		{
555
+			sh_free( T->outbound_response->retr_buffer );
556
+			T->outbound_response->retr_buffer = NULL;
557
+	 	}
558
+	} else {
559
+		rb = (struct retrans_buff*)sh_malloc( sizeof(struct retrans_buff) );
560
+		if (!rb) {
561
+			LOG(L_ERR, "ERROR: t_send_reply: cannot allocate shmem\n");
562
+			goto error;
563
+		} 
564
+		T->outbound_response = rb;
565
+		memset( T->outbound_response , 0 , sizeof (struct retrans_buff) );
566
+	}
534 567
 
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 568
 
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 ) ;
569
+	/* initialize retransmission structure */
570
+	if (update_sock_struct_from_via(  &(T->outbound_response->to),  p_msg->via1 )==-1) {
571
+		LOG(L_ERR, "ERROR: t_send_reply: cannot lookup reply dst: %s\n",
572
+                p_msg->via1->host.s );
573
+		goto error;
574
+	  }
575
+
576
+	T->outbound_response->tl[RETRASMISSIONS_LIST].payload = T->outbound_response;
577
+      	T->outbound_response->tl[FR_TIMER_LIST].payload = T->outbound_response;
578
+      	T->outbound_response->my_T = T;
579
+      	T->status = code;
580
+      	T->outbound_response->bufflen = len ;
581
+      	T->outbound_response->retr_buffer   = (char*)sh_malloc( len );
582
+      	if (!T->outbound_response->retr_buffer) {
583
+		T->outbound_response->retr_buffer = NULL;
584
+		LOG(L_ERR, "ERROR: t_send_reply: cannot allocate shmem buffer\n");
585
+		goto error;
586
+      	}
587
+      	memcpy( T->outbound_response->retr_buffer , buf , len );
588
+      	free( buf ) ;
586 589
 
587 590
       /* 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
591
+      if ( code>=300 &&  p_msg->first_line.u.request.method_value==METHOD_INVITE )
599 592
          {
600
-            t_put_on_wait( p_msg );
593
+            T->outbound_response->timeout_ceiling  = RETR_T2;
594
+            T->outbound_response->timeout_value    = RETR_T1;
595
+            remove_from_timer_list( hash_table , &(T->outbound_response->tl[RETRASMISSIONS_LIST]) , RETRASMISSIONS_LIST );
596
+            insert_into_timer_list( hash_table , &(T->outbound_response->tl[RETRASMISSIONS_LIST]) , RETRASMISSIONS_LIST , RETR_T1 );
597
+            remove_from_timer_list( hash_table , &(T->outbound_response->tl[FR_TIMER_LIST]) , FR_TIMER_LIST );
598
+            insert_into_timer_list( hash_table , &(T->outbound_response->tl[FR_TIMER_LIST]) , FR_TIMER_LIST , FR_TIME_OUT );
601 599
          }
600
+      else if (code>=200) t_put_on_wait( p_msg );
602 601
 
603
-      udp_send( T->inbound_response->buffer , T->inbound_response->bufflen , (struct sockaddr*)&(T->inbound_response->to) , sizeof(struct sockaddr_in) );
604
-   }
602
+      t_retransmit_reply( p_msg, 0 , 0);
605 603
 
606
-   return 1;
604
+      return 1;
605
+
606
+error:
607
+	if (rb) { sh_free(rb); T->outbound_response = rb = NULL;}
608
+	if ( buf ) free ( buf );
609
+	return -1;
607 610
 }
608 611
 
609 612
 
... ...
@@ -712,6 +721,9 @@ int t_reply_matching( struct s_table *hash_table , struct sip_msg *p_msg , struc
712 712
    /* split the branch into pieces: loop_detection_check(ignored),
713 713
       hash_table_id, synonym_id, branch_id
714 714
    */
715
+   if (! ( p_msg->via1 && p_msg->via1->branch && p_msg->via1->branch->value.s) )
716
+	goto nomatch;
717
+
715 718
    p=p_msg->via1->branch->value.s;
716 719
    scan_space=p_msg->via1->branch->value.len;
717 720
 
... ...
@@ -803,11 +815,11 @@ nomatch:
803 803
 int t_store_incoming_reply( struct cell* Trans, unsigned int branch, struct sip_msg* p_msg )
804 804
 {
805 805
    /* if there is a previous reply, replace it */
806
-   if ( Trans->outbound_response[branch] )
807
-      free_sip_msg( Trans->outbound_response[branch] ) ;
806
+   if ( Trans->inbound_response[branch] )
807
+      free_sip_msg( Trans->inbound_response[branch] ) ;
808 808
    /* force parsing all the needed headers*/
809 809
    parse_headers(p_msg, HDR_VIA|HDR_TO|HDR_FROM|HDR_CALLID|HDR_CSEQ );
810
-   Trans->outbound_response[branch] = sip_msg_cloner( p_msg );
810
+   Trans->inbound_response[branch] = sip_msg_cloner( p_msg );
811 811
 }
812 812
 
813 813
 
... ...
@@ -819,7 +831,7 @@ int t_store_incoming_reply( struct cell* Trans, unsigned int branch, struct sip_
819 819
 int t_relay_reply( struct cell* Trans, unsigned int branch, struct sip_msg* p_msg )
820 820
 {
821 821
    t_store_incoming_reply( Trans , branch, p_msg );
822
-   push_reply_from_uac_to_uas( p_msg , branch );
822
+   push_reply_from_uac_to_uas( Trans , branch );
823 823
 }
824 824
 
825 825
 
... ...
@@ -834,7 +846,7 @@ int t_check( struct s_table *hash_table , struct sip_msg* p_msg )
834 834
    unsigned int branch;
835 835
 
836 836
    /* is T still up-to-date ? */
837
-   if ( p_msg->id != global_msg_id || (int)T==-1 )
837
+   if ( p_msg->id != global_msg_id || T==T_UNDEFINED )
838 838
    {
839 839
       global_msg_id = p_msg->id;
840 840
       /* transaction lookup */
... ...
@@ -861,7 +873,7 @@ int t_all_final( struct cell *Trans )
861 861
    unsigned int i;
862 862
 
863 863
    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 )
864
+      if (  !Trans->inbound_response[i] || (Trans->inbound_response[i]) && Trans->inbound_response[i]->first_line.u.reply.statuscode<200 )
865 865
          return 0;
866 866
 
867 867
    return 1;
... ...
@@ -880,14 +892,16 @@ int relay_lowest_reply_upstream( struct cell *Trans , struct sip_msg *p_msg )
880 880
    int                 lowest_v = 999;
881 881
 
882 882
    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 )
883
+      if ( T->inbound_response[i] && 
884
+	   T->inbound_response[i]->first_line.u.reply.statuscode>=200 && 
885
+	   T->inbound_response[i]->first_line.u.reply.statuscode<lowest_v )
884 886
       {
885 887
          lowest_i =i;
886
-         lowest_v = T->outbound_response[i]->first_line.u.reply.statuscode;
888
+         lowest_v = T->inbound_response[i]->first_line.u.reply.statuscode;
887 889
       }
888 890
 
889 891
    if ( lowest_i != -1 )
890
-      push_reply_from_uac_to_uas( p_msg ,lowest_i );
892
+      push_reply_from_uac_to_uas( T ,lowest_i );
891 893
 
892 894
    return lowest_i;
893 895
 }
... ...
@@ -898,62 +912,65 @@ int relay_lowest_reply_upstream( struct cell *Trans , struct sip_msg *p_msg )
898 898
 /* Push a previously stored reply from UA Client to UA Server
899 899
   * and send it out
900 900
   */
901
-int push_reply_from_uac_to_uas( struct sip_msg *p_msg , unsigned int branch )
901
+int push_reply_from_uac_to_uas( struct cell* trans , unsigned int branch )
902 902
 {
903 903
    char *buf;
904 904
    unsigned int len;
905 905
 
906 906
    /* if there is a reply, release the buffer (everything else stays same) */
907
-   if ( T->inbound_response )
907
+   if ( trans->outbound_response )
908 908
    {
909
-      sh_free( T->inbound_response->buffer );
910
-      remove_from_timer_list( hash_table , &(T->inbound_response->tl[RETRASMISSIONS_LIST]) , RETRASMISSIONS_LIST );
909
+      sh_free( trans->outbound_response->retr_buffer );
910
+      remove_from_timer_list( hash_table , &(trans->outbound_response->tl[RETRASMISSIONS_LIST]) , RETRASMISSIONS_LIST );
911 911
    }
912 912
    else
913 913
    {
914 914
       struct hostent  *nhost;
915 915
      char foo;
916 916
 
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;
917
+      trans->outbound_response = (struct retrans_buff*)sh_malloc( sizeof(struct retrans_buff) );
918
+      if (!trans->outbound_response) {
919
+	LOG(L_ERR, "ERROR: push_reply_from_uac_to_uas: no more shmem\n");
920
+	trans->outbound_response = NULL;
921
+	return -1;
922
+      }
923
+      memset( trans->outbound_response , 0 , sizeof (struct retrans_buff) );
924
+      trans->outbound_response->tl[RETRASMISSIONS_LIST].payload = trans->outbound_response;
925
+      if (update_sock_struct_from_via(  &(trans->outbound_response->to),  trans->inbound_response[branch]->via2 )==-1) {
926
+	LOG(L_ERR, "ERROR: push_reply_from_uac_to_uas: cannot lookup reply dst: %s\n",
927
+		trans->inbound_response[branch]->via2->host.s );
928
+	sh_free(  T->outbound_response );
929
+	T->outbound_response = NULL;
930
+	return -1;
931
+      }
931 932
    }
932 933
 
933 934
    /*  */
934
-   buf = build_res_buf_from_sip_res ( p_msg, &len);
935
-   if (!buf)
935
+   buf = build_res_buf_from_sip_res ( trans->inbound_response[branch], &len);
936
+   if (!buf) {
937
+	LOG(L_ERR, "ERROR: push_reply_from_uac_to_uas: no shmem for outbound reply buffer\n");
936 938
         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 );
939
+   }
940
+   trans->outbound_response->bufflen = len ;
941
+   trans->outbound_response->retr_buffer   = (char*)sh_malloc( len );
942
+   memcpy( trans->outbound_response->retr_buffer , buf , len );
940 943
    free( buf ) ;
941 944
 
942 945
    /* 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 );
946
+   if (trans->inbound_response[branch]->first_line.u.reply.statusclass>=2 )
947
+      t_put_on_wait( trans->inbound_request );
945 948
 
946 949
    /* 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)
950
+   if ( trans->inbound_request->first_line.u.request.method_value==METHOD_INVITE &&
951
+         trans->inbound_response[branch]->first_line.u.reply.statusclass>=300)
949 952
          {
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 );
953
+            remove_from_timer_list( hash_table , &(trans->outbound_response->tl[RETRASMISSIONS_LIST]) , RETRASMISSIONS_LIST );
954
+            remove_from_timer_list( hash_table , &(trans->outbound_response->tl[FR_TIMER_LIST]) , FR_TIMER_LIST );
955
+            insert_into_timer_list( hash_table , &(trans->outbound_response->tl[RETRASMISSIONS_LIST]) , RETRASMISSIONS_LIST , RETR_T1 );
956
+            insert_into_timer_list( hash_table , &(trans->outbound_response->tl[FR_TIMER_LIST]) , FR_TIMER_LIST , FR_TIME_OUT );
954 957
          }
955 958
 
956
-   t_retransmit_reply( p_msg, 0 , 0 );
959
+   t_retransmit_reply( trans->inbound_request, 0 , 0 );
957 960
 }
958 961
 
959 962
 
... ...
@@ -1109,7 +1126,7 @@ void retransmission_handler( void *attr)
1109 1109
 
1110 1110
    /* retransmision */
1111 1111
    DBG("DEBUG: retransmission_handler : resending\n");
1112
-   udp_send( r_buf->buffer, r_buf->bufflen, (struct sockaddr*)&(r_buf->to) , sizeof(struct sockaddr_in) );
1112
+   udp_send( r_buf->retr_buffer, r_buf->bufflen, (struct sockaddr*)&(r_buf->to) , sizeof(struct sockaddr_in) );
1113 1113
 
1114 1114
    /* re-insert into RETRASMISSIONS_LIST */
1115 1115
    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 113
 int t_all_final( struct cell * );
114 114
 int t_build_and_send_ACK( struct cell *Trans , unsigned int brach );
115 115
 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 );
116
+int push_reply_from_uac_to_uas( struct cell* Trans , unsigned int );
117 117
 int t_cancel_branch(unsigned int branch); //TO DO
118 118
 int add_branch_label( struct cell *Trans, struct sip_msg *p_msg , int branch );
119 119
 
... ...
@@ -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 545
 		LOG(L_ERR, "ERROR: build_res_buf_from_sip_req: out of memory\n");
546 546
 		goto error;
547 547
 	}
548
+	p=buf;
548 549
 
549 550
 	/* filling the buffer*/
550 551
 	/* first line */
551 552
 	for ( i=2 , foo = code  ;  i>=0  ;  i-- , foo=foo/10 )
552
-		*(p+i) = '0' + foo - ( foo/10 )*10;
553
+		*(p+i) = '0' + foo % 10;
553 554
 	p += 3;
554 555
 	*(p++) = ' ' ;
555
-	memcpy( p , text , strlen(text) );
556
-	p += strlen(text);
557
-	*(p++) = '\n';
556
+	memcpy( p , text , str_len_text );
557
+	p += str_len_text;
558
+	memcpy( p, CRLF, CRLF_LEN );
559
+	p+=CRLF_LEN;
560
+	
558 561
 	/* headers*/
562
+	first_via=1;
559 563
 	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 )
564
+		if ( hdr->type==HDR_FROM ||
565
+				hdr->type==HDR_CALLID || hdr->type==HDR_TO ||
566
+			(hdr->type==HDR_VIA ?  (first_via ? first_via=0, 0: 1 ) : 0) ||
567
+				hdr->type==HDR_CSEQ )
562 568
 		{
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 );
569
+			char *end; int plen;
570
+
571
+			end = hdr->name.s+hdr->name.len-1;
572
+			plen= (*end==0) ? hdr->name.len - 1 : hdr->name.len;
573
+			memcpy( p, hdr->name.s, plen );
574
+			p+=plen;
575
+
576
+			memcpy( p, MY_HF_SEP, MY_HF_SEP_LEN );
577
+			p+=MY_HF_SEP_LEN;
578
+
579
+			end = hdr->body.s+hdr->body.len-1;
580
+			plen= (*end==0) ? hdr->body.len - 1 : hdr->body.len;
581
+			memcpy( p, hdr->body.s, plen );
582
+			p+=plen;
583
+			memcpy( p, CRLF, CRLF_LEN );
584
+			p+=CRLF_LEN;
567 585
 		}
568
-
569
-	*(p++) = '\n';
586
+	memcpy( p, CRLF, CRLF_LEN );
587
+        p+=CRLF_LEN;
570 588
 	*(p++) = 0;
571
-	*returned_len=len;
589
+	
590
+
591
+	/* *returned_len=len; */
592
+	*returned_len=p-buf;
572 593
 	return buf;
573 594
 error:
574 595
 	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 200
 {
201 201
 
202 202
 	int n;
203
+
204
+/*	struct sockaddr_in a2;*/
205
+
206
+#ifndef NO_DEBUG
207
+#define MAX_IP_LENGTH 18
208
+	char ip_txt[MAX_IP_LENGTH];
209
+	char *c;
210
+	struct sockaddr_in* a;
211
+	unsigned short p;
212
+
213
+	a=(struct sockaddr_in*) to;
214
+	memset(ip_txt, 0, MAX_IP_LENGTH);
215
+	c=inet_ntoa(a->sin_addr);
216
+	strncpy( ip_txt, c, MAX_IP_LENGTH - 1 );
217
+	p=ntohs(a->sin_port);
218
+	DBG("DEBUG: udp_send: ");
219
+
220
+	if (tolen < sizeof(struct sockaddr_in)) 
221
+		DBG("DEBUG: tolen small\n");
222
+	if (a->sin_family && a->sin_family != AF_INET) 
223
+		DBG("DEBUG: to not INET\n");
224
+	if (a->sin_port == 0) 
225
+		DBG("DEBUG: no port\n");
226
+
227
+	DBG(" destination: IP=%s, port=%u; packet:\n", ip_txt, p);
228
+	DBG(" destination (hex): IP=%x, port=%x;\n", a->sin_addr.s_addr, a->sin_port );
229
+	DBG("%*s\n", len, buf );
230
+#endif
231
+/*
232
+	memset(&a2, 0, sizeof(struct sockaddr_in));
233
+	a2.sin_family = a->sin_family;
234
+	a2.sin_port = a->sin_port;
235
+	a2.sin_addr.s_addr = a->sin_addr.s_addr;
236
+*/
237
+
203 238
 again:
204 239
 	n=sendto(udp_sock, buf, len, 0, to, tolen);
240
+/*	n=sendto(udp_sock, buf, len, 0, &a2, sizeof(struct sockaddr_in) );*/
205 241
 	if (n==-1){
206 242
 		LOG(L_ERR, "ERROR: udp_send: sendto: %s\n", strerror(errno));
207 243
 		if (errno==EINTR) goto again;
244
+		if (errno==EINVAL) LOG(L_CRIT,"CRITICAL: invalid sendtoparameters\n"
245
+			"one possible reason is the server is bound to localhost and\n"
246
+			"attempts to send to the net\n");
208 247
 	}
209 248
 	return n;
210 249
 }