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
