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

Reply via email to