Module: sems
Branch: master
Commit: f50051ddf3cb9703bb9eeb5a056b66d03d26a230
URL:    
http://git.sip-router.org/cgi-bin/gitweb.cgi/sems/?a=commit;h=f50051ddf3cb9703bb9eeb5a056b66d03d26a230

Author: Raphael Coeffic <[email protected]>
Committer: Raphael Coeffic <[email protected]>
Date:   Fri Feb 25 15:19:17 2011 +0100

b/f: PRACK transaction matching.

PRACK should be first matched using normal transaction matching to identify 
retransmissions. Then, it can be matched against the original INVITE 
transaction to disable the re-transmission timers.

---

 core/sip/trans_layer.cpp |    8 ++--
 core/sip/trans_table.cpp |   99 ++++++++++++++++++++++++++-------------------
 core/sip/trans_table.h   |    5 ++-
 3 files changed, 65 insertions(+), 47 deletions(-)

diff --git a/core/sip/trans_layer.cpp b/core/sip/trans_layer.cpp
index 341230a..85fe929 100644
--- a/core/sip/trans_layer.cpp
+++ b/core/sip/trans_layer.cpp
@@ -1116,8 +1116,7 @@ void _trans_layer::received_msg(sip_msg* msg)
                    DBG("trans_layer::update_uas_trans() failed!\n");
                    // Anyway, there is nothing we can do...
                }
-               else if((err == TS_TERMINATED) ||
-                       (err == TS_REMOVED)){
+               else {
                
                    // do not touch the transaction anymore:
                    // it could have been deleted !!!
@@ -1129,7 +1128,8 @@ void _trans_layer::received_msg(sip_msg* msg)
                    //  the UA. 
                    assert(ua);
                    DBG("Passing ACK to the UA.\n");
-                   ua->handle_sip_request(trans_ticket(t,bucket),msg);
+                   ua->handle_sip_request(trans_ticket(), // dummy
+                                          msg);
                    
                    DROP_MSG;
                }
@@ -1161,7 +1161,7 @@ void _trans_layer::received_msg(sip_msg* msg)
                      inv_h = hash(msg->callid->value, get_rack(msg)->cseq_str);
                      inv_bucket = get_trans_bucket(inv_h);
                      inv_bucket->lock();
-                     if((inv_t = inv_bucket->match_request(msg)) != NULL) {
+                     if((inv_t = inv_bucket->match_1xx_prack(msg)) != NULL) {
                          assert(msg->u.request->method != 
                              inv_t->msg->u.request->method);
                          err = update_uas_request(inv_bucket,inv_t,msg);
diff --git a/core/sip/trans_table.cpp b/core/sip/trans_table.cpp
index 680685f..4ac6be4 100644
--- a/core/sip/trans_table.cpp
+++ b/core/sip/trans_table.cpp
@@ -98,14 +98,14 @@ sip_trans* trans_bucket::match_request(sip_msg* msg)
            }
 
            if(msg->u.request->method != (*it)->msg->u.request->method) {
-                if((*it)->msg->u.request->method == sip_request::INVITE) {
-                    if(msg->u.request->method == sip_request::ACK) {
-                        if ((t = match_200_ack(*it,msg)))
-                            break;
-                    } else if(msg->u.request->method == sip_request::PRACK) {
-                        if ((t = match_1xx_prack(*it,msg)))
-                            break;
-                    }
+
+               // ACK is the only request that should match an existing
+               // transaction without being a re-transmission
+                if( ((*it)->msg->u.request->method == sip_request::INVITE)
+                   && (msg->u.request->method == sip_request::ACK) 
+                   && (t = match_200_ack(*it,msg)) ){
+
+                   break;
                 }
                
                continue;
@@ -335,48 +335,63 @@ sip_trans* trans_bucket::match_200_ack(sip_trans* t, 
sip_msg* msg)
     return t;
 }
 
-sip_trans* trans_bucket::match_1xx_prack(sip_trans* t, sip_msg* msg)
+sip_trans* trans_bucket::match_1xx_prack(sip_msg* msg)
 {
-  /* first, check quickly if lenghts match (From tag, To tag, Call-ID) */
-
-  sip_from_to* from = dynamic_cast<sip_from_to*>(msg->from->p);
-  sip_from_to* t_from = dynamic_cast<sip_from_to*>(t->msg->from->p);
-  if(from->tag.len != t_from->tag.len)
-    return 0;
-
-  sip_from_to* to = dynamic_cast<sip_from_to*>(msg->to->p);
-  if(to->tag.len != t->to_tag.len)
-    return 0;
-
-  if(msg->callid->value.len != t->msg->callid->value.len)
-    return 0;
-
+    DBG("Matching %.*s request\n",
+       msg->u.request->method_str.len,
+       msg->u.request->method_str.s);
 
-  sip_rack *rack = dynamic_cast<sip_rack *>(msg->rack->p);
-  sip_cseq* t_cseq = dynamic_cast<sip_cseq*>(t->msg->cseq->p);
-  if (rack->cseq != t_cseq->num)
-    return 0;
+    if(elmts.empty())
+       return NULL;
+    
+    trans_list::iterator it = elmts.begin();
+    for(;it!=elmts.end();++it) {
+           
+       if( (*it)->msg->type != SIP_REQUEST ){
+           continue;
+       }
+       sip_trans* t = *it;
 
-  if (rack->rseq != t->last_rseq)
-    return 0;
+       /* first, check quickly if lenghts match (From tag, To tag, Call-ID) */
 
-  if (rack->method != t->msg->u.request->method)
-    return 0;
+       sip_from_to* from = dynamic_cast<sip_from_to*>(msg->from->p);
+       sip_from_to* t_from = dynamic_cast<sip_from_to*>(t->msg->from->p);
+       if(from->tag.len != t_from->tag.len)
+           continue;
 
+       sip_from_to* to = dynamic_cast<sip_from_to*>(msg->to->p);
+       if(to->tag.len != t->to_tag.len)
+           continue;
+       
+       if(msg->callid->value.len != t->msg->callid->value.len)
+           continue;
 
-  /* numbers fit, try content */
+       sip_rack *rack = dynamic_cast<sip_rack *>(msg->rack->p);
+       sip_cseq* t_cseq = dynamic_cast<sip_cseq*>(t->msg->cseq->p);
+       if (rack->cseq != t_cseq->num)
+           continue;
+       
+       if (rack->rseq != t->last_rseq)
+           continue;
+       
+       if (rack->method != t->msg->u.request->method)
+           continue;
+               
+       /* numbers fit, try content */
+       if(memcmp(from->tag.s,t_from->tag.s,from->tag.len))
+           continue;
+       
+       if(memcmp(msg->callid->value.s,t->msg->callid->value.s,
+                 msg->callid->value.len))
+           continue;
+       
+       if(memcmp(to->tag.s,t->to_tag.s,to->tag.len))
+           continue;
 
-  if(memcmp(from->tag.s,t_from->tag.s,from->tag.len))
-      return NULL;
+       return t;
+    }
 
-  if(memcmp(msg->callid->value.s,t->msg->callid->value.s,
-            msg->callid->value.len))
-      return NULL;
-  
-  if(memcmp(to->tag.s,t->to_tag.s,to->tag.len))
-      return NULL;
-  
-  return t;
+    return NULL;
 }
 
 sip_trans* trans_bucket::add_trans(sip_msg* msg, int ttype)
diff --git a/core/sip/trans_table.h b/core/sip/trans_table.h
index 08b1643..1c2e0ea 100644
--- a/core/sip/trans_table.h
+++ b/core/sip/trans_table.h
@@ -24,6 +24,10 @@ public:
     // in this bucket
     sip_trans* match_request(sip_msg* msg);
 
+    // Match a PRACK request against transactions
+    // in this bucket
+    sip_trans* match_1xx_prack(sip_msg* msg);
+
     // Match a reply to UAC transactions
     // in this bucket
     sip_trans* match_reply(sip_msg* msg);
@@ -32,7 +36,6 @@ public:
 
 private:
     sip_trans* match_200_ack(sip_trans* t,sip_msg* msg);
-    sip_trans* match_1xx_prack(sip_trans* t,sip_msg* msg);
 };
 
 trans_bucket* get_trans_bucket(const cstring& callid, const cstring& cseq_num);

_______________________________________________
Semsdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/semsdev

Reply via email to