... | ... |
@@ -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 |