Author: rco
Date: 2010-04-22 16:27:20 +0200 (Thu, 22 Apr 2010)
New Revision: 1818

Modified:
   trunk/apps/conference/Conference.cpp
   trunk/core/AmConfig.cpp
   trunk/core/AmConfig.h
   trunk/core/AmSipDialog.cpp
   trunk/core/AmSipDialog.h
   trunk/core/AmSipMsg.h
   trunk/core/SipCtrlInterface.cpp
   trunk/core/SipCtrlInterface.h
   trunk/core/sip/parse_header.cpp
   trunk/core/sip/trans_layer.cpp
   trunk/core/sip/trans_layer.h
Log:
- simplified some code in the SIP stack
- introduced outbound_proxy+force_outbound_proxy at the SIP dialog level 
(AmSipDialog)
- outbound_proxy+force_outbound_proxy is configurable in the sems.conf


Modified: trunk/apps/conference/Conference.cpp
===================================================================
--- trunk/apps/conference/Conference.cpp        2010-04-22 14:01:50 UTC (rev 
1817)
+++ trunk/apps/conference/Conference.cpp        2010-04-22 14:27:20 UTC (rev 
1818)
@@ -839,14 +839,12 @@
   // get route set and next hop
   string iptel_app_param = getHeader(req.hdrs, PARAM_HDR);
   if (iptel_app_param.length()) {
-    dlg.setRoute(get_header_keyvalue(iptel_app_param,"Transfer-RR"));
-    //dlg.next_hop = get_header_keyvalue(iptel_app_param,"Transfer-NH");
+    dlg.route = get_header_keyvalue(iptel_app_param,"Transfer-RR");
   } else {
     INFO("Use of P-Transfer-RR/P-Transfer-NH is deprecated. "
         "Use '%s: Transfer-RR=<rr>;Transfer-NH=<nh>' instead.\n",PARAM_HDR);
 
-    dlg.setRoute(getHeader(req.hdrs,"P-Transfer-RR"));
-    //dlg.next_hop = getHeader(req.hdrs,"P-Transfer-NH");
+    dlg.route = getHeader(req.hdrs,"P-Transfer-RR");
   }
 
   DBG("ConferenceDialog::onSipRequest: local_party = 
%s\n",dlg.local_party.c_str());

Modified: trunk/core/AmConfig.cpp
===================================================================
--- trunk/core/AmConfig.cpp     2010-04-22 14:01:50 UTC (rev 1817)
+++ trunk/core/AmConfig.cpp     2010-04-22 14:27:20 UTC (rev 1818)
@@ -57,6 +57,7 @@
 int          AmConfig::LocalSIPPort            = 5060;
 string       AmConfig::LocalSIPIP              = "";
 string       AmConfig::OutboundProxy           = "";
+bool         AmConfig::ForceOutboundProxy      = false;
 string       AmConfig::Signature               = "";
 bool        AmConfig::SingleCodecInOK         = false;
 unsigned int AmConfig::DeadRtpTime             = DEAD_RTP_TIME;
@@ -218,6 +219,11 @@
   
   // outbound_proxy
   OutboundProxy = cfg.getParameter("outbound_proxy");
+
+  // force_outbound_proxy
+  if(cfg.hasParameter("force_outbound_proxy")) {
+    ForceOutboundProxy = (cfg.getParameter("force_outbound_proxy") == "yes");
+  }
   
   // plugin_path
   PlugInPath = cfg.getParameter("plugin_path");

Modified: trunk/core/AmConfig.h
===================================================================
--- trunk/core/AmConfig.h       2010-04-22 14:01:50 UTC (rev 1817)
+++ trunk/core/AmConfig.h       2010-04-22 14:27:20 UTC (rev 1818)
@@ -87,6 +87,8 @@
   static int LocalSIPPort;
   /** Outbound Proxy (optional, outgoing calls only) */
   static string OutboundProxy;
+  /** force Outbound Proxy to be used for in dialog requests */
+  static bool ForceOutboundProxy;
   /** Server/User-Agent header (optional) */
   static string Signature;
   /** If 200 OK reply should be limited to preferred codec only */

Modified: trunk/core/AmSipDialog.cpp
===================================================================
--- trunk/core/AmSipDialog.cpp  2010-04-22 14:01:50 UTC (rev 1817)
+++ trunk/core/AmSipDialog.cpp  2010-04-22 14:27:20 UTC (rev 1818)
@@ -41,7 +41,9 @@
 
 
 AmSipDialog::AmSipDialog(AmSipDialogEventHandler* h)
-  : status(Disconnected),cseq(10),hdl(h), serKeyLen(0)
+  : status(Disconnected),cseq(10),hdl(h),
+    outbound_proxy(AmConfig::OutboundProxy),
+    force_outbound_proxy(AmConfig::ForceOutboundProxy)
 {
 }
 
@@ -69,8 +71,7 @@
 
 void AmSipDialog::updateStatus(const AmSipRequest& req)
 {
-  if (req.method == "ACK") {
-    // || (req.method == "CANCEL")
+  if ((req.method == "ACK") || (req.method == "CANCEL")) {
     return;
   }
 
@@ -102,9 +103,7 @@
     local_uri    = req.r_uri;
     remote_party = req.from;
     local_party  = req.to;
-
-    setRoute(req.route);
-    //next_hop   = req.next_hop;
+    route        = req.route;
   }
 }
 
@@ -145,8 +144,6 @@
   DBG("reply: transaction found!\n");
     
   AmSipTransaction& t = t_it->second;
-
-  //t->reply_code = code;
   switch(status){
 
   case Disconnected:
@@ -202,24 +199,21 @@
   AmSipTransaction& t = t_it->second;
 
   // rfc3261 12.1
-  // && method==INVITE
   // Dialog established only by 101-199 or 2xx 
   // responses to INVITE
-  if ((reply.code >= 101) && (reply.code < 300) &&  
-      (remote_tag.empty() && !reply.remote_tag.empty()))
-    remote_tag = reply.remote_tag;
 
-  if ((reply.code >= 200) && (reply.code < 300) && 
-      (status != Connected && !reply.remote_tag.empty()))
+  if ( (reply.code > 100) 
+       && (reply.code < 300) 
+       && !reply.remote_tag.empty() 
+       && (remote_tag.empty() ||
+          ((status < Connected) && (reply.code >= 200))) ) {  
+
     remote_tag = reply.remote_tag;
+  }
 
   // allow route overwritting
-  if(status < Connected) {
-
-    if(!reply.route.empty())
-      setRoute(reply.route);
-
-    //next_hop = reply.next_hop;
+  if ((status < Connected) && !reply.route.empty()) {
+      route = reply.route;
   }
 
   if (reply.next_request_uri.length())
@@ -491,7 +485,7 @@
     string      hdrs = "";
     AmSipDialog tmp_d(*this);
                
-    tmp_d.setRoute("");
+    tmp_d.route = "";
     tmp_d.contact_uri = SIP_HDR_COLSP(SIP_HDR_CONTACT) 
       "<" + tmp_d.remote_uri + ">" CRLF;
     tmp_d.remote_uri = target;
@@ -499,14 +493,7 @@
     string r_set;
     if(!route.empty()){
                        
-      vector<string>::iterator it = route.begin();
-      r_set ="Transfer-RR=\"" + *it;
-                       
-      for(it++; it != route.end(); it++)
-       r_set += "," + *it;
-                       
-      r_set += "\"";
-      hdrs = PARAM_HDR ": " + r_set;
+      hdrs = PARAM_HDR ": " "Transfer-RR=\"" + route + "\"";
     }
                                
     int ret = tmp_d.sendRequest("REFER","","",hdrs);
@@ -527,22 +514,12 @@
 
 int AmSipDialog::cancel()
 {
-    
-    
     for(TransMap::reverse_iterator t = uac_trans.rbegin();
        t != uac_trans.rend(); t++) {
        
        if(t->second.method == "INVITE"){
-           
-           AmSipRequest req;
-           
-           req.method = "CANCEL";
-           req.callid = callid;
-           req.cseq = t->second.cseq;
-
-           req.tt = t->second.tt;
-
-           return SipCtrlInterface::send(req) ? 0 : -1;
+         
+         return SipCtrlInterface::cancel(&t->second.tt);
        }
     }
     
@@ -566,7 +543,6 @@
 
   req.method = method;
   req.r_uri = remote_uri;
-  //req.next_hop = next_hop;
 
   req.from = SIP_HDR_COLSP(SIP_HDR_FROM) + local_party;
   if(!local_tag.empty())
@@ -590,13 +566,22 @@
     if (AmConfig::Signature.length())
       req.hdrs += SIP_HDR_COLSP(SIP_HDR_USER_AGENT) + AmConfig::Signature + 
CRLF;
     
-    req.hdrs += SIP_HDR_COLSP(SIP_HDR_MAX_FORWARDS) /*TODO: 
configurable?!*/MAX_FORWARDS CRLF;
+    req.hdrs += SIP_HDR_COLSP(SIP_HDR_MAX_FORWARDS) /*TODO: configurable?!*/ 
MAX_FORWARDS CRLF;
 
   }
 
-  if(!route.empty())
-    req.route = getRoute();
-    
+  if(!route.empty()) {
+
+    req.route = "Route: ";
+    if(force_outbound_proxy){
+      req.route += "<" + outbound_proxy + ";lr>, ";
+    }
+    req.route += route + CRLF;
+  }
+  else if (remote_tag.empty() && !outbound_proxy.empty()) {
+    req.route = "Route: <" + outbound_proxy + ";lr>" CRLF;
+  }
+
   if(!body.empty()) {
     req.content_type = content_type;
     req.body = body;
@@ -613,17 +598,6 @@
   return 0;
 }
 
-
-// bool AmSipDialog::match_cancel(const AmSipRequest& cancel_req)
-// {
-//   TransMap::iterator t = uas_trans.find(cancel_req.cseq);
-
-//   if((t != uas_trans.end()) && (t->second.method == "INVITE"))
-//     return true;
-
-//   return false;
-// }
-
 string AmSipDialog::get_uac_trans_method(unsigned int cseq)
 {
   TransMap::iterator t = uac_trans.find(cseq);
@@ -634,39 +608,6 @@
   return "";
 }
 
-string AmSipDialog::getRoute()
-{
-  string r_set("");
-  for(vector<string>::iterator it = route.begin();
-      it != route.end(); it++) {
-    r_set += SIP_HDR_COLSP(SIP_HDR_ROUTE) + *it + CRLF;
-  }
-
-  return r_set;
-}
-
-void AmSipDialog::setRoute(const string& n_route)
-{
-  string m_route = n_route;
-  if(!m_route.empty() && (m_route.find("Route: ")!=string::npos))
-    m_route = m_route.substr(7/*sizeof("Route: ")*/);
-    
-  route.clear();
-  while(!m_route.empty()){
-       
-    string::size_type comma_pos;
-       
-    comma_pos = m_route.find(',');
-    //route += "Route: " + m_route.substr(0,comma_pos) + "\r\n";
-    route.push_back(m_route.substr(0,comma_pos));
-       
-    if(comma_pos != string::npos)
-      m_route = m_route.substr(comma_pos+1);
-    else
-      m_route = "";
-  }
-}
-
 int AmSipDialog::drop()
 {      
   status = Disconnected;
@@ -722,7 +663,7 @@
   }
 
   if(!route.empty())
-    req.route = getRoute();
+    req.route = route; //getRoute();
     
   if(!body.empty()) {
     req.content_type = content_type;

Modified: trunk/core/AmSipDialog.h
===================================================================
--- trunk/core/AmSipDialog.h    2010-04-22 14:01:50 UTC (rev 1817)
+++ trunk/core/AmSipDialog.h    2010-04-22 14:27:20 UTC (rev 1818)
@@ -100,7 +100,6 @@
   TransMap uac_trans;
 
   AmSipDialogEventHandler* hdl;
-  std::vector<string> route;        // record routing
 
   int updateStatusReply(const AmSipRequest& req, 
                        unsigned int code);
@@ -133,16 +132,12 @@
   string remote_party; // To/From
   string local_party;  // To/From
 
-  string getRoute(); // record routing
-  void   setRoute(const string& n_route);
+  string route;
+  string outbound_proxy;
+  bool   force_outbound_proxy;
 
-  //string next_hop;     // next_hop for t_uac_dlg
+  int    cseq; // Local CSeq for next request
 
-  int cseq;            // CSeq for next request
-
-  char serKey[MAX_SER_KEY_LEN];      // opaque string returned by SER, when 
staring a T
-  unsigned int serKeyLen;
-
   AmSipDialog(AmSipDialogEventHandler* h=0);
   ~AmSipDialog();
 
@@ -152,10 +147,11 @@
 
   void updateStatus(const AmSipRequest& req);
   void updateStatus(const AmSipReply& reply, bool do_200_ack=true);
+
   /** update Status from locally originated request (e.g. INVITE) */
   void updateStatusFromLocalRequest(const AmSipRequest& req);
 
-  int reply(const AmSipRequest& req, // Ser's transaction key
+  int reply(const AmSipRequest& req,
            unsigned int  code, 
            const string& reason,
            const string& content_type = "",
@@ -190,12 +186,6 @@
   int drop();
 
   /**
-   * @return true if a transaction could be found that
-   *              matches the CANCEL's one.
-   */
-  //bool match_cancel(const AmSipRequest& cancel_req);
-
-  /**
    * @return the method of the corresponding uac request
    */
   string get_uac_trans_method(unsigned int cseq);

Modified: trunk/core/AmSipMsg.h
===================================================================
--- trunk/core/AmSipMsg.h       2010-04-22 14:01:50 UTC (rev 1817)
+++ trunk/core/AmSipMsg.h       2010-04-22 14:27:20 UTC (rev 1818)
@@ -11,7 +11,6 @@
 {
   public:
     string       method;
-    //string       next_hop; // URI
     string       route;
 
     string       contact;

Modified: trunk/core/SipCtrlInterface.cpp
===================================================================
--- trunk/core/SipCtrlInterface.cpp     2010-04-22 14:01:50 UTC (rev 1817)
+++ trunk/core/SipCtrlInterface.cpp     2010-04-22 14:27:20 UTC (rev 1818)
@@ -127,16 +127,15 @@
     trans_layer::instance()->register_ua(this);
 }
 
-int SipCtrlInterface::cancel(AmSipRequest& req)
+int SipCtrlInterface::cancel(trans_ticket* tt)
 {
-    return trans_layer::instance()->cancel(&req.tt);
+    return trans_layer::instance()->cancel(tt);
 }
 
-
 int SipCtrlInterface::send(AmSipRequest &req)
 {
     if(req.method == "CANCEL")
-       return cancel(req);
+       return cancel(&req.tt);
 
     sip_msg* msg = new sip_msg();
     
@@ -152,7 +151,6 @@
     // CSeq
     // Contact
     // Max-Forwards
-
     
     char* c = (char*)req.from.c_str();
     int err = parse_headers(msg,&c);
@@ -175,7 +173,6 @@
     msg->callid = new sip_header(0,"Call-ID",stl2cstr(req.callid));
     msg->hdrs.push_back(msg->callid);
 
-
     if(!req.contact.empty()){
 
        c = (char*)req.contact.c_str();
@@ -189,37 +186,20 @@
     
     if(!req.route.empty()){
        
-       char *c = (char*)req.route.c_str();
+       c = (char*)req.route.c_str();
+       err = parse_headers(msg,&c);
        
-       err = parse_headers(msg,&c);
-       
        if(err){
            ERROR("Route headers parsing failed\n");
            ERROR("Faulty headers were: <%s>\n",req.route.c_str());
            delete msg;
            return -1;
        }
-
-       //
-       // parse_headers() appends our route headers 
-       // to msg->hdrs and msg->route. But we want
-       // only msg->route(), so we just remove the
-       // route headers at the end of msg->hdrs.
-       //
-       for(sip_header* h_rr = msg->hdrs.back();
-           !msg->hdrs.empty(); h_rr = msg->hdrs.back()) {
-           
-           if(h_rr->type != sip_header::H_ROUTE){
-               break;
-           }
-           
-           msg->hdrs.pop_back();
-       }
     }
 
     if(!req.hdrs.empty()) {
        
-       char *c = (char*)req.hdrs.c_str();
+       c = (char*)req.hdrs.c_str();
        
        err = parse_headers(msg,&c);
        
@@ -244,41 +224,6 @@
        }
     }
 
-    string next_hop;
-    unsigned int next_port_i = 0;
-
-//     if(!req.next_hop.empty()){
-//     string next_port;
-//     sip_uri parsed_uri;
-//     if (parse_uri(&parsed_uri, (char *)req.next_hop.c_str(),
-//                   req.next_hop.length()) < 0) {
-//         ERROR("invalid next hop URI '%s'\n", req.next_hop.c_str());
-//         ERROR("Using default outbound proxy");
-//         next_hop = SipCtrlInterface::outbound_host;
-//         next_port_i = SipCtrlInterface::outbound_port;
-//     } else {
-//         next_hop = c2stlstr(parsed_uri.host);
-//         if (parsed_uri.port) {
-//             next_port_i= parsed_uri.port;       }
-//         next_hop += *(c++);
-//     }
-//     }
-//    else 
-    if(!SipCtrlInterface::outbound_host.empty()){
-       next_hop = SipCtrlInterface::outbound_host;
-       next_port_i = SipCtrlInterface::outbound_port;
-    }
-
-    cstring c_next_hop = stl2cstr(next_hop);
-    
if(trans_layer::instance()->set_next_hop(msg->route,msg->u.request->ruri_str,
-                       c_next_hop,(unsigned short)next_port_i,
-                       &msg->remote_ip) < 0){
-
-       DBG("set_next_hop failed\n");
-       delete msg;
-       return -1;
-    }
-
     int res = trans_layer::instance()->send_request(msg,&req.tt);
     delete msg;
 

Modified: trunk/core/SipCtrlInterface.h
===================================================================
--- trunk/core/SipCtrlInterface.h       2010-04-22 14:01:50 UTC (rev 1817)
+++ trunk/core/SipCtrlInterface.h       2010-04-22 14:27:20 UTC (rev 1818)
@@ -38,17 +38,16 @@
 class AmSipRequest;
 class AmSipReply;
 
-class trans_layer;
-class trans_bucket;
 struct sip_msg;
 struct sip_header;
+class trans_ticket;
 
+
 class SipCtrlInterface:
     public sip_ua
 {
     void prepare_routes_uac(const list<sip_header*>& routes, string& 
route_field);
     void prepare_routes_uas(const list<sip_header*>& routes, string& 
route_field);
-    static int cancel(AmSipRequest& req);
 
     friend class udp_trsp;
 
@@ -68,10 +67,9 @@
 
     void run(const string& bind_addr, unsigned short bind_port);
     
-    /**
-     * From AmCtrlInterface
-     */
     static int send(AmSipRequest &req);
+    static int cancel(trans_ticket* tt);
+
     static int send(const AmSipReply &rep);
     
     /**

Modified: trunk/core/sip/parse_header.cpp
===================================================================
--- trunk/core/sip/parse_header.cpp     2010-04-22 14:01:50 UTC (rev 1817)
+++ trunk/core/sip/parse_header.cpp     2010-04-22 14:27:20 UTC (rev 1818)
@@ -282,8 +282,6 @@
     int saved_st = 0;
 
     char* begin = *c;
-    //bool  cr = false;
-
     auto_ptr<sip_header> hdr(new sip_header());
 
     for(;**c;(*c)++){

Modified: trunk/core/sip/trans_layer.cpp
===================================================================
--- trunk/core/sip/trans_layer.cpp      2010-04-22 14:01:50 UTC (rev 1817)
+++ trunk/core/sip/trans_layer.cpp      2010-04-22 14:27:20 UTC (rev 1818)
@@ -539,7 +539,7 @@
 //
 int trans_layer::set_next_hop(list<sip_header*>& route_hdrs, 
                              cstring& r_uri, cstring& next_hop,
-                             unsigned short next_port,
+                             unsigned short& next_port,
                              sockaddr_storage* remote_ip)
 {
     int err=0;
@@ -648,7 +648,7 @@
            case RR_PARAMS:
                // remove current route header from message
                DBG("delete (fr=0x%p)\n",fr);
-               delete fr; // route_hdrs.front();
+               delete fr;
                route_hdrs.pop_front();
                DBG("route_hdrs.length() = %i\n",(int)route_hdrs.size());
                break;
@@ -669,7 +669,8 @@
        }
        
     }
-    else if (next_hop.len == 0) {
+    else {
+
        sip_uri parsed_r_uri;
        err = parse_uri(&parsed_r_uri,r_uri.s,r_uri.len);
        if(err < 0){
@@ -730,17 +731,26 @@
     // Contact
     // Supported / Require
     // Content-Length / Content-Type
-    
+
     assert(transport);
     assert(msg);
     assert(tt);
 
+    cstring        next_hop;
+    unsigned short next_port = 0;
+
     tt->_bucket = 0;
     tt->_t = 0;
 
-    // assume that msg->route headers are not in msg->hdrs
-    msg->hdrs.insert(msg->hdrs.begin(),msg->route.begin(),msg->route.end());
+    
if(trans_layer::instance()->set_next_hop(msg->route,msg->u.request->ruri_str,
+                       next_hop,next_port,
+                       &msg->remote_ip) < 0){
 
+       DBG("set_next_hop failed\n");
+       delete msg;
+       return -1;
+    }
+    
     int request_len = request_line_len(msg->u.request->method_str,
                                       msg->u.request->ruri_str);
 
@@ -1036,7 +1046,7 @@
            }
            else {
                DBG("Found retransmission\n");
-               retransmit(t);
+               retransmit(t); // retransmit reply
            }
        }
        else {

Modified: trunk/core/sip/trans_layer.h
===================================================================
--- trunk/core/sip/trans_layer.h        2010-04-22 14:01:50 UTC (rev 1817)
+++ trunk/core/sip/trans_layer.h        2010-04-22 14:27:20 UTC (rev 1818)
@@ -97,12 +97,12 @@
     int update_uas_reply(trans_bucket* bucket, sip_trans* t, int reply_code);
 
     /**
-     * Retransmits reply / non-200 ACK (if possible).
+     * Retransmits the content of the retry buffer (replies or non-200 ACK).
      */
     void retransmit(sip_trans* t);
 
     /**
-     * Retransmits a message (mostly the first UAC request).
+     * Retransmits a message (UAC requests).
      */
     void retransmit(sip_msg* msg);
 
@@ -120,6 +120,14 @@
     int send_sl_reply(sip_msg* req, int reply_code, 
                      const cstring& reason, 
                      const cstring& hdrs, const cstring& body);
+
+    /**
+     * Fills the address structure passed and modifies 
+     * R-URI and Route headers as needed.
+     */
+    int set_next_hop(list<sip_header*>& route_hdrs, cstring& r_uri, 
+                    cstring& next_hop, unsigned short& next_port,
+                    sockaddr_storage* remote_ip);
     
     /**
      * Transaction timeout
@@ -180,14 +188,6 @@
     void received_msg(sip_msg* msg);
 
     /**
-     * Fills the address structure passed and modifies 
-     * R-URI and Route headers as needed.
-     */
-    int set_next_hop(list<sip_header*>& route_hdrs, cstring& r_uri, 
-                    cstring& next_hop, unsigned short next_port,
-                    sockaddr_storage* remote_ip);
-
-    /**
      * This is called by the transaction timer callback.
      * At this place, the bucket is already locked, so
      * please be quick.

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

Reply via email to