|
@@ -12,125 +12,6 @@
|
|
|
#include "../../ut.h"
|
|
|
#include "../../timer.h"
|
|
|
|
|
|
-#ifndef SRL
|
|
|
-/* This function is called whenever a reply for our module is received;
|
|
|
- * we need to register this function on module initialization;
|
|
|
- * Returns : 0 - core router stops
|
|
|
- * 1 - core router relay statelessly
|
|
|
- */
|
|
|
-int t_on_reply_received( struct sip_msg *p_msg )
|
|
|
-{
|
|
|
- unsigned int branch,len, msg_status, msg_class, save_clone;
|
|
|
- unsigned int local_cancel;
|
|
|
- struct sip_msg *clone, *backup;
|
|
|
- int relay;
|
|
|
- int start_fr;
|
|
|
- int is_invite;
|
|
|
- struct retrans_buff *rb;
|
|
|
-
|
|
|
-
|
|
|
- /* make sure we know the assosociated tranaction ... */
|
|
|
- if (t_check( p_msg , &branch , &local_cancel)==-1) return 1;
|
|
|
- /* ... if there is no such, tell the core router to forward statelessly */
|
|
|
- if ( T<=0 ) return 1;
|
|
|
-
|
|
|
- DBG("DEBUG: t_on_reply_received: Original status=%d (%d,%d)\n",
|
|
|
- T->status,branch,local_cancel);
|
|
|
-
|
|
|
- /* special cases (local cancel reply and another 100 reply!)*/
|
|
|
- if (p_msg->REPLY_STATUS==100 && T->status==100)
|
|
|
- return 0;
|
|
|
- if (local_cancel==1)
|
|
|
- {
|
|
|
- reset_timer( hash_table, &(T_>outbound_cancel[branch]->retr_timer));
|
|
|
- if ( p_msg->REPLY_STATUS>=200 )
|
|
|
- reset_timer( hash_table, &(T_>outbound_cancel[branch]->fr_timer));
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- /* it can take quite long -- better do it now than later
|
|
|
- inside a reply_lock */
|
|
|
- if (!(clone=sip_msg_cloner( p_msg ))) {
|
|
|
- goto error;
|
|
|
- }
|
|
|
- msg_status=p_msg->REPLY_STATUS;
|
|
|
- msg_class=REPLY_CLASS(p_msg);
|
|
|
- is_invite= T->inbound_request->REQ_METHOD==METHOD_INVITE;
|
|
|
-
|
|
|
- /* *** stop timers *** */
|
|
|
- rb=T->outbound_request[branch];
|
|
|
- /* stop retransmission */
|
|
|
- reset_timer( hash_table, &(rb->retr_timer));
|
|
|
- /* stop final response timer only if I got a final response */
|
|
|
- if ( msg_class>1 )
|
|
|
- reset_timer( hash_table, &(rb->fr_timer));
|
|
|
-
|
|
|
- LOCK_REPLIES( T );
|
|
|
- /* if a got the first prov. response for an INVITE ->
|
|
|
- change FR_TIME_OUT to INV_FR_TIME_UT */
|
|
|
- start_fr = !T->inbound_response[branch] && msg_class==1 && is_invite;
|
|
|
-
|
|
|
- /* *** store and relay message as needed *** */
|
|
|
- relay = t_should_relay_response( T , msg_status, branch, &save_clone );
|
|
|
-
|
|
|
- if (save_clone) {
|
|
|
- /* release previously hold message */
|
|
|
- backup = T->inbound_response[branch];
|
|
|
- T->inbound_response[branch] = clone;
|
|
|
- T->tag=&(get_to(clone)->tag_value);
|
|
|
- } else {
|
|
|
- backup = NULL;
|
|
|
- sip_msg_free( clone );
|
|
|
- }
|
|
|
-
|
|
|
- if (relay>=0 &&
|
|
|
- push_reply_from_uac_to_uas( T, relay ) == -1 ) {
|
|
|
- /* restore original state first */
|
|
|
- if (save_clone) T->inbound_response[branch] = backup;
|
|
|
- /* restart FR */
|
|
|
- start_fr=1;
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /* *** ACK handling *** */
|
|
|
- if ( is_invite )
|
|
|
- {
|
|
|
- if ( T->outbound_ack[branch] )
|
|
|
- { /*retransmit*/
|
|
|
- SEND_BUFFER( T->outbound_ack[branch] );
|
|
|
- }else if (msg_class>2 ) {
|
|
|
- /*on a non-200 reply to INVITE*/
|
|
|
- DBG("DEBUG: t_on_reply_received: >=3xx reply to INVITE:"
|
|
|
- " send ACK\n");
|
|
|
- if ( t_build_and_send_ACK( T , branch , p_msg )==-1)
|
|
|
- {
|
|
|
- LOG( L_ERR , "ERROR: t_on_reply_received:"
|
|
|
- " unable to send ACK\n" );
|
|
|
- /* restart FR */
|
|
|
- start_fr=1;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-cleanup:
|
|
|
- UNLOCK_REPLIES( T );
|
|
|
- if (backup) sip_msg_free(backup);
|
|
|
- if (start_fr) set_timer( hash_table, &(rb->fr_timer), FR_INV_TIMER_LIST );
|
|
|
- /* restart retransmission if a provisional response came for
|
|
|
- a non_INVITE -> retrasmit at RT_T2*/
|
|
|
- if ( msg_class==1 && !is_invite )
|
|
|
- {
|
|
|
- rb->retr_list = RT_T2;
|
|
|
- set_timer( hash_table, &(rb->retr_timer), RT_T2 );
|
|
|
- }
|
|
|
-error:
|
|
|
- T_UNREF( T );
|
|
|
- /* don't try to relay statelessly on error; on troubles, simply do nothing;
|
|
|
- that will make the other party to retransmit; hopefuly, we'll then
|
|
|
- be better off */
|
|
|
- return 0;
|
|
|
-}
|
|
|
-#endif
|
|
|
|
|
|
|
|
|
|
|
@@ -142,13 +23,10 @@ error:
|
|
|
int t_retransmit_reply( /* struct sip_msg* p_msg */ )
|
|
|
{
|
|
|
|
|
|
-#ifdef SRL
|
|
|
void *b;
|
|
|
int len;
|
|
|
-#endif
|
|
|
- LOCK_REPLIES( T );
|
|
|
|
|
|
-#ifdef SRL
|
|
|
+ LOCK_REPLIES( T );
|
|
|
len=T->outbound_response.bufflen;
|
|
|
b=pkg_malloc( len );
|
|
|
if (!b) {
|
|
@@ -156,15 +34,10 @@ int t_retransmit_reply( /* struct sip_msg* p_msg */ )
|
|
|
return -1;
|
|
|
}
|
|
|
memcpy( b, T->outbound_response.retr_buffer, len );
|
|
|
-#else
|
|
|
- SEND_BUFFER( & T->outbound_response );
|
|
|
-#endif
|
|
|
UNLOCK_REPLIES( T );
|
|
|
|
|
|
-#ifdef SRL
|
|
|
SEND_PR_BUFFER( & T->outbound_response, b, len );
|
|
|
pkg_free( b );
|
|
|
-#endif
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
@@ -226,18 +99,12 @@ int t_send_reply( struct sip_msg* p_msg , unsigned int code , char * text )
|
|
|
rb->bufflen = len ;
|
|
|
memcpy( rb->retr_buffer , buf , len );
|
|
|
T->status = code;
|
|
|
-#ifndef SRL
|
|
|
- SEND_BUFFER( rb );
|
|
|
-#endif
|
|
|
/* needs to be protected too because what timers are set depends
|
|
|
- on current transactions status
|
|
|
- */
|
|
|
+ on current transactions status */
|
|
|
t_update_timers_after_sending_reply( rb );
|
|
|
UNLOCK_REPLIES( T );
|
|
|
|
|
|
-#ifdef SRL
|
|
|
SEND_PR_BUFFER( rb, buf, len );
|
|
|
-#endif
|
|
|
|
|
|
free( buf ) ;
|
|
|
/* start/stops the proper timers*/
|
|
@@ -256,20 +123,12 @@ error:
|
|
|
|
|
|
|
|
|
/* Push a previously stored reply from UA Client to UA Server
|
|
|
- * and send it out
|
|
|
- */
|
|
|
-static int push_reply_from_uac_to_uas( struct cell* trans , unsigned int branch
|
|
|
-#ifdef SRL
|
|
|
- , char *buf, unsigned int len
|
|
|
-#endif
|
|
|
- )
|
|
|
+ * and send it out */
|
|
|
+static int push_reply( struct cell* trans , unsigned int branch ,
|
|
|
+ char *buf, unsigned int len)
|
|
|
{
|
|
|
unsigned int buf_len;
|
|
|
struct retrans_buff *rb;
|
|
|
-#ifndef SRL
|
|
|
- char *buf;
|
|
|
- unsigned int len;
|
|
|
-#endif
|
|
|
|
|
|
DBG("DEBUG: push_reply_from_uac_to_uas: start\n");
|
|
|
rb= & trans->outbound_response;
|
|
@@ -291,23 +150,7 @@ static int push_reply_from_uac_to_uas( struct cell* trans , unsigned int branch
|
|
|
rb->to.sin_family = AF_INET;
|
|
|
rb->my_T = trans;
|
|
|
rb->status = trans->inbound_response[branch]->REPLY_STATUS;
|
|
|
-
|
|
|
- } else {
|
|
|
-#ifndef SRL
|
|
|
- reset_timer( hash_table, &(rb->retr_timer));
|
|
|
- reset_timer( hash_table, &(rb->fr_timer));
|
|
|
-#endif
|
|
|
- }
|
|
|
-
|
|
|
-#ifndef SRL
|
|
|
- /* generate the retrans buffer */
|
|
|
- buf = build_res_buf_from_sip_res ( trans->inbound_response[branch], &len);
|
|
|
- if (!buf) {
|
|
|
- LOG(L_ERR, "ERROR: push_reply_from_uac_to_uas: "
|
|
|
- "no shmem for outbound reply buffer\n");
|
|
|
- goto error;
|
|
|
- }
|
|
|
-#endif
|
|
|
+ };
|
|
|
|
|
|
/* if this is a first reply (?100), longer replies will probably follow;
|
|
|
try avoiding shm_resize by higher buffer size */
|
|
@@ -319,9 +162,6 @@ static int push_reply_from_uac_to_uas( struct cell* trans , unsigned int branch
|
|
|
}
|
|
|
rb->bufflen = len ;
|
|
|
memcpy( rb->retr_buffer , buf , len );
|
|
|
-#ifndef SRL
|
|
|
- free( buf ) ;
|
|
|
-#endif
|
|
|
|
|
|
/* update the status*/
|
|
|
trans->status = trans->inbound_response[branch]->REPLY_STATUS;
|
|
@@ -333,85 +173,18 @@ static int push_reply_from_uac_to_uas( struct cell* trans , unsigned int branch
|
|
|
trans->relaied_reply_branch = branch;
|
|
|
}
|
|
|
|
|
|
-#ifndef SRL
|
|
|
- /* start/stops the proper timers*/
|
|
|
- t_update_timers_after_sending_reply( rb );
|
|
|
-#endif
|
|
|
-
|
|
|
/*send the reply*/
|
|
|
SEND_BUFFER( rb );
|
|
|
return 1;
|
|
|
|
|
|
error1:
|
|
|
-#ifndef SRL
|
|
|
- free( buf );
|
|
|
-#endif
|
|
|
error:
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
-/* Push a previously stored reply from UA Client to UA Server
|
|
|
- * and send it out
|
|
|
- */
|
|
|
-static int push_reply( struct cell* trans , unsigned int branch ,
|
|
|
- char *buf, unsigned int len)
|
|
|
-{
|
|
|
- unsigned int buf_len;
|
|
|
- struct retrans_buff *rb;
|
|
|
-
|
|
|
- DBG("DEBUG: push_reply_from_uac_to_uas: start\n");
|
|
|
- rb= & trans->outbound_response;
|
|
|
- /* if there is a reply, release the buffer (everything else stays same) */
|
|
|
- if ( ! rb->retr_buffer ) {
|
|
|
- /*init retrans buffer*/
|
|
|
- memset( rb , 0 , sizeof (struct retrans_buff) );
|
|
|
- if (update_sock_struct_from_via( &(rb->to),
|
|
|
- trans->inbound_response[branch]->via2 )==-1) {
|
|
|
- LOG(L_ERR, "ERROR: push_reply_from_uac_to_uas: "
|
|
|
- "cannot lookup reply dst: %s\n",
|
|
|
- trans->inbound_response[branch]->via2->host.s );
|
|
|
- goto error;
|
|
|
- }
|
|
|
- rb->retr_timer.tg=TG_RT;
|
|
|
- rb->fr_timer.tg=TG_FR;
|
|
|
- rb->retr_timer.payload = rb;
|
|
|
- rb->fr_timer.payload = rb;
|
|
|
- rb->to.sin_family = AF_INET;
|
|
|
- rb->my_T = trans;
|
|
|
- rb->status = trans->inbound_response[branch]->REPLY_STATUS;
|
|
|
- };
|
|
|
-
|
|
|
- /* if this is a first reply (?100), longer replies will probably follow;
|
|
|
- try avoiding shm_resize by higher buffer size */
|
|
|
- buf_len = rb->retr_buffer ? len : len + REPLY_OVERBUFFER_LEN;
|
|
|
- if (! (rb->retr_buffer = (char*)shm_resize( rb->retr_buffer, buf_len )))
|
|
|
- {
|
|
|
- LOG(L_ERR, "ERROR: t_push: cannot allocate shmem buffer\n");
|
|
|
- goto error1;
|
|
|
- }
|
|
|
- rb->bufflen = len ;
|
|
|
- memcpy( rb->retr_buffer , buf , len );
|
|
|
-
|
|
|
- /* update the status*/
|
|
|
- trans->status = trans->inbound_response[branch]->REPLY_STATUS;
|
|
|
- if ( trans->inbound_response[branch]->REPLY_STATUS>=200 &&
|
|
|
- trans->relaied_reply_branch==-1 ) {
|
|
|
-
|
|
|
- memcpy( & trans->ack_to, & trans->outbound_request[ branch ]->to,
|
|
|
- sizeof( struct sockaddr_in ) );
|
|
|
- trans->relaied_reply_branch = branch;
|
|
|
- }
|
|
|
|
|
|
- /*send the reply*/
|
|
|
- SEND_BUFFER( rb );
|
|
|
- return 1;
|
|
|
|
|
|
-error1:
|
|
|
-error:
|
|
|
- return -1;
|
|
|
-}
|
|
|
|
|
|
-#ifdef SRL
|
|
|
/* This function is called whenever a reply for our module is received;
|
|
|
* we need to register this function on module initialization;
|
|
|
* Returns : 0 - core router stops
|
|
@@ -623,4 +396,3 @@ error:
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-#endif
|