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

Author: Václav Kubart <[email protected]>
Committer: Václav Kubart <[email protected]>
Date:   Wed Feb 22 11:54:49 2012 +0100

AmB2BSession: quick fix to generate more appropriate SIP error code

fixes bug #71
https://bugtracker.iptel.org/view.php?id=71

Introduced solution is rather a hack and should be replaced by more
sophisticated error propagation mechanism. This would probably change a lot of
code and should be done in 1.6.

---

 core/AmB2BSession.cpp    |   34 +++++++++++++++++++++++++---------
 core/AmSipDialog.cpp     |   11 ++++++-----
 core/sip/trans_layer.cpp |    7 ++++---
 3 files changed, 35 insertions(+), 17 deletions(-)

diff --git a/core/AmB2BSession.cpp b/core/AmB2BSession.cpp
index 54e355e..f2f74aa 100644
--- a/core/AmB2BSession.cpp
+++ b/core/AmB2BSession.cpp
@@ -49,6 +49,23 @@ static void countStreams(const AmSdp &sdp, int &active, int 
&inactive)
   }
 }
 
+static void errCode2RelayedReply(AmSipReply &reply, int err_code, unsigned 
default_code = 500)
+{
+  // FIXME: use cleaner method to propagate error codes/reasons, 
+  // do it everywhere in the code
+  if ((err_code < -399) && (err_code > -700)) {
+    reply.code = -err_code;
+  }
+  else reply.code = default_code;
+
+  // TODO: optimize with a table
+  switch (reply.code) {
+    case 400: reply.reason = "Bad Request"; break;
+    case 478: reply.reason = "Unresolvable destination"; break;
+    default: reply.reason = SIP_REPLY_SERVER_INTERNAL_ERROR;
+  }
+}
+
 //
 // AmB2BSession methods
 //
@@ -144,11 +161,11 @@ void AmB2BSession::onB2BEvent(B2BEvent* ev)
          return;
        }
 
-       if(relaySip(req_ev->req) < 0) {
+        int res = relaySip(req_ev->req);
+       if(res < 0) {
          // reply relayed request internally
          AmSipReply n_reply;
-         n_reply.code = 500;
-         n_reply.reason = SIP_REPLY_SERVER_INTERNAL_ERROR;
+          errCode2RelayedReply(n_reply, res, 500);
          n_reply.cseq = req_ev->req.cseq;
          n_reply.from_tag = dlg.local_tag;
          relayEvent(new B2BSipReplyEvent(n_reply, true, req_ev->req.method));
@@ -1292,14 +1309,13 @@ void AmB2BCalleeSession::onB2BEvent(B2BEvent* ev)
       }
     }
 
-    if (dlg.sendRequest(SIP_METH_INVITE,
+    int res = dlg.sendRequest(SIP_METH_INVITE,
                        co_ev->content_type, *body,
-                       co_ev->hdrs, SIP_FLAGS_VERBATIM) < 0) {
-
-      DBG("sending INVITE failed, relaying back 400 Bad Request\n");
+                       co_ev->hdrs, SIP_FLAGS_VERBATIM);
+    if (res < 0) {
+      DBG("sending INVITE failed, relaying back error reply\n");
       AmSipReply n_reply;
-      n_reply.code = 400;
-      n_reply.reason = "Bad Request";
+      errCode2RelayedReply(n_reply, res, 400);
       n_reply.cseq = co_ev->r_cseq;
       n_reply.from_tag = dlg.local_tag;
       relayEvent(new B2BSipReplyEvent(n_reply, co_ev->relayed_invite, 
SIP_METH_INVITE));
diff --git a/core/AmSipDialog.cpp b/core/AmSipDialog.cpp
index 2ef5b2c..f3dcb2e 100644
--- a/core/AmSipDialog.cpp
+++ b/core/AmSipDialog.cpp
@@ -754,7 +754,6 @@ int AmSipDialog::reply(const AmSipTransaction& t,
   }
 
   int ret = SipCtrlInterface::send(reply);
-
   if(ret){
     ERROR("Could not send reply: code=%i; reason='%s'; method=%s; call-id=%s; 
cseq=%i\n",
          reply.code,reply.reason.c_str(),reply.cseq_method.c_str(),
@@ -1097,10 +1096,11 @@ int AmSipDialog::sendRequest(const string& method,
     hdl->onSendRequest(req,flags);
 
   onTxRequest(req);
-  if(SipCtrlInterface::send(req, next_hop_ip, 
next_hop_port,outbound_interface)) {
+  int res = SipCtrlInterface::send(req, next_hop_ip, 
next_hop_port,outbound_interface);
+  if(res) {
     ERROR("Could not send request: method=%s; call-id=%s; cseq=%i\n",
          req.method.c_str(),req.callid.c_str(),req.cseq);
-    return -1;
+    return res;
   }
  
   if(method != SIP_METH_ACK) {
@@ -1180,8 +1180,9 @@ int AmSipDialog::send_200_ack(unsigned int inv_cseq,
     hdl->onSendRequest(req,flags);
 
   //onTxRequest(req); // not needed right now in the ACK case
-  if (SipCtrlInterface::send(req, next_hop_ip, next_hop_port, 
outbound_interface))
-    return -1;
+  int res = SipCtrlInterface::send(req, next_hop_ip, next_hop_port, 
outbound_interface);
+  if (res)
+    return res;
 
   uac_trans.erase(inv_cseq);
   if (offeranswer_enabled) {
diff --git a/core/sip/trans_layer.cpp b/core/sip/trans_layer.cpp
index b3f6c3c..83d322e 100644
--- a/core/sip/trans_layer.cpp
+++ b/core/sip/trans_layer.cpp
@@ -743,7 +743,7 @@ int _trans_layer::set_destination_ip(sip_msg* msg, cstring* 
next_hop, unsigned s
                                                     &(msg->remote_ip),IPv4);
        if(err < 0){
            ERROR("Unresolvable Request URI domain\n");
-           return -1;
+           return -478;
        }
     }
 
@@ -849,9 +849,10 @@ int _trans_layer::send_request(sip_msg* msg, trans_ticket* 
tt,
     string uri_buffer; // must have the same scope as 'msg'
     prepare_strict_routing(msg,uri_buffer);
 
-    if(set_destination_ip(msg,&next_hop,next_port) < 0){
+    int res = set_destination_ip(msg,&next_hop,next_port);
+    if(res < 0){
        DBG("set_destination_ip failed\n");
-       return -1;
+       return res;
     }
 
     // rco: should we overwrite the socket from the request in all cases???

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

Reply via email to