moved IP related config to AmConfig

sayer/1.4-spce2.6
Raphael Coeffic 15 years ago
parent e3f48aba8c
commit 6aaeb6ece9

@ -27,8 +27,10 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netdb.h>
#include <stdio.h>
#include "AmConfig.h"
@ -41,6 +43,8 @@
#include <cctype>
#include <algorithm>
using std::make_pair;
string AmConfig::ConfigurationFile = CONFIG_FILE;
string AmConfig::ModConfigPath = MOD_CFG_PATH;
string AmConfig::PlugInPath = PLUG_IN_PATH;
@ -497,8 +501,6 @@ int AmConfig::readConfiguration()
}
}
INFO("100rel: %d.\n", AmConfig::rel100);
return ret;
}
@ -507,13 +509,6 @@ static int readInterface(AmConfigReader& cfg, const string& i_name)
int ret=0;
AmConfig::IP_interface intf;
intf.LocalSIPIP = "";
intf.LocalSIPPort = 5060;
intf.LocalIP = "";
intf.PublicIP = "";
intf.RtpLowPort = RTP_LOWPORT;
intf.RtpHighPort = RTP_HIGHPORT;
string suffix;
if(!i_name.empty())
suffix = "_" + i_name;
@ -523,8 +518,8 @@ static int readInterface(AmConfigReader& cfg, const string& i_name)
intf.LocalSIPIP = cfg.getParameter("sip_ip" + suffix);
}
else if(!suffix.empty()) {
ERROR("sip_ip%s parameter is required",suffix.c_str());
ret = -1;
ERROR("sip_ip%s parameter is required",suffix.c_str());
ret = -1;
}
if(cfg.hasParameter("sip_port" + suffix)){
@ -541,20 +536,16 @@ static int readInterface(AmConfigReader& cfg, const string& i_name)
if(cfg.hasParameter("media_ip" + suffix)) {
intf.LocalIP = cfg.getParameter("media_ip" + suffix);
}
else if(!suffix.empty()) {
ERROR("media_ip%s parameter is required",suffix.c_str());
ret = -1;
else if(!intf.LocalSIPIP.empty()) {
DBG("media_ip%s parameter is missing: using same as sip_ip%s",
suffix.c_str(),suffix.c_str());
intf.LocalIP = intf.LocalSIPIP;
}
// public_ip
if(cfg.hasParameter("public_ip" + suffix)){
string p_ip = cfg.getParameter("public_ip" + suffix);
DBG("Setting public_ip%s parameter to %s.\n", suffix.c_str(), p_ip.c_str());
intf.PublicIP = p_ip;
intf.PublicIP = cfg.getParameter("public_ip" + suffix);
}
//else {
// DBG("Config file has no public_ip%s parameter.",suffix.c_str());
//}
// rtp_low_port
if(cfg.hasParameter("rtp_low_port" + suffix)){
@ -579,9 +570,15 @@ static int readInterface(AmConfigReader& cfg, const string& i_name)
}
intf.name = i_name;
AmConfig::Ifs.push_back(intf);
AmConfig::LocalSIPIP2If.insert(std::make_pair(intf.LocalSIPIP,
AmConfig::Ifs.size()-1));
if(!suffix.empty()) {// !default Interface
AmConfig::Ifs.push_back(intf);
}
else {
AmConfig::Ifs[0] = intf;
}
AmConfig::If_names[i_name] = AmConfig::Ifs.size()-1;
return ret;
}
@ -590,8 +587,6 @@ static int readInterfaces(AmConfigReader& cfg)
{
int ret = 0;
AmConfig::Ifs.clear();
// read default params first
if(readInterface(cfg,"") < 0) {
return -1;
@ -610,27 +605,161 @@ static int readInterfaces(AmConfigReader& cfg)
if(readInterface(cfg,*it) < 0){
ret = -1;
}
if(AmConfig::Ifs.size() > 0)
AmConfig::If_names[*it] = AmConfig::Ifs.size()-1;
}
//debug
if(ret != -1) {
AmConfig::dump_Ifs();
return ret;
}
/** Get the list of network interfaces with the associated PF_INET addresses */
static bool getInterfaceList(int sd, std::vector<std::pair<string,string> >& if_list)
{
struct ifconf ifc;
struct ifreq ifrs[MAX_NET_DEVICES];
ifc.ifc_len = sizeof(struct ifreq) * MAX_NET_DEVICES;
ifc.ifc_req = ifrs;
memset(ifrs, 0, ifc.ifc_len);
if(ioctl(sd, SIOCGIFCONF, &ifc)!=0){
ERROR("getInterfaceList: ioctl: %s.\n", strerror(errno));
return false;
}
#if !defined(BSD44SOCKETS)
int n_dev = ifc.ifc_len / sizeof(struct ifreq);
for(int i=0; i<n_dev; i++){
if(ifrs[i].ifr_addr.sa_family==PF_INET){
struct sockaddr_in* sa = (struct sockaddr_in*)&ifrs[i].ifr_addr;
// avoid dereferencing type-punned pointer below
struct sockaddr_in sa4;
memcpy(&sa4, sa, sizeof(struct sockaddr_in));
if_list.push_back(make_pair((char*)ifrs[i].ifr_name,
inet_ntoa(sa4.sin_addr)));
}
}
#else // defined(BSD44SOCKETS)
struct ifreq* p_ifr = ifc.ifc_req;
while((char*)p_ifr - (char*)ifc.ifc_req < ifc.ifc_len){
return ret;
if(p_ifr->ifr_addr.sa_family == PF_INET){
struct sockaddr_in* sa = (struct sockaddr_in*)&p_ifr->ifr_addr;
if_list.push_back(make_pair((const char*)p_ifr->ifr_name,
inet_ntoa(sa->sin_addr)));
}
p_ifr = (struct ifreq*)(((char*)p_ifr) + IFNAMSIZ + p_ifr->ifr_addr.sa_len);
}
#endif
return true;
}
void AmConfig::dump_Ifs()
/** Get the PF_INET address associated with the network interface */
static string getLocalIP(const string& dev_name)
{
string local_ip;
struct ifreq ifr;
std::vector<std::pair<string,string> > if_list;
#ifdef SUPPORT_IPV6
struct sockaddr_storage ss;
if(inet_aton_v6(dev_name.c_str(), &ss))
#else
struct in_addr inp;
if(inet_aton(dev_name.c_str(), &inp))
#endif
{
return dev_name;
}
int sd = socket(PF_INET, SOCK_DGRAM, 0);
if(sd == -1){
ERROR("socket: %s.\n", strerror(errno));
goto error;
}
if(dev_name.empty()) {
if (!getInterfaceList(sd, if_list)) {
goto error;
}
}
else {
memset(&ifr, 0, sizeof(struct ifreq));
strncpy(ifr.ifr_name, dev_name.c_str(), IFNAMSIZ-1);
if(ioctl(sd, SIOCGIFADDR, &ifr)!=0){
ERROR("ioctl(SIOCGIFADDR): %s.\n", strerror(errno));
goto error;
}
if(ifr.ifr_addr.sa_family==PF_INET){
struct sockaddr_in* sa = (struct sockaddr_in*)&ifr.ifr_addr;
// avoid dereferencing type-punned pointer below
struct sockaddr_in sa4;
memcpy(&sa4, sa, sizeof(struct sockaddr_in));
if_list.push_back(make_pair((char*)ifr.ifr_name,
inet_ntoa(sa4.sin_addr)));
}
}
for( std::vector<std::pair<string,string> >::iterator it = if_list.begin();
it != if_list.end(); ++it) {
memset(&ifr, 0, sizeof(struct ifreq));
strncpy(ifr.ifr_name, it->first.c_str(), IFNAMSIZ-1);
if(ioctl(sd, SIOCGIFFLAGS, &ifr)!=0){
ERROR("ioctl(SIOCGIFFLAGS): %s.\n", strerror(errno));
goto error;
}
if( (ifr.ifr_flags & IFF_UP) &&
(!dev_name.empty() || !(ifr.ifr_flags & IFF_LOOPBACK)) ) {
local_ip = it->second;
break;
}
}
if(ifr.ifr_flags & IFF_LOOPBACK){
WARN("Media advertising using loopback address!\n"
"Try to use another network interface if your SEMS "
"should be accessible from the rest of the world.\n");
}
error:
close(sd);
return local_ip;
}
int AmConfig::finalizeIPConfig()
{
for(map<string,unsigned short>::iterator it = If_names.begin();
it != If_names.end(); it++) {
for(int i=0; i < (int)AmConfig::Ifs.size(); i++) {
AmConfig::Ifs[i].LocalIP = getLocalIP(AmConfig::Ifs[i].LocalIP);
if (AmConfig::Ifs[i].LocalIP.empty()) {
ERROR("Cannot determine proper local address for media advertising!\n"
"Try using 'ifconfig -a' to find a proper interface and configure SEMS to use it.\n");
return -1;
}
INFO("Interface: '%s'",it->first.c_str());
if (AmConfig::Ifs[i].LocalSIPIP.empty()) {
AmConfig::Ifs[i].LocalSIPIP = AmConfig::Ifs[i].LocalIP;
}
IP_interface& it_ref = Ifs[it->second];
AmConfig::LocalSIPIP2If.insert(std::make_pair(AmConfig::Ifs[i].LocalSIPIP,i));
}
return 0;
}
void AmConfig::dump_Ifs()
{
for(int i=0; i<(int)Ifs.size(); i++) {
IP_interface& it_ref = Ifs[i];
INFO("Interface: '%s' (%i)",it_ref.name.c_str(),i);
INFO("\tLocalIP='%s'",it_ref.LocalIP.c_str());
INFO("\tPublicIP='%s'",it_ref.PublicIP.c_str());
INFO("\tLocalSIPIP='%s'",it_ref.LocalSIPIP.c_str());
@ -642,6 +771,7 @@ void AmConfig::dump_Ifs()
INFO("Signaling address map:");
for(multimap<string,unsigned short>::iterator it = LocalSIPIP2If.begin();
it != LocalSIPIP2If.end(); ++it) {
if(Ifs[it->second].name.empty()){
INFO("\t%s -> default",it->first.c_str());
}

@ -112,31 +112,9 @@ struct AmConfig
static map<string,unsigned short> If_names;
static multimap<string,unsigned short> LocalSIPIP2If;
static void dump_Ifs();
static string& LocalIP() {
return (Ifs[0].LocalIP);
}
static string& PublicIP() {
return (Ifs[0].PublicIP);
}
static int& RtpLowPort() {
return (Ifs[0].RtpLowPort);
}
static int finalizeIPConfig();
static int& RtpHighPort() {
return (Ifs[0].RtpHighPort);
}
static string& LocalSIPIP() {
return (Ifs[0].LocalSIPIP);
}
static int& LocalSIPPort() {
return (Ifs[0].LocalSIPPort);
}
static void dump_Ifs();
/** number of session (signaling/application) processor threads */
static int SessionProcessorThreads;

@ -111,7 +111,7 @@ rtp_high_port=60000
# suffixed with the interface name should be defined.
#
# Please note that for each additional interface,
# 'sip_ip' and 'media_ip' are mandatory. The other
# 'sip_ip' is mandatory. The other
# parameters are optional.
#
# Example:

@ -111,7 +111,7 @@ rtp_high_port=60000
# suffixed with the interface name should be defined.
#
# Please note that for each additional interface,
# 'sip_ip' and 'media_ip' are mandatory. The other
# 'sip_ip' is mandatory. The other
# parameters are optional.
#
# Example:

@ -51,20 +51,14 @@
#include <grp.h>
#include <pwd.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
//#include <sys/wait.h>
//#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string>
using std::string;
using std::make_pair;
const char* progname = NULL; /**< Program name (actually argv[0])*/
@ -145,7 +139,7 @@ static bool apply_args(std::map<char,string>& args)
switch( it->first ){
case 'd':
AmConfig::LocalIP() = it->second;
AmConfig::Ifs[0].LocalIP = it->second;
break;
case 'D':
@ -283,127 +277,6 @@ static int write_pid_file()
#endif /* !DISABLE_DAEMON_MODE */
/** Get the list of network interfaces with the associated PF_INET addresses */
static bool getInterfaceList(int sd, std::vector<std::pair<string,string> >& if_list)
{
struct ifconf ifc;
struct ifreq ifrs[MAX_NET_DEVICES];
ifc.ifc_len = sizeof(struct ifreq) * MAX_NET_DEVICES;
ifc.ifc_req = ifrs;
memset(ifrs, 0, ifc.ifc_len);
if(ioctl(sd, SIOCGIFCONF, &ifc)!=0){
ERROR("getInterfaceList: ioctl: %s.\n", strerror(errno));
return false;
}
#if !defined(BSD44SOCKETS)
int n_dev = ifc.ifc_len / sizeof(struct ifreq);
for(int i=0; i<n_dev; i++){
if(ifrs[i].ifr_addr.sa_family==PF_INET){
struct sockaddr_in* sa = (struct sockaddr_in*)&ifrs[i].ifr_addr;
// avoid dereferencing type-punned pointer below
struct sockaddr_in sa4;
memcpy(&sa4, sa, sizeof(struct sockaddr_in));
if_list.push_back(make_pair((char*)ifrs[i].ifr_name,
inet_ntoa(sa4.sin_addr)));
}
}
#else // defined(BSD44SOCKETS)
struct ifreq* p_ifr = ifc.ifc_req;
while((char*)p_ifr - (char*)ifc.ifc_req < ifc.ifc_len){
if(p_ifr->ifr_addr.sa_family == PF_INET){
struct sockaddr_in* sa = (struct sockaddr_in*)&p_ifr->ifr_addr;
if_list.push_back(make_pair((const char*)p_ifr->ifr_name,
inet_ntoa(sa->sin_addr)));
}
p_ifr = (struct ifreq*)(((char*)p_ifr) + IFNAMSIZ + p_ifr->ifr_addr.sa_len);
}
#endif
return true;
}
/** Get the PF_INET address associated with the network interface */
static string getLocalIP(const string& dev_name)
{
string local_ip;
struct ifreq ifr;
std::vector<std::pair<string,string> > if_list;
#ifdef SUPPORT_IPV6
struct sockaddr_storage ss;
if(inet_aton_v6(dev_name.c_str(), &ss))
#else
struct in_addr inp;
if(inet_aton(dev_name.c_str(), &inp))
#endif
{
return dev_name;
}
int sd = socket(PF_INET, SOCK_DGRAM, 0);
if(sd == -1){
ERROR("socket: %s.\n", strerror(errno));
goto error;
}
if(dev_name.empty()) {
if (!getInterfaceList(sd, if_list)) {
goto error;
}
}
else {
memset(&ifr, 0, sizeof(struct ifreq));
strncpy(ifr.ifr_name, dev_name.c_str(), IFNAMSIZ-1);
if(ioctl(sd, SIOCGIFADDR, &ifr)!=0){
ERROR("ioctl(SIOCGIFADDR): %s.\n", strerror(errno));
goto error;
}
if(ifr.ifr_addr.sa_family==PF_INET){
struct sockaddr_in* sa = (struct sockaddr_in*)&ifr.ifr_addr;
// avoid dereferencing type-punned pointer below
struct sockaddr_in sa4;
memcpy(&sa4, sa, sizeof(struct sockaddr_in));
if_list.push_back(make_pair((char*)ifr.ifr_name,
inet_ntoa(sa4.sin_addr)));
}
}
for( std::vector<std::pair<string,string> >::iterator it = if_list.begin();
it != if_list.end(); ++it) {
memset(&ifr, 0, sizeof(struct ifreq));
strncpy(ifr.ifr_name, it->first.c_str(), IFNAMSIZ-1);
if(ioctl(sd, SIOCGIFFLAGS, &ifr)!=0){
ERROR("ioctl(SIOCGIFFLAGS): %s.\n", strerror(errno));
goto error;
}
if( (ifr.ifr_flags & IFF_UP) &&
(!dev_name.empty() || !(ifr.ifr_flags & IFF_LOOPBACK)) ) {
local_ip = it->second;
break;
}
}
if(ifr.ifr_flags & IFF_LOOPBACK){
WARN("Media advertising using loopback address!\n"
"Try to use another network interface if your SEMS "
"should be accessible from the rest of the world.\n");
}
error:
close(sd);
return local_ip;
}
/*
* Main
@ -431,6 +304,9 @@ int main(int argc, char* argv[])
return 0;
}
// Init default interface
AmConfig::Ifs.push_back(AmConfig::IP_interface());
/* apply command-line options */
if(!apply_args(args)){
print_usage(true);
@ -453,16 +329,8 @@ int main(int argc, char* argv[])
goto error;
}
AmConfig::LocalIP() = getLocalIP(AmConfig::LocalIP());
if (AmConfig::LocalIP().empty()) {
ERROR("Cannot determine proper local address for media advertising!\n"
"Try using 'ifconfig -a' to find a proper interface and configure SEMS to use it.\n");
if(AmConfig::finalizeIPConfig() < 0)
goto error;
}
if (AmConfig::LocalSIPIP().empty()) {
AmConfig::LocalSIPIP() = AmConfig::LocalIP();
}
printf("Configuration:\n"
#ifdef _DEBUG
@ -476,11 +344,6 @@ int main(int argc, char* argv[])
" daemon UID: %s\n"
" daemon GID: %s\n"
#endif
" local SIP IP: %s\n"
" public media IP: %s\n"
" local SIP port: %i\n"
" local media IP: %s\n"
" out-bound proxy: %s\n"
" application: %s\n"
"\n",
#ifdef _DEBUG
@ -494,13 +357,10 @@ int main(int argc, char* argv[])
AmConfig::DaemonUid.empty() ? "<not set>" : AmConfig::DaemonUid.c_str(),
AmConfig::DaemonGid.empty() ? "<not set>" : AmConfig::DaemonGid.c_str(),
#endif
AmConfig::LocalSIPIP().c_str(),
AmConfig::PublicIP().c_str(),
AmConfig::LocalSIPPort(),
AmConfig::LocalIP().c_str(),
AmConfig::OutboundProxy.c_str(),
AmConfig::Application.empty() ? "<not set>" : AmConfig::Application.c_str());
AmConfig::dump_Ifs();
#ifndef DISABLE_DAEMON_MODE
if(AmConfig::DaemonMode){

Loading…
Cancel
Save