This time WITH patch ;-)

-Raphael.

On 20.04.10 18:00, Raphael Coeffic wrote:
Gentlemen,

here is a patch implementing the outbound proxy (with "force" flag) at the AmSipDialog level following the "guidance of the bible" (RFC3261).

Though it is not tested, please have a close look at it (especially the code for AmSipDialog::send_request()) and tell me if this could satisfy your needs.

-Raphael.

PS: I haven't ported the code for the SIPRegistrarClient yet... please forgive me!

On 20.04.10 15:32, Juha Heinanen wrote:
Raphael Coeffic writes:

>  This means that the intended behavior is:
>    1. send the first request to the outbound proxy (if existing).
> 2. send subsequent requests using the route-set and standard behavior
>  (means: no outbound proxy there).
>
> Forcing the proxy is an option, but should definitely not be the default > behavior. At least not if we claim to have some level of compliance with
>  standards ;-)

raphael,

i agree that standard behavior is to follow route set, but for security
reasons, it makes sense to have an option for force ob also for inbound
requests.

-- juha


Index: apps/conference/Conference.cpp
===================================================================
--- apps/conference/Conference.cpp      (revision 1811)
+++ apps/conference/Conference.cpp      (working copy)
@@ -839,13 +839,13 @@
   // 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.route = get_header_keyvalue(iptel_app_param,"Transfer-RR");
     //dlg.next_hop = get_header_keyvalue(iptel_app_param,"Transfer-NH");
   } 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.route = getHeader(req.hdrs,"P-Transfer-RR");
     //dlg.next_hop = getHeader(req.hdrs,"P-Transfer-NH");
   }
 
Index: core/AmSipDialog.h
===================================================================
--- core/AmSipDialog.h  (revision 1811)
+++ core/AmSipDialog.h  (working copy)
@@ -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();
 
Index: core/AmSipDialog.cpp
===================================================================
--- core/AmSipDialog.cpp        (revision 1811)
+++ core/AmSipDialog.cpp        (working copy)
@@ -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;
   }
 
@@ -103,7 +104,9 @@
     remote_party = req.from;
     local_party  = req.to;
 
-    setRoute(req.route);
+    //setRoute(req.route);
+    route = req.route;
+
     //next_hop   = req.next_hop;
   }
 }
@@ -217,7 +220,8 @@
   if(status < Connected) {
 
     if(!reply.route.empty())
-      setRoute(reply.route);
+      //setRoute(reply.route);
+      route = reply.route;
 
     //next_hop = reply.next_hop;
   }
@@ -491,7 +495,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 +503,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 +524,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 +553,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 +576,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 + ", ";
+    }
+    req.route += route + CRLF;
+  }
+  else if (!local_tag.empty() && !remote_tag.empty() && 
!outbound_proxy.empty()) {
+    req.route = "Route: " + outbound_proxy + CRLF;
+  }
+
   if(!body.empty()) {
     req.content_type = content_type;
     req.body = body;
@@ -613,17 +608,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 +618,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 +673,7 @@
   }
 
   if(!route.empty())
-    req.route = getRoute();
+    req.route = route; //getRoute();
     
   if(!body.empty()) {
     req.content_type = content_type;
Index: core/sip/trans_layer.h
===================================================================
--- core/sip/trans_layer.h      (revision 1811)
+++ core/sip/trans_layer.h      (working copy)
@@ -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.
Index: core/sip/parse_header.cpp
===================================================================
--- core/sip/parse_header.cpp   (revision 1811)
+++ core/sip/parse_header.cpp   (working copy)
@@ -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)++){
Index: core/sip/trans_layer.cpp
===================================================================
--- core/sip/trans_layer.cpp    (revision 1811)
+++ core/sip/trans_layer.cpp    (working copy)
@@ -535,7 +535,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;
@@ -644,7 +644,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;
@@ -665,7 +665,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){
@@ -726,17 +727,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);
 
@@ -1032,7 +1042,7 @@
            }
            else {
                DBG("Found retransmission\n");
-               retransmit(t);
+               retransmit(t); // retransmit reply
            }
        }
        else {
Index: core/AmSipMsg.h
===================================================================
--- core/AmSipMsg.h     (revision 1811)
+++ core/AmSipMsg.h     (working copy)
@@ -11,7 +11,6 @@
 {
   public:
     string       method;
-    //string       next_hop; // URI
     string       route;
 
     string       contact;
Index: core/AmConfig.h
===================================================================
--- core/AmConfig.h     (revision 1811)
+++ core/AmConfig.h     (working copy)
@@ -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 */
Index: core/SipCtrlInterface.h
===================================================================
--- core/SipCtrlInterface.h     (revision 1811)
+++ core/SipCtrlInterface.h     (working copy)
@@ -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);
     
     /**
Index: core/AmConfig.cpp
===================================================================
--- core/AmConfig.cpp   (revision 1811)
+++ core/AmConfig.cpp   (working copy)
@@ -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");
Index: core/SipCtrlInterface.cpp
===================================================================
--- core/SipCtrlInterface.cpp   (revision 1811)
+++ core/SipCtrlInterface.cpp   (working copy)
@@ -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;
 
_______________________________________________
Semsdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/semsdev

Reply via email to