Browse code

function for building and sending ACK added!

Bogdan-Andrei Iancu authored on 28/11/2001 19:55:30
Showing 3 changed files
... ...
@@ -145,6 +145,8 @@ struct cell*  build_cell( struct sip_msg* p_msg )
145 145
       new_cell->tl->payload = new_cell;
146 146
 
147 147
    /* inbound request */
148
+   /* force parsing all the needed headers*/
149
+   parse_headers(p_msg, HDR_VIA|HDR_TO|HDR_FROM|HDR_CALLID|HDR_CSEQ );
148 150
    new_cell->inbound_request =  sip_msg_cloner(p_msg) ;
149 151
    /* inbound response is NULL*/
150 152
    /* status is 0 */
... ...
@@ -11,9 +11,10 @@ int t_store_incoming_reply( struct cell* , unsigned int , struct sip_msg* );
11 11
 int t_relay_reply( struct cell* , unsigned int , struct sip_msg* );
12 12
 int t_check( struct s_table* , struct sip_msg*  );
13 13
 int t_all_final( struct cell * );
14
-int t_cancel_branch(unsigned int branch);
14
+int t_build_and_send_ACK( struct cell *Trans , unsigned int brach );
15 15
 int relay_lowest_reply_upstream( struct cell *Trans , struct sip_msg *p_msg );
16 16
 int push_reply_from_uac_to_uas( struct sip_msg * , unsigned int );
17
+int t_cancel_branch(unsigned int branch); //TO DO
17 18
 
18 19
 int send_udp_to( char *buf, unsigned buflen, struct sockaddr_in*  to, unsigned tolen );
19 20
 
... ...
@@ -221,7 +222,7 @@ int t_forward( struct sip_msg* p_msg , unsigned int dest_ip_param , unsigned int
221 222
       unsigned int dest_ip     = dest_ip_param;
222 223
       unsigned int dest_port  = dest_port_param;
223 224
       unsigned int len;
224
-      char              *buf;
225
+      char               *buf;
225 226
 
226 227
       /* allocates a new retrans_buff for the outbound request */
227 228
       T->outbound_request[0] = (struct retrans_buff*)sh_malloc( sizeof(struct retrans_buff) );
... ...
@@ -254,11 +255,13 @@ int t_forward( struct sip_msg* p_msg , unsigned int dest_ip_param , unsigned int
254 255
       T->outbound_request[0]->dest_port      = dest_port;
255 256
       T->outbound_request[0]->to.sin_family = AF_INET;
256 257
       T->outbound_request[0]->to.sin_port     = htonl( dest_port ) ;
257
-      T->outbound_request[0]->to.sin_addr.s_addr = ntohl( dest_port ) ;
258
+      T->outbound_request[0]->to.sin_addr.s_addr = ntohl( dest_ip ) ;
258 259
 
259 260
       // buf = build_message( p_mesg , &len );      TO DO!!
260 261
       // T->outbound_request[0]->bufflen     = len ;
262
+      // T->outbound_request[0]->buffer = (struct retans_buff*)sh_malloc( len );
261 263
       // memcpy( T->outbound_request[0]->buffer , buf , len );
264
+      // free( buf ) ;
262 265
    }/* end for the first time */
263 266
 
264 267
 
... ...
@@ -294,7 +297,7 @@ int t_on_reply_received( struct sip_msg  *p_msg )
294 297
    /* on a non-200 reply to INVITE, generate local ACK and stop retransmission of the INVITE */
295 298
    if ( T->inbound_request->first_line.u.request.method_value==METHOD_INVITE && p_msg->first_line.u.reply.statusclass>2 )
296 299
    {
297
-      // sendACK   TO DO !!!!!!!!!!
300
+      t_build_and_send_ACK( T , branch );
298 301
       remove_from_timer_list( hash_table , &(T->outbound_request[branch]->tl[RETRASMISSIONS_LIST]) , RETRASMISSIONS_LIST );
299 302
       t_store_incoming_reply( T , branch , p_msg );
300 303
    }
... ...
@@ -391,7 +394,7 @@ int t_put_on_wait(  struct sip_msg  *p_msg  )
391 394
   * Returns  -1 -error
392 395
   *                0 - OK
393 396
   */
394
-int t_retransmit_reply( struct s_table *hash_table , struct sip_msg* p_msg )
397
+int t_retransmit_reply( struct sip_msg* p_msg )
395 398
 {
396 399
    t_check( hash_table, p_msg );
397 400
 
... ...
@@ -556,6 +559,8 @@ int t_store_incoming_reply( struct cell* Trans, unsigned int branch, struct sip_
556 559
    /* if there is a previous reply, replace it */
557 560
    if ( Trans->outbound_response[branch] )
558 561
       free_sip_msg( Trans->outbound_response[branch] ) ;
562
+   /* force parsing all the needed headers*/
563
+   parse_headers(p_msg, HDR_VIA|HDR_TO|HDR_FROM|HDR_CALLID|HDR_CSEQ );
559 564
    Trans->outbound_response[branch] = sip_msg_cloner( p_msg );
560 565
 }
561 566
 
... ...
@@ -653,10 +658,114 @@ int push_reply_from_uac_to_uas( struct sip_msg *p_msg , unsigned int branch )
653 658
    if ( T->inbound_response )
654 659
    {
655 660
       sh_free( T->inbound_response->buffer );
656
-      //release_retransmision.... ????
657 661
    }
662
+   else
663
+   {
664
+      struct hostent  *nhost;
665
+     char foo,*buf;
666
+      unsigned int len;
667
+
668
+      T->inbound_response = (struct retrans_buff*)sh_malloc( sizeof(struct retrans_buff) );
669
+      memset( T->inbound_response , 0 , sizeof (struct retrans_buff) );
670
+      T->inbound_response->tl[RETRASMISSIONS_LIST].payload = &(T->inbound_response);
671
+      /*some dirty trick to get the port and ip of destination */
672
+      foo = *((p_msg->via2->host.s)+(p_msg->via2->host.len));
673
+      *((p_msg->via2->host.s)+(p_msg->via2->host.len)) = 0;
674
+      nhost = gethostbyname( p_msg->via2->host.s );
675
+      *((p_msg->via2->host.s)+(p_msg->via2->host.len)) = foo;
676
+      if ( !nhost )
677
+         return -1;
678
+      memcpy( &(T->inbound_response->to.sin_addr) , &(nhost->h_addr) , nhost->h_length );
679
+      T->inbound_response->dest_ip         = htonl(T->inbound_response->to.sin_addr.s_addr);
680
+      T->inbound_response->dest_port      = ntohl(T->inbound_response->to.sin_port);
681
+      T->inbound_response->to.sin_family = AF_INET;
682
+   }
683
+
684
+   /*  */
685
+   // buf = build_message( p_mesg , &len );      TO DO!!
686
+   // T->inbound_request->bufflen     = len ;
687
+   // T->outbound_request[0]->buffer = (struct retans_buff*)sh_malloc( len );
688
+   // memcpy( T->inbound_request->buffer , buf , len );
689
+   // free( buf ) ;
658 690
 
691
+   /* make sure that if we send something final upstream, everything else will be cancelled */
692
+   if (T->outbound_response[branch]->first_line.u.reply.statusclass>=2 )
693
+      t_put_on_wait( p_msg );
659 694
 
695
+   t_retransmit_reply( p_msg );
696
+}
697
+
698
+
699
+
700
+
701
+/* Builds an ACK request based on an INVITE request. ACK is send
702
+  * to same address
703
+  */
704
+int t_build_and_send_ACK( struct cell *Trans, unsigned int branch)
705
+{
706
+    struct sip_msg* p_msg = T->inbound_request;
707
+    struct via_body *via;
708
+    struct hdr_field *hdr;
709
+   char *ack_buf, *p;
710
+    unsigned int len;
711
+
712
+   ack_buf = (char *)malloc( 1024 * 10 );
713
+   p = ack_buf;
714
+
715
+   /* first line */
716
+   memcpy( p , "ACK " , 4);
717
+   p += 4;
718
+   memcpy( p , p_msg->first_line.u.request.uri.s , p_msg->first_line.u.request.uri.len );
719
+   p += p_msg->first_line.u.request.uri.len+1;
720
+   *(p++)=' ';
721
+   memcpy( p , p_msg->first_line.u.request.version.s , p_msg->first_line.u.request.version.len );
722
+   p += p_msg->first_line.u.request.version.len;
723
+   *(p++) = '\n';
724
+
725
+   /* insert our via */
726
+   memcpy( p , "Via: SIP/2.0/UDP " , 17);
727
+   p += 17;
728
+   memcpy( p , names[0] , names_len[0] );
729
+   p += names_len[0];
730
+   *(p++) = ':';
731
+   memcpy( p , port_no_str , port_no_str_len );
732
+   p += port_no_str_len;
733
+
734
+   /* VIA (first we have to find the header) */
735
+   for( hdr=p_msg->headers ; hdr ; hdr=hdr->next  )
736
+      if ( hdr->type==HDR_VIA || hdr->type==HDR_FROM || hdr->type==HDR_CALLID )
737
+      {
738
+         len = (hdr->body.s+hdr->body.len) - hdr->name.s;
739
+         memcpy( p , p_msg->orig+(hdr->name.s-p_msg->buf) , len );
740
+         p += len;
741
+         *(p++) = '\n';
742
+      }
743
+      else if ( hdr->type==HDR_CSEQ )
744
+      {
745
+         len = (get_cseq(p_msg)->number.s+get_cseq(p_msg)->number.len) - hdr->name.s;
746
+         memcpy( p , p_msg->orig+(hdr->name.s-p_msg->buf) , len );
747
+         p += len;
748
+         memcpy( p , " ACK\n" , 5);
749
+         p += 5;
750
+      }
751
+      if ( hdr->type==HDR_TO )
752
+      {
753
+         len = (T->outbound_response[branch]->to->body.s+T->outbound_response[branch]->to->body.len) - T->outbound_response[branch]->to->name.s;
754
+         memcpy( p , T->outbound_response[branch]->orig+(T->outbound_response[branch]->to->name.s-T->outbound_response[branch]->buf) , len );
755
+         p += len;
756
+         *(p++) = '\n';
757
+      }
758
+
759
+   /* end of message*/
760
+   *(p++) = '\n';
761
+
762
+   /* sends the ACK message to the same destination as the INVITE */
763
+   send_udp_to( ack_buf, p-ack_buf, &(T->outbound_request[branch]->to) , sizeof(struct sockaddr_in) );
764
+
765
+   /* free mem*/
766
+   free( ack_buf );
767
+
768
+   return 0;
660 769
 }
661 770
 
662 771
 
... ...
@@ -3,7 +3,9 @@
3 3
 
4 4
 #include <errno.h>
5 5
 #include <netinet/in.h>
6
+#include <netdb.h>
6 7
 #include "../../msg_parser.h"
8
+#include "../../globals.h"
7 9
 
8 10
 struct s_table;
9 11
 struct timer;
... ...
@@ -66,7 +68,7 @@ int t_put_on_wait(  struct sip_msg  *p_msg  );
66 68
 
67 69
 /* Retransmits the last sent inbound reply.
68 70
   */
69
-int t_retransmit_reply( struct s_table * , struct sip_msg *  );
71
+int t_retransmit_reply( struct sip_msg *  );
70 72
 
71 73
 
72 74
 #endif