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

Author: Raphael Coeffic <[email protected]>
Committer: Raphael Coeffic <[email protected]>
Date:   Fri Feb  3 20:50:40 2012 +0100

core: added force_via_address interface option.

---

 core/AmConfig.cpp         |   18 ++++++++++++++++++
 core/AmConfig.h           |    3 +++
 core/SipCtrlInterface.cpp |    3 ++-
 core/sip/trans_layer.cpp  |   24 +++++++++++++++++-------
 core/sip/transport.cpp    |   11 ++++++++---
 core/sip/transport.h      |   14 +++++++++++++-
 core/sip/udp_trsp.h       |    4 +++-
 7 files changed, 64 insertions(+), 13 deletions(-)

diff --git a/core/AmConfig.cpp b/core/AmConfig.cpp
index 561a0bd..19bc4f3 100644
--- a/core/AmConfig.cpp
+++ b/core/AmConfig.cpp
@@ -42,6 +42,7 @@
 #include "AmUtils.h"
 #include "AmSession.h"
 #include "Am100rel.h"
+#include "sip/transport.h"
 
 #include <cctype>
 #include <algorithm>
@@ -126,6 +127,7 @@ AmConfig::IP_interface::IP_interface()
     PublicIP(),
     RtpLowPort(RTP_LOWPORT),
     RtpHighPort(RTP_HIGHPORT),
+    SigSockOpts(0),
     next_rtp_port(-1)
 {
 }
@@ -641,6 +643,22 @@ static int readInterface(AmConfigReader& cfg, const 
string& i_name)
     }
   }
 
+  if(cfg.hasParameter("sig_sock_opts" + suffix)){
+    vector<string> opt_strs = explode(cfg.getParameter("sig_sock_opts" + 
suffix),",");
+    unsigned int opts = 0;
+    for(vector<string>::iterator it_opt = opt_strs.begin();
+       it_opt != opt_strs.end(); ++it_opt) {
+      if(*it_opt == "force_via_address") {
+       opts |= trsp_socket::force_via_address;
+      }
+      else {
+       WARN("unknown signaling socket option '%s' set on interface '%s'\n",
+            it_opt->c_str(),i_name.c_str());
+      }
+    }
+    intf.SigSockOpts = opts;
+  }
+
   intf.name = i_name;
 
   if(!suffix.empty()) {// !default Interface
diff --git a/core/AmConfig.h b/core/AmConfig.h
index 16d91d2..009ec3e 100644
--- a/core/AmConfig.h
+++ b/core/AmConfig.h
@@ -99,6 +99,9 @@ struct AmConfig
     /** the port SIP requests are sent from - optional (default 5060) */
     int LocalSIPPort;
 
+    /** options for the signaling socket (@see trsp_socket::socket_options) */
+    unsigned int SigSockOpts;
+
     IP_interface();
 
     int getNextRtpPort();
diff --git a/core/SipCtrlInterface.cpp b/core/SipCtrlInterface.cpp
index 11c3a32..4e7af84 100644
--- a/core/SipCtrlInterface.cpp
+++ b/core/SipCtrlInterface.cpp
@@ -240,7 +240,8 @@ int SipCtrlInterface::run()
     // Init transport instances
     for(unsigned int i=0; i<AmConfig::Ifs.size();i++) {
 
-       udp_trsp_socket* udp_socket = new udp_trsp_socket(i);
+       udp_trsp_socket* udp_socket = 
+           new udp_trsp_socket(i,AmConfig::Ifs[i].SigSockOpts);
 
        if(udp_socket->bind(AmConfig::Ifs[i].LocalSIPIP,
                            AmConfig::Ifs[i].LocalSIPPort) < 0){
diff --git a/core/sip/trans_layer.cpp b/core/sip/trans_layer.cpp
index f2e3244..1c9454c 100644
--- a/core/sip/trans_layer.cpp
+++ b/core/sip/trans_layer.cpp
@@ -382,7 +382,13 @@ int _trans_layer::send_reply(trans_ticket* tt,
     sockaddr_storage remote_ip;
     trsp_socket* local_socket = NULL;
 
-    local_socket = req->local_socket;
+    // rco: should we overwrite the socket from the request in all cases???
+    if((out_interface >= 0) && ((unsigned int)out_interface < 
transports.size())){
+       local_socket = transports[out_interface];
+    }
+    else {
+       local_socket = req->local_socket;
+    }
 
     if (!_next_hop.len) {
        memcpy(&remote_ip,&req->remote_ip,sizeof(sockaddr_storage));
@@ -394,6 +400,7 @@ int _trans_layer::send_reply(trans_ticket* tt,
                ((sockaddr_in*)&remote_ip)->sin_port = 
htons(req->via_p1->rport_i);
            }
            // else: use the source port from the replied request (from IP hdr)
+           //       (already set).
        }
        else {
        
@@ -403,7 +410,15 @@ int _trans_layer::send_reply(trans_ticket* tt,
            }
            // else: use the source port from the replied request (from IP hdr)
 
-           // TODO: use destination address from 1st Via???
+       if(local_socket->is_opt_set(trsp_socket::force_via_address)) {
+           DBG("force_via_address\n");
+           string via_host = c2stlstr(req->via_p1->host);
+           if (resolver::instance()->str2ip(via_host.c_str(), &remote_ip,
+                                            (address_type)(IPv4 | IPv6)) != 1) 
{
+               ERROR("Invalid via_host '%s'\n", via_host.c_str());
+               delete [] reply_buf;
+               goto end;
+           }
        }
     } else {
        DBG("setting next hop '%.*s:%u'\n",
@@ -424,11 +439,6 @@ int _trans_layer::send_reply(trans_ticket* tt,
        ntohs(((sockaddr_in*)&remote_ip)->sin_port),
        50 /* preview - instead of p_msg->len */,reply_buf);
 
-    // rco: should we overwrite the socket from the request in all cases???
-    if((out_interface >= 0) && ((unsigned int)out_interface < 
transports.size())){
-       local_socket = transports[out_interface];
-    }
-
     err = local_socket->send(&remote_ip,reply_buf,reply_len);
     if(err < 0){
        delete [] reply_buf;
diff --git a/core/sip/transport.cpp b/core/sip/transport.cpp
index 62aa1d0..eb47590 100644
--- a/core/sip/transport.cpp
+++ b/core/sip/transport.cpp
@@ -27,7 +27,6 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include "transport.h"
-#include "../SipCtrlInterface.h"
 #include "../log.h"
 
 #include <assert.h>
@@ -36,8 +35,8 @@
 
 int trsp_socket::log_level_raw_msgs = L_DBG;
 
-trsp_socket::trsp_socket(unsigned short if_num)
-    : sd(0), ip(), port(0), if_num(if_num)
+trsp_socket::trsp_socket(unsigned short if_num, unsigned int opts)
+    : sd(0), ip(), port(0), if_num(if_num), socket_options(opts)
 {
     memset(&addr,0,sizeof(sockaddr_storage));
 }
@@ -56,6 +55,12 @@ unsigned short trsp_socket::get_port()
     return port;
 }
 
+bool trsp_socket::is_opt_set(unsigned int mask)
+{
+    DBG("trsp_socket::socket_options = 0x%x\n",socket_options);
+    return (socket_options & mask) == mask;
+}
+
 void trsp_socket::copy_addr_to(sockaddr_storage* sa)
 {
     memcpy(sa,&addr,sizeof(sockaddr_storage));
diff --git a/core/sip/transport.h b/core/sip/transport.h
index 817a23e..c2619f4 100644
--- a/core/sip/transport.h
+++ b/core/sip/transport.h
@@ -44,6 +44,10 @@ using std::string;
 class trsp_socket
 {
 public:
+    enum socket_options {
+       force_via_address = (1 << 0)
+    };
+
     static int log_level_raw_msgs;
     
 protected:
@@ -62,8 +66,11 @@ protected:
     // interface number
     unsigned short   if_num;
 
+    // ORed field of socket_option
+    unsigned int socket_options;
+
 public:
-    trsp_socket(unsigned short if_num);
+    trsp_socket(unsigned short if_num, unsigned int opts);
     virtual ~trsp_socket();
 
     /**
@@ -93,6 +100,11 @@ public:
     unsigned short get_if();
 
     /**
+     * Checks for socket options
+     */
+    bool is_opt_set(unsigned int mask);
+
+    /**
      * Copy the internal address into the given one (sa).
      */
     void copy_addr_to(sockaddr_storage* sa);
diff --git a/core/sip/udp_trsp.h b/core/sip/udp_trsp.h
index f508489..bd38215 100644
--- a/core/sip/udp_trsp.h
+++ b/core/sip/udp_trsp.h
@@ -45,7 +45,9 @@ using std::string;
 class udp_trsp_socket: public trsp_socket
 {
 public:
-    udp_trsp_socket(unsigned short if_num) : trsp_socket(if_num) {}
+    udp_trsp_socket(unsigned short if_num, unsigned int opts) 
+       : trsp_socket(if_num,opts) {}
+
     ~udp_trsp_socket() {}
 
     /**

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

Reply via email to