Module: sems Branch: master Commit: f803a7b28210b3eb02a0b0e2c3d281d6445bbb33 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sems/?a=commit;h=f803a7b28210b3eb02a0b0e2c3d281d6445bbb33
Author: Raphael Coeffic <[email protected]> Committer: Raphael Coeffic <[email protected]> Date: Thu Feb 2 18:30:13 2012 +0100 b/f: fixes send_reply() error handling on transport error. - fixed crash in send_reply when called a second time after a transport error for the same transaction. - the transaction timers are now first set after the message has been sent (safe as the bucket is locked). - TIMER_J is set if a transport error is triggered, so that the transaction is first removed after a while and request re-transmission can still be absorbed. --- core/sip/trans_layer.cpp | 55 ++++++++++++++++----------------------------- core/sip/trans_layer.h | 2 +- 2 files changed, 21 insertions(+), 36 deletions(-) diff --git a/core/sip/trans_layer.cpp b/core/sip/trans_layer.cpp index 83563da..2ae704f 100644 --- a/core/sip/trans_layer.cpp +++ b/core/sip/trans_layer.cpp @@ -131,6 +131,11 @@ int _trans_layer::send_reply(trans_ticket* tt, return -1; } + if(t->reply_status >= 200){ + ERROR("Transaction has already been closed with a final reply\n"); + return -1; + } + sip_msg* req = t->msg; assert(req); @@ -424,36 +429,27 @@ int _trans_layer::send_reply(trans_ticket* tt, local_socket = transports[out_interface]; } - err = update_uas_reply(bucket,t,reply_code); + err = local_socket->send(&remote_ip,reply_buf,reply_len); if(err < 0){ - - ERROR("Invalid state change\n"); delete [] reply_buf; + // set timer to capture retransmissions + // and delete transaction afterwards + t->reset_timer(STIMER_J,J_TIMER,bucket->get_id()); goto end; } - else if(err != TS_TERMINATED) { - if (t->retr_buf) - delete [] t->retr_buf; - t->retr_buf = reply_buf; - t->retr_len = reply_len; - memcpy(&t->retr_addr,&remote_ip,sizeof(sockaddr_storage)); - t->retr_socket = local_socket; - - err = 0; - } - else { - // Transaction has been deleted - // -> should not happen, as we - // now wait for 200 ACK - delete [] reply_buf; - err = 0; + if (t->retr_buf) { + // delete old retry-buffer + // before overwriting it + delete [] t->retr_buf; } - err = local_socket->send(&remote_ip,reply_buf,reply_len); - if(err < 0){ - delete [] reply_buf; - } + t->retr_buf = reply_buf; + t->retr_len = reply_len; + memcpy(&t->retr_addr,&remote_ip,sizeof(sockaddr_storage)); + t->retr_socket = local_socket; + + update_uas_reply(bucket,t,reply_code); end: bucket->unlock(); @@ -1538,15 +1534,10 @@ int _trans_layer::update_uac_request(trans_bucket* bucket, sip_trans*& t, sip_ms return 0; } -int _trans_layer::update_uas_reply(trans_bucket* bucket, sip_trans* t, int reply_code) +void _trans_layer::update_uas_reply(trans_bucket* bucket, sip_trans* t, int reply_code) { DBG("update_uas_reply(t=%p)\n", t); - if(t->reply_status >= 200){ - ERROR("Transaction has already been closed with a final reply\n"); - return -1; - } - t->reply_status = reply_code; if(t->reply_status >= 300){ @@ -1568,10 +1559,6 @@ int _trans_layer::update_uas_reply(trans_bucket* bucket, sip_trans* t, int reply if(t->msg->u.request->method == sip_request::INVITE){ // final reply - - //bucket->remove_trans(t); - //return TS_TERMINATED; - // // In this stack, the transaction layer // takes care of re-transmiting the 200 reply @@ -1602,8 +1589,6 @@ int _trans_layer::update_uas_reply(trans_bucket* bucket, sip_trans* t, int reply t->state = TS_PROCEEDING; } } - - return t->state; } int _trans_layer::update_uas_request(trans_bucket* bucket, sip_trans* t, sip_msg* msg) diff --git a/core/sip/trans_layer.h b/core/sip/trans_layer.h index 4462202..12d0e80 100644 --- a/core/sip/trans_layer.h +++ b/core/sip/trans_layer.h @@ -147,7 +147,7 @@ public: * Implements the state changes for the UAS state machine */ int update_uas_request(trans_bucket* bucket, sip_trans* t, sip_msg* msg); - int update_uas_reply(trans_bucket* bucket, sip_trans* t, int reply_code); + void update_uas_reply(trans_bucket* bucket, sip_trans* t, int reply_code); /** * Send ACK coresponding to error replies _______________________________________________ Semsdev mailing list [email protected] http://lists.iptel.org/mailman/listinfo/semsdev
