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

Author: bpintea <[email protected]>
Committer: bpintea <[email protected]>
Date:   Mon Mar  7 01:51:06 2011 +0100

fix session leak on 100rel disabled

In case 100rel is disabled on SEMS' side, but UAC requires it, SEMS
would reject the INVITE, drop further processing on the session, but
still keep it. If INVITE is first in session, UAC would clear the
dialog, but SEMS would still keep it.

But spotted and explained by Stefan S.

---

 core/AmSession.cpp   |   15 +++++++++++----
 core/AmSipDialog.cpp |   16 +++++++---------
 core/AmSipDialog.h   |    6 ++++--
 core/AmSipHeaders.h  |    1 +
 4 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/core/AmSession.cpp b/core/AmSession.cpp
index 7963453..cb92abf 100644
--- a/core/AmSession.cpp
+++ b/core/AmSession.cpp
@@ -1216,16 +1216,23 @@ void 
AmSession::onFailure(AmSipDialogEventHandler::FailureCause cause,
     const AmSipRequest *req, const AmSipReply *rpl)
 {
   switch (cause) {
-    case FAIL_REL100:
+    case FAIL_REL100_421:
+    case FAIL_REL100_420:
       if (rpl) {
         dlg.cancel();
         if (dlg.getStatus() < AmSipDialog::Connected)
           setStopped();
       } else if (req) {
-          dlg.reply(*req, 421, "Extension Required", "", "",
+        if (cause == FAIL_REL100_421) {
+          dlg.reply(*req, 421, SIP_REPLY_EXTENSION_REQUIRED, "", "",
               SIP_HDR_COLSP(SIP_HDR_REQUIRE) SIP_EXT_100REL CRLF);
-          if (dlg.getStatus() < AmSipDialog::Connected)
-            setStopped();
+        } else {
+          dlg.reply(*req, 420, SIP_REPLY_BAD_EXTENSION, "", "",
+              SIP_HDR_COLSP(SIP_HDR_UNSUPPORTED) SIP_EXT_100REL CRLF);
+        }
+        /* finally, stop session if running */
+        if (dlg.getStatus() < AmSipDialog::Connected)
+          setStopped();
       }
       break;
     default:
diff --git a/core/AmSipDialog.cpp b/core/AmSipDialog.cpp
index 3a79d3a..fa73dc1 100644
--- a/core/AmSipDialog.cpp
+++ b/core/AmSipDialog.cpp
@@ -173,19 +173,17 @@ int AmSipDialog::rel100OnRequestIn(const AmSipRequest& 
req)
               SIP_EXT_100REL))) {
           ERROR("'" SIP_EXT_100REL "' extension required, but not advertised"
             " by peer.\n");
-          if (hdl) hdl->onFailure(FAIL_REL100, &req, 0);
+          if (hdl) hdl->onFailure(FAIL_REL100_421, &req, 0);
           return 0; // has been replied
         }
         break; // 100rel required
 
       case REL100_DISABLED:
         // TODO: shouldn't this be part of a more general check in SEMS?
-        if (key_in_list(getHeader(req.hdrs,SIP_HDR_REQUIRE),SIP_EXT_100REL))
-          reply_error(req, 420, SIP_REPLY_BAD_EXTENSION, 
-                     SIP_HDR_COLSP(SIP_HDR_UNSUPPORTED) SIP_EXT_100REL CRLF,
-                     next_hop_for_replies ? next_hop_ip : "",
-                     next_hop_for_replies ? next_hop_port : 0);
-       return 0;
+        if (key_in_list(getHeader(req.hdrs,SIP_HDR_REQUIRE),SIP_EXT_100REL)) {
+          if (hdl) hdl->onFailure(FAIL_REL100_420, &req, 0);
+          return 0; // has been replied
+        }
         break;
 
       default:
@@ -416,7 +414,7 @@ int AmSipDialog::rel100OnReplyIn(const AmSipReply &reply)
           !reply.rseq) {
         ERROR(SIP_EXT_100REL " not supported or no positive RSeq value in "
             "(reliable) 1xx.\n");
-        if (hdl) hdl->onFailure(FAIL_REL100, 0, &reply);
+        if (hdl) hdl->onFailure(FAIL_REL100_421, 0, &reply);
       } else {
         DBG(SIP_EXT_100REL " now active.\n");
         if (hdl) hdl->onInvite1xxRel(reply);
@@ -436,7 +434,7 @@ int AmSipDialog::rel100OnReplyIn(const AmSipReply &reply)
   } else if (reliable_1xx && reply.method==SIP_METH_PRACK) {
     if (300 <= reply.code) {
       // if PRACK fails, tear down session
-      if (hdl) hdl->onFailure(FAIL_REL100, 0, &reply);
+      if (hdl) hdl->onFailure(FAIL_REL100_421, 0, &reply);
     } else if (200 <= reply.code) {
       if (hdl) hdl->onPrack2xx(reply);
     } else {
diff --git a/core/AmSipDialog.h b/core/AmSipDialog.h
index 52f2a36..baceb2c 100644
--- a/core/AmSipDialog.h
+++ b/core/AmSipDialog.h
@@ -110,8 +110,10 @@ class AmSipDialogEventHandler
   virtual void onPrack2xx(const AmSipReply &)=0;
 
   enum FailureCause {
-    FAIL_REL100,
-#define FAIL_REL100  AmSipDialogEventHandler::FAIL_REL100
+    FAIL_REL100_421,
+#define FAIL_REL100_421  AmSipDialogEventHandler::FAIL_REL100_421
+    FAIL_REL100_420,
+#define FAIL_REL100_420  AmSipDialogEventHandler::FAIL_REL100_420
   };
   virtual void onFailure(FailureCause cause, const AmSipRequest*, 
       const AmSipReply*)=0;
diff --git a/core/AmSipHeaders.h b/core/AmSipHeaders.h
index 28ac91a..cb8543c 100644
--- a/core/AmSipHeaders.h
+++ b/core/AmSipHeaders.h
@@ -52,4 +52,5 @@
 
 #define SIP_REPLY_SERVER_INTERNAL_ERROR "Server Internal Error"
 #define SIP_REPLY_BAD_EXTENSION         "Bad Extension"
+#define SIP_REPLY_EXTENSION_REQUIRED    "Extension Required"
 #endif /* __AMSIPHEADERS_H__ */

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

Reply via email to