Browse code

core:zrtp: make ZRTP debug logging configurable

Stefan Sayer authored on 03/11/2014 16:46:54
Showing 1 changed files
... ...
@@ -106,6 +106,7 @@ int          AmConfig::UnhandledReplyLoglevel  = 0;
106 106
 
107 107
 #ifdef WITH_ZRTP
108 108
 bool         AmConfig::enable_zrtp             = true;
109
+bool         AmConfig::enable_zrtp_debuglog    = true;
109 110
 #endif
110 111
 
111 112
 unsigned int AmConfig::SessionLimit            = 0;
... ...
@@ -595,6 +596,9 @@ int AmConfig::readConfiguration()
595 596
 #ifdef WITH_ZRTP
596 597
   enable_zrtp = cfg.getParameter("enable_zrtp", "yes") == "yes";
597 598
   INFO("ZRTP %sabled\n", enable_zrtp ? "en":"dis");
599
+
600
+  enable_zrtp_debuglog = cfg.getParameter("enable_zrtp_debuglog", "yes") == "yes";
601
+  INFO("ZRTP debug log %sabled\n", enable_zrtp_debuglog ? "en":"dis");
598 602
 #endif
599 603
 
600 604
   if(cfg.hasParameter("session_limit")){ 
Browse code

zrtp: updated ZRTP support, compiles with the current zfone SDK

use the zfone SDK from https://github.com/traviscross/libzrtp

Stefan Sayer authored on 30/10/2014 22:31:46
Showing 1 changed files
... ...
@@ -104,6 +104,10 @@ bool         AmConfig::LogSessions             = false;
104 104
 bool         AmConfig::LogEvents               = false;
105 105
 int          AmConfig::UnhandledReplyLoglevel  = 0;
106 106
 
107
+#ifdef WITH_ZRTP
108
+bool         AmConfig::enable_zrtp             = true;
109
+#endif
110
+
107 111
 unsigned int AmConfig::SessionLimit            = 0;
108 112
 unsigned int AmConfig::SessionLimitErrCode     = 503;
109 113
 string       AmConfig::SessionLimitErrReason   = "Server overload";
... ...
@@ -588,6 +592,11 @@ int AmConfig::readConfiguration()
588 592
     }
589 593
   }
590 594
 
595
+#ifdef WITH_ZRTP
596
+  enable_zrtp = cfg.getParameter("enable_zrtp", "yes") == "yes";
597
+  INFO("ZRTP %sabled\n", enable_zrtp ? "en":"dis");
598
+#endif
599
+
591 600
   if(cfg.hasParameter("session_limit")){ 
592 601
     vector<string> limit = explode(cfg.getParameter("session_limit"), ";");
593 602
     if (limit.size() != 3) {
Browse code

Improvement: Add option not to add ";transport=" to contact

Carsten Bock authored on 20/08/2014 08:10:33
Showing 1 changed files
... ...
@@ -761,8 +761,9 @@ static int readSIPInterface(AmConfigReader& cfg, const string& i_name)
761 761
 	it_opt != opt_strs.end(); ++it_opt) {
762 762
       if(*it_opt == "force_via_address") {
763 763
 	opts |= trsp_socket::force_via_address;
764
-      }
765
-      else {
764
+      } else if(*it_opt == "no_transport_in_contact") {
765
+	opts |= trsp_socket::no_transport_in_contact;
766
+      } else {
766 767
 	WARN("unknown signaling socket option '%s' set on interface '%s'\n",
767 768
 	     it_opt->c_str(),i_name.c_str());
768 769
       }
Browse code

sip: moved resolve_targets() to resolver

Raphael Coeffic authored on 19/11/2013 12:31:01
Showing 1 changed files
... ...
@@ -43,6 +43,7 @@
43 43
 #include "AmSessionContainer.h"
44 44
 #include "Am100rel.h"
45 45
 #include "sip/transport.h"
46
+#include "sip/resolver.h"
46 47
 #include "sip/ip_util.h"
47 48
 #include "sip/sip_timers.h"
48 49
 #include "sip/raw_sender.h"
... ...
@@ -91,7 +92,6 @@ bool         AmConfig::ForceSymmetricRtp       = false;
91 92
 bool         AmConfig::SipNATHandling          = false;
92 93
 bool         AmConfig::UseRawSockets           = false;
93 94
 bool         AmConfig::IgnoreNotifyLowerCSeq   = false;
94
-bool         AmConfig::DisableDNSSRV           = false;
95 95
 string       AmConfig::Signature               = "";
96 96
 unsigned int AmConfig::MaxForwards             = MAX_FORWARDS;
97 97
 bool	     AmConfig::SingleCodecInOK	       = false;
... ...
@@ -386,7 +386,7 @@ int AmConfig::readConfiguration()
386 386
   }
387 387
 
388 388
   if(cfg.hasParameter("disable_dns_srv")) {
389
-    DisableDNSSRV = (cfg.getParameter("disable_dns_srv") == "yes");
389
+    _resolver::disable_srv = (cfg.getParameter("disable_dns_srv") == "yes");
390 390
   }
391 391
   
392 392
 
Browse code

sip: added tcp_connect_timeout & tcp_idle_timeout

Both options can be set per signalling interface ([tcp-option]_[interface name]=[time in milliseconds]). When set to 0, the feature is disabled.

Raphael Coeffic authored on 13/11/2013 17:33:32
Showing 1 changed files
... ...
@@ -770,6 +770,13 @@ static int readSIPInterface(AmConfigReader& cfg, const string& i_name)
770 770
     intf.SigSockOpts = opts;
771 771
   }
772 772
 
773
+  intf.tcp_connect_timeout =
774
+    cfg.getParameterInt("tcp_connect_timeout" + suffix,
775
+			DEFAULT_TCP_CONNECT_TIMEOUT);
776
+
777
+  intf.tcp_idle_timeout =
778
+    cfg.getParameterInt("tcp_idle_timeout" + suffix, DEFAULT_TCP_IDLE_TIMEOUT);
779
+
773 780
   if(!i_name.empty())
774 781
     intf.name = i_name;
775 782
   else
... ...
@@ -1172,9 +1179,11 @@ void AmConfig::dump_Ifs()
1172 1179
     SIP_interface& it_ref = SIP_Ifs[i];
1173 1180
 
1174 1181
     INFO("\t(%i) name='%s'" ";LocalIP='%s'" 
1175
-	 ";LocalPort='%u'" ";PublicIP='%s'",
1182
+	 ";LocalPort='%u'" ";PublicIP='%s';TCP=%u/%u",
1176 1183
 	 i,it_ref.name.c_str(),it_ref.LocalIP.c_str(),
1177
-	 it_ref.LocalPort,it_ref.PublicIP.c_str());
1184
+	 it_ref.LocalPort,it_ref.PublicIP.c_str(),
1185
+	 it_ref.tcp_connect_timeout,
1186
+	 it_ref.tcp_idle_timeout);
1178 1187
   }
1179 1188
   
1180 1189
   INFO("Signaling address map:");
Browse code

core: draft support for TCP transport (WIP)

Raphael Coeffic authored on 22/08/2013 07:16:33
Showing 1 changed files
... ...
@@ -713,6 +713,7 @@ int AmConfig::insert_SIP_interface(const SIP_interface& intf)
713 713
 
714 714
 	return -1;
715 715
       }
716
+      //FIXME: what happens now? shouldn't we insert the interface????
716 717
     }
717 718
   }
718 719
 
Browse code

Merge branch 'master' into 1.6-dev

Václav Kubart authored on 12/11/2013 06:30:28
Showing 0 changed files
Browse code

core: CPS limiter Calls-per-sec limiting capability, similar to the maximum number of calls limiter. There is a "soft limit" that is intended to use by the applications: if the app uses async processing and detects that the incoming workload is too much for the currenti capacity (which can depend on for example the remote DB engine's load), it can slewi it back to some percent of the current CPS; then when the circumstances are restored it can switch the CPS limit back to the configuration (or XMLRPC/stats interface) mandated value.

Szókovács Róbert authored on 07/11/2013 14:59:47
Showing 1 changed files
... ...
@@ -40,7 +40,7 @@
40 40
 #include "log.h"
41 41
 #include "AmConfigReader.h"
42 42
 #include "AmUtils.h"
43
-#include "AmSession.h"
43
+#include "AmSessionContainer.h"
44 44
 #include "Am100rel.h"
45 45
 #include "sip/transport.h"
46 46
 #include "sip/ip_util.h"
... ...
@@ -110,6 +110,9 @@ unsigned int AmConfig::OptionsSessionLimit            = 0;
110 110
 unsigned int AmConfig::OptionsSessionLimitErrCode     = 503;
111 111
 string       AmConfig::OptionsSessionLimitErrReason   = "Server overload";
112 112
 
113
+unsigned int AmConfig::CPSLimitErrCode     = 503;
114
+string       AmConfig::CPSLimitErrReason   = "Server overload";
115
+
113 116
 bool         AmConfig::AcceptForkedDialogs     = true;
114 117
 
115 118
 bool         AmConfig::ShutdownMode            = false;
... ...
@@ -600,6 +603,20 @@ int AmConfig::readConfiguration()
600 603
     }
601 604
   }
602 605
 
606
+  if(cfg.hasParameter("cps_limit")){ 
607
+    unsigned int CPSLimit;
608
+    vector<string> limit = explode(cfg.getParameter("cps_limit"), ";");
609
+    if (limit.size() != 3) {
610
+      ERROR("invalid cps_limit specified.\n");
611
+    } else {
612
+      if (str2i(limit[0], CPSLimit) || str2i(limit[1], CPSLimitErrCode)) {
613
+	ERROR("invalid cps_limit specified.\n");
614
+      }
615
+      CPSLimitErrReason = limit[2];
616
+    }
617
+    AmSessionContainer::instance()->setCPSLimit(CPSLimit);
618
+  }
619
+
603 620
   if(cfg.hasParameter("accept_forked_dialogs"))
604 621
     AcceptForkedDialogs = !(cfg.getParameter("accept_forked_dialogs") == "no");
605 622
 
Browse code

core: raised log level for SIP timer config info (DBG->INFO)

Raphael Coeffic authored on 23/10/2013 22:30:29
Showing 1 changed files
... ...
@@ -393,13 +393,13 @@ int AmConfig::readConfiguration()
393 393
     if(cfg.hasParameter(timer_cfg)) {
394 394
 
395 395
       sip_timers[t] = cfg.getParameterInt(timer_cfg, sip_timers[t]);
396
-      DBG("Set SIP Timer '%s' to %u ms\n", timer_name(t), sip_timers[t]);
396
+      INFO("Set SIP Timer '%s' to %u ms\n", timer_name(t), sip_timers[t]);
397 397
     }
398 398
   }
399 399
 
400 400
   if (cfg.hasParameter("sip_timer_t2")) {
401 401
     sip_timer_t2 = cfg.getParameterInt("sip_timer_t2", DEFAULT_T2_TIMER);
402
-    DBG("Set SIP Timer T2 to %u ms\n", sip_timer_t2);
402
+    INFO("Set SIP Timer T2 to %u ms\n", sip_timer_t2);
403 403
   }
404 404
 
405 405
   // plugin_path
Browse code

core: read log level config param at the beginning

Raphael Coeffic authored on 23/10/2013 22:29:23
Showing 1 changed files
... ...
@@ -306,6 +306,14 @@ int AmConfig::readConfiguration()
306 306
   // take values from global configuration file
307 307
   // they will be overwritten by command line args
308 308
 
309
+  // log_level
310
+  if(cfg.hasParameter("loglevel")){
311
+    if(!setLogLevel(cfg.getParameter("loglevel"))){
312
+      ERROR("invalid log level specified\n");
313
+      ret = -1;
314
+    }
315
+  }
316
+
309 317
   // stderr 
310 318
   if(cfg.hasParameter("stderr")){
311 319
     if(!setLogStderr(cfg.getParameter("stderr"), true)){
... ...
@@ -436,14 +444,6 @@ int AmConfig::readConfiguration()
436 444
       }
437 445
   }
438 446
 
439
-  // log_level
440
-  if(cfg.hasParameter("loglevel")){
441
-    if(!setLogLevel(cfg.getParameter("loglevel"))){
442
-      ERROR("invalid log level specified\n");
443
-      ret = -1;
444
-    }
445
-  }
446
-
447 447
   if(cfg.hasParameter("log_sessions"))
448 448
     LogSessions = cfg.getParameter("log_sessions")=="yes";
449 449
   
Browse code

core: add link MTU detection to be used by raw sockets

Raphael Coeffic authored on 17/10/2013 15:14:32
Showing 1 changed files
... ...
@@ -66,7 +66,7 @@ vector<AmConfig::RTP_interface> AmConfig::RTP_Ifs;
66 66
 map<string,unsigned short>      AmConfig::SIP_If_names;
67 67
 map<string,unsigned short>      AmConfig::RTP_If_names;
68 68
 map<string,unsigned short>      AmConfig::LocalSIPIP2If;
69
-list<AmConfig::SysIntf>         AmConfig::SysIfs;
69
+vector<AmConfig::SysIntf>         AmConfig::SysIfs;
70 70
 
71 71
 #ifndef DISABLE_DAEMON_MODE
72 72
 bool         AmConfig::DaemonMode              = DEFAULT_DAEMON_MODE;
... ...
@@ -889,6 +889,13 @@ static int readInterfaces(AmConfigReader& cfg)
889 889
 static bool fillSysIntfList()
890 890
 {
891 891
   struct ifaddrs *ifap = NULL;
892
+
893
+  // socket to grab MTU
894
+  int fd = socket(AF_INET, SOCK_DGRAM, 0);
895
+  if(fd < 0) {
896
+    ERROR("socket() failed: %s",strerror(errno));
897
+    return false;
898
+  }
892 899
   
893 900
   if(getifaddrs(&ifap) < 0){
894 901
     ERROR("getifaddrs() failed: %s",strerror(errno));
... ...
@@ -924,12 +931,13 @@ static bool fillSysIntfList()
924 931
     if (am_inet_ntop((const sockaddr_storage*)p_if->ifa_addr,
925 932
 		     host, NI_MAXHOST) == NULL) {
926 933
       ERROR("am_inet_ntop() failed\n");
927
-      freeifaddrs(ifap);
928
-      return false;
934
+      continue;
935
+      // freeifaddrs(ifap);
936
+      // return false;
929 937
     }
930 938
 
931 939
     string iface_name(p_if->ifa_name);
932
-    list<AmConfig::SysIntf>::iterator intf_it;
940
+    vector<AmConfig::SysIntf>::iterator intf_it;
933 941
     for(intf_it = AmConfig::SysIfs.begin();
934 942
 	intf_it != AmConfig::SysIfs.end(); ++intf_it) {
935 943
 
... ...
@@ -938,10 +946,25 @@ static bool fillSysIntfList()
938 946
     }
939 947
 
940 948
     if(intf_it == AmConfig::SysIfs.end()){
941
-      intf_it = AmConfig::SysIfs.insert(AmConfig::SysIfs.end(),
942
-					AmConfig::SysIntf());
949
+      unsigned int sys_if_idx = if_nametoindex(iface_name.c_str());
950
+      if(AmConfig::SysIfs.size() < sys_if_idx+1)
951
+	AmConfig::SysIfs.resize(sys_if_idx+1);
952
+
953
+      intf_it = AmConfig::SysIfs.begin() + sys_if_idx;
943 954
       intf_it->name  = iface_name;
944 955
       intf_it->flags = p_if->ifa_flags;
956
+
957
+      struct ifreq ifr;
958
+      strncpy(ifr.ifr_name,p_if->ifa_name,IFNAMSIZ);
959
+
960
+      if (ioctl(fd, SIOCGIFMTU, &ifr) < 0 ) {
961
+	ERROR("ioctl: %s",strerror(errno));
962
+	ERROR("setting MTU for this interface to default (1500)");
963
+	intf_it->mtu = 1500;
964
+      }
965
+      else {
966
+	intf_it->mtu = ifr.ifr_mtu;
967
+      }
945 968
     }
946 969
 
947 970
     DBG("iface='%s';ip='%s';flags=0x%x\n",p_if->ifa_name,host,p_if->ifa_flags);
... ...
@@ -949,11 +972,12 @@ static bool fillSysIntfList()
949 972
   }
950 973
 
951 974
   freeifaddrs(ifap);
975
+  close(fd);
952 976
 
953 977
   // add addresses from SysIntfList, if not present
954 978
   for(unsigned int idx = 0; idx < AmConfig::SIP_Ifs.size(); idx++) {
955 979
 
956
-    list<AmConfig::SysIntf>::iterator intf_it = AmConfig::SysIfs.begin();
980
+    vector<AmConfig::SysIntf>::iterator intf_it = AmConfig::SysIfs.begin();
957 981
     for(;intf_it != AmConfig::SysIfs.end(); ++intf_it) {
958 982
 
959 983
       list<AmConfig::IPAddr>::iterator addr_it = intf_it->addrs.begin();
... ...
@@ -992,7 +1016,7 @@ string fixIface2IP(const string& dev_name, bool v6_for_sip)
992 1016
       return dev_name;
993 1017
   }
994 1018
 
995
-  for(list<AmConfig::SysIntf>::iterator intf_it = AmConfig::SysIfs.begin();
1019
+  for(vector<AmConfig::SysIntf>::iterator intf_it = AmConfig::SysIfs.begin();
996 1020
       intf_it != AmConfig::SysIfs.end(); ++intf_it) {
997 1021
       
998 1022
     if(intf_it->name != dev_name)
... ...
@@ -1013,7 +1037,7 @@ string fixIface2IP(const string& dev_name, bool v6_for_sip)
1013 1037
 /** Get IP addrese from first non-loopback interface */
1014 1038
 static string getDefaultIP()
1015 1039
 {
1016
-  for(list<AmConfig::SysIntf>::iterator intf_it = AmConfig::SysIfs.begin();
1040
+  for(vector<AmConfig::SysIntf>::iterator intf_it = AmConfig::SysIfs.begin();
1017 1041
       intf_it != AmConfig::SysIfs.end(); ++intf_it) {
1018 1042
       
1019 1043
     if(intf_it->flags & IFF_LOOPBACK)
... ...
@@ -1031,14 +1055,13 @@ static string getDefaultIP()
1031 1055
 
1032 1056
 static int setNetInterface(AmConfig::IP_interface* ip_if)
1033 1057
 {
1034
-  for(list<AmConfig::SysIntf>::iterator sys_it = AmConfig::SysIfs.begin();
1035
-      sys_it != AmConfig::SysIfs.end(); sys_it++) {
1058
+  for(unsigned int i=0; i < AmConfig::SysIfs.size(); i++) {
1036 1059
     
1037
-    list<AmConfig::IPAddr>::iterator addr_it = sys_it->addrs.begin();
1038
-    while(addr_it != sys_it->addrs.end()) {
1060
+    list<AmConfig::IPAddr>::iterator addr_it = AmConfig::SysIfs[i].addrs.begin();
1061
+    while(addr_it != AmConfig::SysIfs[i].addrs.end()) {
1039 1062
       if(ip_if->LocalIP == addr_it->addr) {
1040
-	ip_if->NetIf = sys_it->name;
1041
-	ip_if->NetIfIdx = if_nametoindex(sys_it->name.c_str());
1063
+	ip_if->NetIf = AmConfig::SysIfs[i].name;
1064
+	ip_if->NetIfIdx = i;
1042 1065
 	return 0;
1043 1066
       }
1044 1067
       addr_it++;
Browse code

udp: raw socket support

To use this feature, set following in sems.conf:
use_raw_sockets=yes

Raphael Coeffic authored on 15/10/2013 07:42:43
Showing 1 changed files
... ...
@@ -45,6 +45,7 @@
45 45
 #include "sip/transport.h"
46 46
 #include "sip/ip_util.h"
47 47
 #include "sip/sip_timers.h"
48
+#include "sip/raw_sender.h"
48 49
 
49 50
 #include <cctype>
50 51
 #include <algorithm>
... ...
@@ -88,6 +89,7 @@ bool         AmConfig::ProxyStickyAuth         = false;
88 89
 bool         AmConfig::ForceOutboundIf         = false;
89 90
 bool         AmConfig::ForceSymmetricRtp       = false;
90 91
 bool         AmConfig::SipNATHandling          = false;
92
+bool         AmConfig::UseRawSockets           = false;
91 93
 bool         AmConfig::IgnoreNotifyLowerCSeq   = false;
92 94
 bool         AmConfig::DisableDNSSRV           = false;
93 95
 string       AmConfig::Signature               = "";
... ...
@@ -353,6 +355,13 @@ int AmConfig::readConfiguration()
353 355
     ForceOutboundIf = (cfg.getParameter("force_outbound_if") == "yes");
354 356
   }
355 357
 
358
+  if(cfg.hasParameter("use_raw_sockets")) {
359
+    UseRawSockets = (cfg.getParameter("use_raw_sockets") == "yes");
360
+    if(UseRawSockets && (raw_sender::init() < 0)) {
361
+      UseRawSockets = false;
362
+    }
363
+  }
364
+
356 365
   if(cfg.hasParameter("ignore_notify_lower_cseq")) {
357 366
     IgnoreNotifyLowerCSeq = (cfg.getParameter("ignore_notify_lower_cseq") == "yes");
358 367
   }
Browse code

sip: reorganized timer settings table

Raphael Coeffic authored on 15/09/2013 10:05:11 • Václav Kubart committed on 16/10/2013 09:19:54
Showing 1 changed files
... ...
@@ -370,10 +370,13 @@ int AmConfig::readConfiguration()
370 370
   }
371 371
   
372 372
 
373
-  for (char c = 'a'; c <= 'm'; c++) {
374
-    if(cfg.hasParameter(string("sip_timer_")+c)) {
375
-      sip_timers[c-'a']=cfg.getParameterInt(string("sip_timer_")+c, sip_timers[c-'a']);
376
-      DBG("Set SIP Timer '%c' to %u ms\n", 'A'+c-'a', sip_timers[c-'a']);
373
+  for (int t = STIMER_A; t < __STIMER_MAX; t++) {
374
+
375
+    string timer_cfg = string("sip_timer_") + timer_name(t);
376
+    if(cfg.hasParameter(timer_cfg)) {
377
+
378
+      sip_timers[t] = cfg.getParameterInt(timer_cfg, sip_timers[t]);
379
+      DBG("Set SIP Timer '%s' to %u ms\n", timer_name(t), sip_timers[t]);
377 380
     }
378 381
   }
379 382
 
Browse code

core: sip_nat_handling config option to learn next_hop from remote IP

Stefan Sayer authored on 29/07/2013 13:42:50
Showing 1 changed files
... ...
@@ -87,6 +87,7 @@ bool         AmConfig::NextHop1stReq           = false;
87 87
 bool         AmConfig::ProxyStickyAuth         = false;
88 88
 bool         AmConfig::ForceOutboundIf         = false;
89 89
 bool         AmConfig::ForceSymmetricRtp       = false;
90
+bool         AmConfig::SipNATHandling          = false;
90 91
 bool         AmConfig::IgnoreNotifyLowerCSeq   = false;
91 92
 bool         AmConfig::DisableDNSSRV           = false;
92 93
 string       AmConfig::Signature               = "";
... ...
@@ -360,6 +361,10 @@ int AmConfig::readConfiguration()
360 361
     ForceSymmetricRtp = (cfg.getParameter("force_symmetric_rtp") == "yes");
361 362
   }
362 363
 
364
+  if(cfg.hasParameter("sip_nat_handling")) {
365
+    SipNATHandling = (cfg.getParameter("sip_nat_handling") == "yes");
366
+  }
367
+
363 368
   if(cfg.hasParameter("disable_dns_srv")) {
364 369
     DisableDNSSRV = (cfg.getParameter("disable_dns_srv") == "yes");
365 370
   }
Browse code

core: force_symmetric_rtp option to force comedia style remote RTP address learning for NAT

Stefan Sayer authored on 24/07/2013 15:03:24
Showing 1 changed files
... ...
@@ -86,6 +86,7 @@ string       AmConfig::NextHop                 = "";
86 86
 bool         AmConfig::NextHop1stReq           = false;
87 87
 bool         AmConfig::ProxyStickyAuth         = false;
88 88
 bool         AmConfig::ForceOutboundIf         = false;
89
+bool         AmConfig::ForceSymmetricRtp       = false;
89 90
 bool         AmConfig::IgnoreNotifyLowerCSeq   = false;
90 91
 bool         AmConfig::DisableDNSSRV           = false;
91 92
 string       AmConfig::Signature               = "";
... ...
@@ -355,6 +356,10 @@ int AmConfig::readConfiguration()
355 356
     IgnoreNotifyLowerCSeq = (cfg.getParameter("ignore_notify_lower_cseq") == "yes");
356 357
   }
357 358
 
359
+  if(cfg.hasParameter("force_symmetric_rtp")) {
360
+    ForceSymmetricRtp = (cfg.getParameter("force_symmetric_rtp") == "yes");
361
+  }
362
+
358 363
   if(cfg.hasParameter("disable_dns_srv")) {
359 364
     DisableDNSSRV = (cfg.getParameter("disable_dns_srv") == "yes");
360 365
   }
Browse code

do not include link-local IPv6 addresses in the system interface map.

Raphael Coeffic authored on 19/12/2012 15:27:08
Showing 1 changed files
... ...
@@ -886,6 +886,19 @@ static bool fillSysIntfList()
886 886
     if( !(p_if->ifa_flags & IFF_UP) || !(p_if->ifa_flags & IFF_RUNNING) )
887 887
       continue;
888 888
 
889
+    if(p_if->ifa_addr->sa_family == AF_INET6) {
890
+      
891
+      struct sockaddr_in6 *addr = (struct sockaddr_in6 *)p_if->ifa_addr;
892
+      if(IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)){
893
+	// sorry, we don't support link-local addresses...
894
+	continue;
895
+
896
+	// convert address from kernel-style to userland
897
+	// addr->sin6_scope_id = ntohs(*(uint16_t *)&addr->sin6_addr.s6_addr[2]);
898
+	// addr->sin6_addr.s6_addr[2] = addr->sin6_addr.s6_addr[3] = 0;
899
+      }
900
+    }
901
+
889 902
     if (am_inet_ntop((const sockaddr_storage*)p_if->ifa_addr,
890 903
 		     host, NI_MAXHOST) == NULL) {
891 904
       ERROR("am_inet_ntop() failed\n");
Browse code

new interface config

Allows for signaling-only or media-only interfaces.

The parameter "additional_interfaces" has been renamed to
"interfaces". When not present, SEMS will look for IP config
parameters without any suffixes (sip_ip, media_ip, etc...).

If the "media_ip_[interface name]" is set, the interface is considered
to be a media interface. If the "sip_ip_[interface name]" parameter
is defined, the interface is considered to be a media interface. If
both parameters are defined for the same interface, it is a signaling
and media interface.

Raphael Coeffic authored on 29/10/2012 08:55:54
Showing 1 changed files
... ...
@@ -60,9 +60,11 @@ string       AmConfig::ExcludePayloads         = "";
60 60
 int          AmConfig::LogLevel                = L_INFO;
61 61
 bool         AmConfig::LogStderr               = false;
62 62
 
63
-vector<AmConfig::IP_interface>  AmConfig::Ifs;
64
-map<string,unsigned short>      AmConfig::If_names;
65
-multimap<string,unsigned short> AmConfig::LocalSIPIP2If;
63
+vector<AmConfig::SIP_interface> AmConfig::SIP_Ifs;
64
+vector<AmConfig::RTP_interface> AmConfig::RTP_Ifs;
65
+map<string,unsigned short>      AmConfig::SIP_If_names;
66
+map<string,unsigned short>      AmConfig::RTP_If_names;
67
+map<string,unsigned short>      AmConfig::LocalSIPIP2If;
66 68
 list<AmConfig::SysIntf>         AmConfig::SysIfs;
67 69
 
68 70
 #ifndef DISABLE_DAEMON_MODE
... ...
@@ -143,18 +145,28 @@ AmAudio::ResamplingImplementationType AmConfig::ResamplingImplementationType = A
143 145
 static int readInterfaces(AmConfigReader& cfg);
144 146
 
145 147
 AmConfig::IP_interface::IP_interface()
146
-  : LocalSIPIP(),
147
-    LocalSIPPort(5060),
148
-    LocalIP(),
149
-    PublicIP(),
148
+  : LocalIP(),
149
+    PublicIP()
150
+{
151
+}
152
+
153
+AmConfig::SIP_interface::SIP_interface()
154
+  : IP_interface(),
155
+    LocalPort(5060),
156
+    SigSockOpts(0),
157
+    RtpInterface(-1)
158
+{
159
+}
160
+
161
+AmConfig::RTP_interface::RTP_interface()
162
+  : IP_interface(),
150 163
     RtpLowPort(RTP_LOWPORT),
151 164
     RtpHighPort(RTP_HIGHPORT),
152
-    SigSockOpts(0),
153 165
     next_rtp_port(-1)
154 166
 {
155 167
 }
156 168
 
157
-int AmConfig::IP_interface::getNextRtpPort()
169
+int AmConfig::RTP_interface::getNextRtpPort()
158 170
 {
159 171
     
160 172
   int port=0;
... ...
@@ -626,10 +638,52 @@ int AmConfig::readConfiguration()
626 638
   return ret;
627 639
 }	
628 640
 
629
-static int readInterface(AmConfigReader& cfg, const string& i_name)
641
+int AmConfig::insert_SIP_interface(const SIP_interface& intf)
642
+{
643
+  if(SIP_If_names.find(intf.name) !=
644
+     SIP_If_names.end()) {
645
+
646
+    if(intf.name != "default") {
647
+      ERROR("duplicated interface name '%s'\n",intf.name.c_str());
648
+      return -1;
649
+    }
650
+
651
+    unsigned int idx = SIP_If_names[intf.name];
652
+    SIP_Ifs[idx] = intf;
653
+  }
654
+  else {
655
+    SIP_Ifs.push_back(intf);
656
+    unsigned int idx = SIP_Ifs.size()-1;
657
+    SIP_If_names[intf.name] = idx;
658
+
659
+    if(LocalSIPIP2If.find(intf.LocalIP) == 
660
+       LocalSIPIP2If.end()) {
661
+
662
+      LocalSIPIP2If.insert(make_pair(intf.LocalIP,idx));
663
+    }
664
+    else {
665
+      map<string,unsigned short>::iterator it = 
666
+	LocalSIPIP2If.find(intf.LocalIP);
667
+
668
+      const SIP_interface& old_intf = SIP_Ifs[it->second];
669
+      if(intf.LocalPort == old_intf.LocalPort) {
670
+	ERROR("duplicated signaling interfaces "
671
+	      "(%s and %s) detected using %s:%u",
672
+	      old_intf.name.c_str(),intf.name.c_str(),
673
+	      intf.LocalIP.c_str(),intf.LocalPort);
674
+
675
+	return -1;
676
+      }
677
+    }
678
+  }
679
+
680
+  return 0;
681
+}
682
+
683
+static int readSIPInterface(AmConfigReader& cfg, const string& i_name)
630 684
 {
631 685
   int ret=0;
632
-  AmConfig::IP_interface intf;
686
+  AmConfig::SIP_interface intf;
633 687
 
634 688
   string suffix;
635 689
   if(!i_name.empty())
... ...
@@ -637,17 +691,17 @@ static int readInterface(AmConfigReader& cfg, const string& i_name)
637 691
 
638 692
   // listen, sip_ip, sip_port, and media_ip
639 693
   if(cfg.hasParameter("sip_ip" + suffix)) {
640
-    intf.LocalSIPIP = cfg.getParameter("sip_ip" + suffix);
694
+    intf.LocalIP = cfg.getParameter("sip_ip" + suffix);
641 695
   }
642
-  else if(!suffix.empty()) {
643
-     ERROR("sip_ip%s parameter is required",suffix.c_str());
644
-     ret = -1;
696
+  else {
697
+    // no sip_ip definition
698
+    return 0;
645 699
   }
646 700
 
647 701
   if(cfg.hasParameter("sip_port" + suffix)){
648 702
     string sip_port_str = cfg.getParameter("sip_port" + suffix);
649 703
     if(sscanf(sip_port_str.c_str(),"%u",
650
-	      &(intf.LocalSIPPort)) != 1){
704
+	      &(intf.LocalPort)) != 1){
651 705
       ERROR("sip_port%s: invalid sip port specified (%s)\n",
652 706
 	    suffix.c_str(),
653 707
 	    sip_port_str.c_str());
... ...
@@ -655,13 +709,83 @@ static int readInterface(AmConfigReader& cfg, const string& i_name)
655 709
     }
656 710
   }
657 711
 
712
+  // public_ip
713
+  if(cfg.hasParameter("public_ip" + suffix)){
714
+    intf.PublicIP = cfg.getParameter("public_ip" + suffix);
715
+  }
716
+
717
+  if(cfg.hasParameter("sig_sock_opts" + suffix)){
718
+    vector<string> opt_strs = explode(cfg.getParameter("sig_sock_opts" + suffix),",");
719
+    unsigned int opts = 0;
720
+    for(vector<string>::iterator it_opt = opt_strs.begin();
721
+	it_opt != opt_strs.end(); ++it_opt) {
722
+      if(*it_opt == "force_via_address") {
723
+	opts |= trsp_socket::force_via_address;
724
+      }
725
+      else {
726
+	WARN("unknown signaling socket option '%s' set on interface '%s'\n",
727
+	     it_opt->c_str(),i_name.c_str());
728
+      }
729
+    }
730
+    intf.SigSockOpts = opts;
731
+  }
732
+
733
+  if(!i_name.empty())
734
+    intf.name = i_name;
735
+  else
736
+    intf.name = "default";
737
+
738
+  return AmConfig::insert_SIP_interface(intf);
739
+}
740
+
741
+int AmConfig::insert_RTP_interface(const RTP_interface& intf)
742
+{
743
+  if(RTP_If_names.find(intf.name) !=
744
+     RTP_If_names.end()) {
745
+
746
+    if(intf.name != "default") {
747
+      ERROR("duplicated interface '%s'\n",intf.name.c_str());
748
+      return -1;
749
+    }
750
+
751
+    unsigned int idx = RTP_If_names[intf.name];
752
+    RTP_Ifs[idx] = intf;
753
+  }
754
+  else {
755
+    // insert interface
756
+    RTP_Ifs.push_back(intf);
757
+    unsigned short rtp_idx = RTP_Ifs.size()-1;
758
+    RTP_If_names[intf.name] = rtp_idx;
759
+    
760
+    // fix RtpInterface index in SIP interface
761
+    map<string,unsigned short>::iterator sip_idx_it = 
762
+      SIP_If_names.find(intf.name);
763
+
764
+    if((sip_idx_it != SIP_If_names.end()) &&
765
+       (SIP_Ifs.size() > sip_idx_it->second)) {
766
+      SIP_Ifs[sip_idx_it->second].RtpInterface = rtp_idx;
767
+    }
768
+  }
769
+
770
+  return 0;
771
+}
772
+
773
+static int readRTPInterface(AmConfigReader& cfg, const string& i_name)
774
+{
775
+  int ret=0;
776
+  AmConfig::RTP_interface intf;
777
+
778
+  string suffix;
779
+  if(!i_name.empty())
780
+    suffix = "_" + i_name;
781
+
782
+  // media_ip
658 783
   if(cfg.hasParameter("media_ip" + suffix)) {
659 784
     intf.LocalIP = cfg.getParameter("media_ip" + suffix);
660 785
   }
661
-  else if(!intf.LocalSIPIP.empty()) {
662
-    WARN("media_ip%s parameter is missing: using same as sip_ip%s",
663
-	suffix.c_str(),suffix.c_str());
664
-    intf.LocalIP = intf.LocalSIPIP;
786
+  else {
787
+    // no media definition for this interface name
788
+    return 0;
665 789
   }
666 790
 
667 791
   // public_ip
... ...
@@ -691,62 +815,52 @@ static int readInterface(AmConfigReader& cfg, const string& i_name)
691 815
     }
692 816
   }
693 817
 
694
-  if(cfg.hasParameter("sig_sock_opts" + suffix)){
695
-    vector<string> opt_strs = explode(cfg.getParameter("sig_sock_opts" + suffix),",");
696
-    unsigned int opts = 0;
697
-    for(vector<string>::iterator it_opt = opt_strs.begin();
698
-	it_opt != opt_strs.end(); ++it_opt) {
699
-      if(*it_opt == "force_via_address") {
700
-	opts |= trsp_socket::force_via_address;
701
-      }
702
-      else {
703
-	WARN("unknown signaling socket option '%s' set on interface '%s'\n",
704
-	     it_opt->c_str(),i_name.c_str());
705
-      }
706
-    }
707
-    intf.SigSockOpts = opts;
708
-  }
709
-
710
-  intf.name = i_name;
711
-
712
-  if(!suffix.empty()) {// !default Interface
713
-    AmConfig::Ifs.push_back(intf);
714
-  }
715
-  else {
818
+  if(!i_name.empty())
819
+    intf.name = i_name;
820
+  else
716 821
     intf.name = "default";
717
-    AmConfig::Ifs[0] = intf;
718
-  }
719 822
 
720
-  AmConfig::If_names[i_name] = AmConfig::Ifs.size()-1;
721
-
722
-  return ret;
823
+  return AmConfig::insert_RTP_interface(intf);
723 824
 }
724 825
 
725 826
 static int readInterfaces(AmConfigReader& cfg)
726 827
 {
727
-  int ret = 0;
828
+  if(!cfg.hasParameter("interfaces")) {
829
+    // no interface list defined:
830
+    // read default params
831
+    readSIPInterface(cfg,"");
832
+    readRTPInterface(cfg,"");
833
+    return 0;
834
+  }
728 835
 
729
-  // read default params first
730
-  if(readInterface(cfg,"") < 0) {
836
+  vector<string> if_names;
837
+  string ifs_str = cfg.getParameter("interfaces");
838
+  if(ifs_str.empty()) {
839
+    ERROR("empty interface list.\n");
731 840
     return -1;
732 841
   }
733
-  
734
-  vector<string> if_names;
735
-  if(cfg.hasParameter("additional_interfaces")) {
736
-    string ifs_str = cfg.getParameter("additional_interfaces");
737
-    if(!ifs_str.empty())
738
-      if_names = explode(ifs_str,",");
842
+
843
+  if_names = explode(ifs_str,",");
844
+  if(!if_names.size()) {
845
+    ERROR("could not parse interface list.\n");
846
+    return -1;
739 847
   }
740 848
 
741 849
   for(vector<string>::iterator it = if_names.begin();
742 850
       it != if_names.end(); it++) {
743 851
 
744
-    if(readInterface(cfg,*it) < 0){
745
-      ret = -1;
852
+    readSIPInterface(cfg,*it);
853
+    readRTPInterface(cfg,*it);
854
+
855
+    if((AmConfig::SIP_If_names.find(*it) == AmConfig::SIP_If_names.end()) &&
856
+       (AmConfig::RTP_If_names.find(*it) == AmConfig::RTP_If_names.end())) {
857
+      ERROR("missing interface definition for '%s'\n",it->c_str());
858
+      return -1;
746 859
     }
747 860
   }
748 861
 
749
-  return ret;
862
+  //TODO: check interfaces
863
+  return 0;
750 864
 }
751 865
 
752 866
 /** Get the list of network interfaces with the associated addresses & flags */
... ...
@@ -801,14 +915,40 @@ static bool fillSysIntfList()
801 915
 
802 916
   freeifaddrs(ifap);
803 917
 
918
+  // add addresses from SysIntfList, if not present
919
+  for(unsigned int idx = 0; idx < AmConfig::SIP_Ifs.size(); idx++) {
920
+
921
+    list<AmConfig::SysIntf>::iterator intf_it = AmConfig::SysIfs.begin();
922
+    for(;intf_it != AmConfig::SysIfs.end(); ++intf_it) {
923
+
924
+      list<AmConfig::IPAddr>::iterator addr_it = intf_it->addrs.begin();
925
+      for(;addr_it != intf_it->addrs.end(); addr_it++) {
926
+	if(addr_it->addr == AmConfig::SIP_Ifs[idx].LocalIP)
927
+	  break;
928
+      }
929
+
930
+      // address not in this interface
931
+      if(addr_it == intf_it->addrs.end())
932
+	continue;
933
+
934
+      // address is primary
935
+      if(addr_it == intf_it->addrs.begin())
936
+	continue;
937
+
938
+      if(AmConfig::LocalSIPIP2If.find(intf_it->addrs.front().addr)
939
+	 == AmConfig::LocalSIPIP2If.end()) {
940
+	
941
+	AmConfig::LocalSIPIP2If[intf_it->addrs.front().addr] = idx;
942
+      }
943
+    }
944
+  }
945
+
804 946
   return true;
805 947
 }
806 948
 
807 949
 /** Get the AF_INET[6] address associated with the network interface */
808 950
 string fixIface2IP(const string& dev_name, bool v6_for_sip)
809 951
 {
810
-  string local_ip;
811
-
812 952
   struct sockaddr_storage ss;
813 953
   if(am_inet_pton(dev_name.c_str(), &ss)) {
814 954
     if(v6_for_sip && (ss.ss_family == AF_INET6) && (dev_name[0] != '['))
... ...
@@ -820,112 +960,129 @@ string fixIface2IP(const string& dev_name, bool v6_for_sip)
820 960
   for(list<AmConfig::SysIntf>::iterator intf_it = AmConfig::SysIfs.begin();
821 961
       intf_it != AmConfig::SysIfs.end(); ++intf_it) {
822 962
       
823
-    if((!dev_name.empty() && (intf_it->name == dev_name))
824
-       || (dev_name.empty() && !(intf_it->flags & IFF_LOOPBACK))) {
963
+    if(intf_it->name != dev_name)
964
+      continue;
825 965
 
826
-      if(intf_it->addrs.empty()){
827
-	ERROR("No IP address for interface '%s'\n",intf_it->name.c_str());
828
-	return "";
829
-      }
830
-      
831
-      DBG("dev_name = '%s'\n", dev_name.c_str());
832
-      const AmConfig::IPAddr& ip = intf_it->addrs.front();
833
-      if(v6_for_sip && (ip.family == AF_INET6))
834
-	local_ip = "[" + ip.addr + "]";
835
-      else
836
-	local_ip = ip.addr;
837
-      break;
966
+    if(intf_it->addrs.empty()){
967
+      ERROR("No IP address for interface '%s'\n",intf_it->name.c_str());
968
+      return "";
838 969
     }
970
+      
971
+    DBG("dev_name = '%s'\n",dev_name.c_str());
972
+    return intf_it->addrs.front().addr;
839 973
   }    
840 974
 
841
-  return local_ip;
975
+  return "";
842 976
 }
843 977
 
844
-int AmConfig::finalizeIPConfig()
978
+/** Get IP addrese from first non-loopback interface */
979
+static string getDefaultIP()
845 980
 {
846
-  fillSysIntfList();
847
-
848
-  for(int i=0; i < (int)AmConfig::Ifs.size(); i++) {
981
+  for(list<AmConfig::SysIntf>::iterator intf_it = AmConfig::SysIfs.begin();
982
+      intf_it != AmConfig::SysIfs.end(); ++intf_it) {
983
+      
984
+    if(intf_it->flags & IFF_LOOPBACK)
985
+      continue;
849 986
 
850
-    AmConfig::Ifs[i].LocalIP = fixIface2IP(AmConfig::Ifs[i].LocalIP,false);
851
-    if (AmConfig::Ifs[i].LocalIP.empty()) {
852
-      ERROR("Cannot determine proper local address for media advertising!\n"
853
-	    "Try using 'ifconfig -a' to find a proper interface and configure SEMS to use it.\n");
854
-      return -1;
855
-    }
856
-    
857
-    if (AmConfig::Ifs[i].LocalSIPIP.empty()) {
858
-      AmConfig::Ifs[i].LocalSIPIP = fixIface2IP(AmConfig::Ifs[i].LocalIP,true);
859
-    }
860
-    else {
861
-      AmConfig::Ifs[i].LocalSIPIP = fixIface2IP(AmConfig::Ifs[i].LocalSIPIP,true);
862
-    }
987
+    if(intf_it->addrs.empty())
988
+      continue;
863 989
 
864
-    list<AmConfig::SysIntf>::iterator intf_it = AmConfig::SysIfs.begin();
865
-    for(;intf_it != AmConfig::SysIfs.end(); ++intf_it) {
990
+    DBG("dev_name = '%s'\n",intf_it->name.c_str());
991
+    return intf_it->addrs.front().addr;
992
+  }
866 993
 
867
-      list<AmConfig::IPAddr>::iterator addr_it = intf_it->addrs.begin();
868
-      for(;addr_it != intf_it->addrs.end(); addr_it++) {
994
+  return "";
995
+}
869 996
 
870
-	if(AmConfig::Ifs[i].LocalSIPIP == addr_it->addr)
871
-	  break;
997
+static int setNetInterface(AmConfig::IP_interface* ip_if)
998
+{
999
+  for(list<AmConfig::SysIntf>::iterator sys_it = AmConfig::SysIfs.begin();
1000
+      sys_it != AmConfig::SysIfs.end(); sys_it++) {
1001
+    
1002
+    list<AmConfig::IPAddr>::iterator addr_it = sys_it->addrs.begin();
1003
+    while(addr_it != sys_it->addrs.end()) {
1004
+      if(ip_if->LocalIP == addr_it->addr) {
1005
+	ip_if->NetIf = sys_it->name;
1006
+	ip_if->NetIfIdx = if_nametoindex(sys_it->name.c_str());
1007
+	return 0;
872 1008
       }
1009
+      addr_it++;
1010
+    }
1011
+  }
1012
+  
1013
+  // not interface found
1014
+  return -1;
1015
+}
873 1016
 
874
-      // address not in this interface
875
-      if(addr_it == intf_it->addrs.end())
876
-	continue;
877
-
878
-      for(addr_it = intf_it->addrs.begin(); 
879
-	  addr_it != intf_it->addrs.end(); ++addr_it) {
1017
+int AmConfig::finalizeIPConfig()
1018
+{
1019
+  fillSysIntfList();
880 1020
 
881
-	if(AmConfig::LocalSIPIP2If.find(addr_it->addr)
882
-	   == AmConfig::LocalSIPIP2If.end()) {
883
-	
884
-	  AmConfig::LocalSIPIP2If.insert(make_pair(addr_it->addr,i));
885
-	}
886
-      }
1021
+  // replace system interface names with IPs
1022
+  for(vector<SIP_interface>::iterator it = SIP_Ifs.begin();
1023
+      it != SIP_Ifs.end(); it++) {
1024
+    
1025
+    it->LocalIP = fixIface2IP(it->LocalIP,true);
1026
+    if(it->LocalIP.empty()) {
1027
+      ERROR("could not determine signaling IP for "