diff --git a/sflphone-common/src/account.h b/sflphone-common/src/account.h index d3c61eecc12624b0069b5c43a9069ac79c07a397..6a37fe01347c0a1e2be32cc978a00a77bd520a45 100644 --- a/sflphone-common/src/account.h +++ b/sflphone-common/src/account.h @@ -70,6 +70,14 @@ typedef enum RegistrationState { #define REALM "realm" #define DEFAULT_REALM "*" +#define LOCAL_PORT "Account.localPort" +#define LOCAL_ADDRESS "Account.localAddress" +#define PUBLISHED_PORT "Account.publishedPort" +#define PUBLISHED_ADDRESS "Account.publishedAddress" + +#define DISPLAY_NAME "Account.displayName" +#define DEFAULT_ADDRESS "0.0.0.0" + // SIP specific parameters #define SIP_PROXY "SIP.proxy" #define SIP_STUN_SERVER "STUN.server" @@ -86,7 +94,6 @@ typedef enum RegistrationState { #define ZRTP_DISPLAY_SAS_ONCE "ZRTP.displaySasOnce" #define TLS_ENABLE "TLS.enable" -#define TLS_PORT "TLS.port" #define TLS_CA_LIST_FILE "TLS.certificateListFile" #define TLS_CERTIFICATE_FILE "TLS.certificateFile" #define TLS_PRIVATE_KEY_FILE "TLS.privateKeyFile" diff --git a/sflphone-common/src/dbus/configurationmanager.cpp b/sflphone-common/src/dbus/configurationmanager.cpp index 5a3069cb6292332a72f9ea23e95ab344f6f25559..10311054121ef8d28093b8ffbbe0fb9eda3e309e 100644 --- a/sflphone-common/src/dbus/configurationmanager.cpp +++ b/sflphone-common/src/dbus/configurationmanager.cpp @@ -47,7 +47,6 @@ ConfigurationManager::getTlsSettingsDefault (void) _debug ("ConfigurationManager::getTlsDefaultSettings\n"); std::map<std::string, std::string> tlsSettingsDefault; - tlsSettingsDefault.insert(std::pair<std::string, std::string> (TLS_PORT, DEFAULT_SIP_TLS_PORT)); tlsSettingsDefault.insert(std::pair<std::string, std::string> (TLS_CA_LIST_FILE, "")); tlsSettingsDefault.insert(std::pair<std::string, std::string> (TLS_CERTIFICATE_FILE, "")); tlsSettingsDefault.insert(std::pair<std::string, std::string> (TLS_PRIVATE_KEY_FILE, "")); @@ -128,9 +127,7 @@ ConfigurationManager::getTlsSettings(const std::string& section) { std::map<std::string, std::string> tlsSettings; tlsSettings.insert(std::pair<std::string, std::string> - (TLS_ENABLE, Manager::instance().getConfigString(section, TLS_ENABLE))); - tlsSettings.insert(std::pair<std::string, std::string> - (TLS_PORT, Manager::instance().getConfigString(section, TLS_PORT))); + (TLS_ENABLE, Manager::instance().getConfigString(section, TLS_ENABLE))); tlsSettings.insert(std::pair<std::string, std::string> (TLS_CA_LIST_FILE, Manager::instance().getConfigString(section, TLS_CA_LIST_FILE))); tlsSettings.insert(std::pair<std::string, std::string> @@ -168,12 +165,7 @@ ConfigurationManager::setTlsSettings(const std::string& section, const std::map< if (it != details.end()) { Manager::instance().setConfig(section, TLS_ENABLE, it->second); } - - it = map_cpy.find(TLS_PORT); - if (it != details.end()) { - Manager::instance().setConfig(section, TLS_PORT, it->second); - } - + it = map_cpy.find(TLS_CA_LIST_FILE); if (it != details.end()) { Manager::instance().setConfig(section, TLS_CA_LIST_FILE, it->second); diff --git a/sflphone-common/src/managerimpl.cpp b/sflphone-common/src/managerimpl.cpp index a70fc654d4a25bea101aabe0a6901b432790f3d6..215f96ae7b48cfe65d9caf3a57d4c169dc67f54b 100644 --- a/sflphone-common/src/managerimpl.cpp +++ b/sflphone-common/src/managerimpl.cpp @@ -47,7 +47,7 @@ #include <sstream> #include <sys/types.h> // mkdir(2) #include <sys/stat.h> // mkdir(2) - +#include <pwd.h> // getpwuid #define fill_config_str(name, value) \ (_config.addConfigTreeItem(section, Conf::ConfigTreeItem(std::string(name), std::string(value), type_str))) @@ -1260,7 +1260,7 @@ ManagerImpl::getStunInfo (StunAddress4& stunSvrAddr, int port) } bool -ManagerImpl::behindNat (const std::string& svr, int port) +ManagerImpl::isBehindNat (const std::string& svr, int port) { StunAddress4 stunSvrAddr; stunSvrAddr.addr = 0; @@ -1341,7 +1341,6 @@ ManagerImpl::initConfigFile (bool load_user_value, std::string alternate) _config.addDefaultValue(std::pair<std::string, std::string> (ZRTP_DISPLAY_SAS_ONCE, FALSE_STR), IP2IP_PROFILE); _config.addDefaultValue(std::pair<std::string, std::string> (ZRTP_NOT_SUPP_WARNING, TRUE_STR), IP2IP_PROFILE); _config.addDefaultValue(std::pair<std::string, std::string> (TLS_ENABLE, FALSE_STR), IP2IP_PROFILE); - _config.addDefaultValue(std::pair<std::string, std::string> (TLS_PORT, DEFAULT_SIP_TLS_PORT), IP2IP_PROFILE); _config.addDefaultValue(std::pair<std::string, std::string> (TLS_CA_LIST_FILE, EMPTY_FIELD), IP2IP_PROFILE); _config.addDefaultValue(std::pair<std::string, std::string> (TLS_CERTIFICATE_FILE, EMPTY_FIELD), IP2IP_PROFILE); _config.addDefaultValue(std::pair<std::string, std::string> (TLS_PRIVATE_KEY_FILE, EMPTY_FIELD), IP2IP_PROFILE); @@ -1353,7 +1352,22 @@ ManagerImpl::initConfigFile (bool load_user_value, std::string alternate) _config.addDefaultValue(std::pair<std::string, std::string> (TLS_VERIFY_CLIENT, TRUE_STR), IP2IP_PROFILE); _config.addDefaultValue(std::pair<std::string, std::string> (TLS_REQUIRE_CLIENT_CERTIFICATE, TRUE_STR), IP2IP_PROFILE); _config.addDefaultValue(std::pair<std::string, std::string> (TLS_NEGOTIATION_TIMEOUT_SEC, "2"), IP2IP_PROFILE); - _config.addDefaultValue(std::pair<std::string, std::string> (TLS_NEGOTIATION_TIMEOUT_MSEC, "0"), IP2IP_PROFILE); + _config.addDefaultValue(std::pair<std::string, std::string> (TLS_NEGOTIATION_TIMEOUT_MSEC, "0"), IP2IP_PROFILE); + _config.addDefaultValue(std::pair<std::string, std::string> (LOCAL_PORT, DEFAULT_SIP_PORT), IP2IP_PROFILE); + _config.addDefaultValue(std::pair<std::string, std::string> (PUBLISHED_PORT, DEFAULT_SIP_PORT), IP2IP_PROFILE); + _config.addDefaultValue(std::pair<std::string, std::string> (LOCAL_ADDRESS, DEFAULT_ADDRESS), IP2IP_PROFILE); + _config.addDefaultValue(std::pair<std::string, std::string> (PUBLISHED_ADDRESS, DEFAULT_ADDRESS), IP2IP_PROFILE); + + // Init display name to the username under which + // this sflphone instance is running. + std::string diplayName(""); + uid_t uid = getuid(); + struct passwd * user_info = NULL; + user_info = getpwuid(uid); + if (user_info != NULL) { + diplayName = user_info->pw_name; + } + _config.addDefaultValue(std::pair<std::string, std::string> (DISPLAY_NAME, diplayName), IP2IP_PROFILE); // Signalisation settings _config.addDefaultValue(std::pair<std::string, std::string> (SYMMETRIC, TRUE_STR), SIGNALISATION); @@ -2543,6 +2557,11 @@ std::map< std::string, std::string > ManagerImpl::getAccountDetails (const Accou a.insert(std::pair<std::string, std::string> (AUTHENTICATION_USERNAME, getConfigString(accountID, AUTHENTICATION_USERNAME))); a.insert(std::pair<std::string, std::string> (CONFIG_ACCOUNT_MAILBOX, getConfigString(accountID, CONFIG_ACCOUNT_MAILBOX))); a.insert(std::pair<std::string, std::string> (CONFIG_ACCOUNT_REGISTRATION_EXPIRE, getConfigString(accountID, CONFIG_ACCOUNT_REGISTRATION_EXPIRE))); + a.insert(std::pair<std::string, std::string> (LOCAL_ADDRESS, getConfigString(accountID, LOCAL_ADDRESS))); + a.insert(std::pair<std::string, std::string> (PUBLISHED_ADDRESS, getConfigString(accountID, PUBLISHED_ADDRESS))); + a.insert(std::pair<std::string, std::string> (LOCAL_PORT, getConfigString(accountID, LOCAL_PORT))); + a.insert(std::pair<std::string, std::string> (PUBLISHED_PORT, getConfigString(accountID, PUBLISHED_PORT))); + a.insert(std::pair<std::string, std::string> (DISPLAY_NAME, getConfigString(accountID, DISPLAY_NAME))); RegistrationState state; state = account->getRegistrationState(); @@ -2555,7 +2574,6 @@ std::map< std::string, std::string > ManagerImpl::getAccountDetails (const Accou a.insert(std::pair<std::string, std::string> (ZRTP_NOT_SUPP_WARNING, getConfigString(accountID, ZRTP_NOT_SUPP_WARNING))); a.insert(std::pair<std::string, std::string> (TLS_ENABLE, Manager::instance().getConfigString(accountID, TLS_ENABLE))); - a.insert(std::pair<std::string, std::string> (TLS_PORT, Manager::instance().getConfigString(accountID, TLS_PORT))); a.insert(std::pair<std::string, std::string> (TLS_CA_LIST_FILE, Manager::instance().getConfigString(accountID, TLS_CA_LIST_FILE))); a.insert(std::pair<std::string, std::string> (TLS_CERTIFICATE_FILE, Manager::instance().getConfigString(accountID, TLS_CERTIFICATE_FILE))); a.insert(std::pair<std::string, std::string> (TLS_PRIVATE_KEY_FILE, Manager::instance().getConfigString(accountID, TLS_PRIVATE_KEY_FILE))); @@ -2728,6 +2746,11 @@ void ManagerImpl::setAccountDetails (const std::string& accountID, const std::ma std::string registrationExpire; std::string hostname; + std::string displayName; + std::string localAddress; + std::string publishedAddress; + std::string localPort; + std::string publishedPort; std::string srtpEnable; std::string zrtpDisplaySas; std::string zrtpDisplaySasOnce; @@ -2735,8 +2758,7 @@ void ManagerImpl::setAccountDetails (const std::string& accountID, const std::ma std::string zrtpHelloHash; std::string srtpKeyExchange; - std::string tlsEnable; - std::string tlsPort; + std::string tlsEnable; std::string tlsCaListFile; std::string tlsCertificateFile; std::string tlsPrivateKeyFile; @@ -2751,6 +2773,11 @@ void ManagerImpl::setAccountDetails (const std::string& accountID, const std::ma std::string tlsNegotiationTimeoutMsec; if((iter = map_cpy.find(HOSTNAME)) != map_cpy.end()) { hostname = iter->second; } + if((iter = map_cpy.find(DISPLAY_NAME)) != map_cpy.end()) { displayName = iter->second; } + if((iter = map_cpy.find(LOCAL_ADDRESS)) != map_cpy.end()) { localAddress = iter->second; } + if((iter = map_cpy.find(PUBLISHED_ADDRESS)) != map_cpy.end()) { publishedAddress = iter->second; } + if((iter = map_cpy.find(LOCAL_PORT)) != map_cpy.end()) { localPort = iter->second; } + if((iter = map_cpy.find(PUBLISHED_PORT)) != map_cpy.end()) { publishedPort = iter->second; } if((iter = map_cpy.find(SRTP_ENABLE)) != map_cpy.end()) { srtpEnable = iter->second; } if((iter = map_cpy.find(ZRTP_DISPLAY_SAS)) != map_cpy.end()) { zrtpDisplaySas = iter->second; } if((iter = map_cpy.find(ZRTP_DISPLAY_SAS_ONCE)) != map_cpy.end()) { zrtpDisplaySasOnce = iter->second; } @@ -2766,7 +2793,6 @@ void ManagerImpl::setAccountDetails (const std::string& accountID, const std::ma if((iter = map_cpy.find(CONFIG_ACCOUNT_REGISTRATION_EXPIRE)) != map_cpy.end()) { registrationExpire = iter->second; } if((iter = map_cpy.find(TLS_ENABLE)) != map_cpy.end()) { tlsEnable = iter->second; } - if((iter = map_cpy.find(TLS_PORT)) != map_cpy.end()) { tlsPort = iter->second; } if((iter = map_cpy.find(TLS_CA_LIST_FILE)) != map_cpy.end()) { tlsCaListFile = iter->second; } if((iter = map_cpy.find(TLS_CERTIFICATE_FILE)) != map_cpy.end()) { tlsCertificateFile = iter->second; } if((iter = map_cpy.find(TLS_PRIVATE_KEY_FILE)) != map_cpy.end()) { tlsPrivateKeyFile = iter->second; } @@ -2781,7 +2807,12 @@ void ManagerImpl::setAccountDetails (const std::string& accountID, const std::ma if((iter = map_cpy.find(TLS_NEGOTIATION_TIMEOUT_MSEC)) != map_cpy.end()) { tlsNegotiationTimeoutMsec = iter->second; } _debug("Enable account %s\n", accountEnable.c_str()); - setConfig(accountID, HOSTNAME, hostname); + setConfig(accountID, HOSTNAME, hostname); + setConfig(accountID, LOCAL_ADDRESS, localAddress); + setConfig(accountID, PUBLISHED_ADDRESS, publishedAddress); + setConfig(accountID, LOCAL_PORT, localPort); + setConfig(accountID, PUBLISHED_PORT, publishedPort); + setConfig(accountID, DISPLAY_NAME, displayName); setConfig(accountID, SRTP_ENABLE, srtpEnable); setConfig(accountID, ZRTP_DISPLAY_SAS, zrtpDisplaySas); setConfig(accountID, ZRTP_DISPLAY_SAS_ONCE, zrtpDisplaySasOnce); @@ -2790,7 +2821,6 @@ void ManagerImpl::setAccountDetails (const std::string& accountID, const std::ma setConfig(accountID, SRTP_KEY_EXCHANGE, srtpKeyExchange); setConfig(accountID, TLS_ENABLE, tlsEnable); - setConfig(accountID, TLS_PORT, tlsPort); setConfig(accountID, TLS_CA_LIST_FILE, tlsCaListFile); setConfig(accountID, TLS_CERTIFICATE_FILE, tlsCertificateFile); setConfig(accountID, TLS_PRIVATE_KEY_FILE, tlsPrivateKeyFile); @@ -3068,12 +3098,14 @@ ManagerImpl::loadAccountMap() // registration. This is useful since the Account object // provides a handful of method that simplifies URI creation // and loading of various settings. - // _directIpAccount = AccountCreator::createAccount (AccountCreator::SIP_DIRECT_IP_ACCOUNT, ""); if (_directIpAccount == NULL) { _debug("Failed to create direct ip calls \"account\"\n"); } else { - _directIpAccount->registerVoIPLink(); + // Force the options to be loaded + // No registration in the sense of + // the REGISTER method is performed. + _directIpAccount->registerVoIPLink(); } _debug ("nbAccount loaded %i \n",nbAccount); diff --git a/sflphone-common/src/managerimpl.h b/sflphone-common/src/managerimpl.h index 394696961f214247b1117ddea2ede4d7650a810f..2b9d78bb90c08572e77dd74c907c208b6361b76c 100644 --- a/sflphone-common/src/managerimpl.h +++ b/sflphone-common/src/managerimpl.h @@ -904,7 +904,7 @@ class ManagerImpl { * @param port On which port we want to listen to * @return true if we are behind a NAT (without error) */ - bool behindNat(const std::string& svr, int port); + bool isBehindNat(const std::string& svr, int port); /** * Init default values for the different fields in the config file. diff --git a/sflphone-common/src/sip/sipaccount.cpp b/sflphone-common/src/sip/sipaccount.cpp index 5c5f24c364e5f40ab1eef287945feff7735dcc17..ed04e13e39d78f5db73948fd5056a94d96da2a8a 100644 --- a/sflphone-common/src/sip/sipaccount.cpp +++ b/sflphone-common/src/sip/sipaccount.cpp @@ -26,15 +26,21 @@ SIPAccount::SIPAccount (const AccountID& accountID) : Account (accountID, "sip") - , _cred (NULL) - , _regc() - , _bRegister (false) - , _resolveOnce (false) - , _contact ("") - , _displayName ("") - , _tlsSetting (NULL) - , _port(DFT_SIP_PORT) - , _transportType(PJSIP_TRANSPORT_UNSPECIFIED) + , _regc(NULL) + , _bRegister(false) + , _registrationExpire("") + , _localIpAddress("") + , _publishedIpAddress("") + , _localPort(atoi(DEFAULT_SIP_PORT)) + , _publishedPort(atoi(DEFAULT_SIP_PORT)) + , _transportType (PJSIP_TRANSPORT_UNSPECIFIED) + , _resolveOnce(false) + , _credentialCount(0) + , _cred(NULL) + , _realm(DEFAULT_REALM) + , _authenticationUsername("") + , _tlsSetting(NULL) + , _displayName("") { /* SIPVoIPlink is used as a singleton, because we want to have only one link for all the SIP accounts created */ /* So instead of creating a new instance, we just fetch the static instance, or create one if it is not yet */ @@ -134,7 +140,6 @@ int SIPAccount::registerVoIPLink() // Init TLS settings if the user wants to use TLS bool tlsEnabled = Manager::instance().getConfigBool(_accountID, TLS_ENABLE); if (tlsEnabled) { - _port = (pj_uint16_t) Manager::instance().getConfigInt(_accountID, TLS_PORT); _transportType = PJSIP_TRANSPORT_TLS; initTlsConfiguration(); } @@ -221,23 +226,33 @@ void SIPAccount::initTlsConfiguration(void) } void SIPAccount::loadConfig() -{ - // Init general account settings - setHostname (Manager::instance().getConfigString (_accountID, HOSTNAME)); +{ + // Load primary credential setUsername (Manager::instance().getConfigString (_accountID, USERNAME)); setPassword (Manager::instance().getConfigString (_accountID, PASSWORD)); - _authenticationUsername = Manager::instance().getConfigString (_accountID, AUTHENTICATION_USERNAME); _realm = Manager::instance().getConfigString (_accountID, REALM); _resolveOnce = Manager::instance().getConfigString (_accountID, CONFIG_ACCOUNT_RESOLVE_ONCE) == "1" ? true : false; + // Load general account settings + setHostname (Manager::instance().getConfigString (_accountID, HOSTNAME)); if (Manager::instance().getConfigString (_accountID, CONFIG_ACCOUNT_REGISTRATION_EXPIRE).empty()) { _registrationExpire = DFT_EXPIRE_VALUE; } else { _registrationExpire = Manager::instance().getConfigString (_accountID, CONFIG_ACCOUNT_REGISTRATION_EXPIRE); } - _port = Manager::instance().getSipPort(); + // Load network settings + std::string localPort = Manager::instance().getConfigString(_accountID, LOCAL_PORT); + std::string publishedPort = Manager::instance().getConfigString(_accountID, PUBLISHED_PORT); + std::stringstream ss; + ss << localPort; + ss >> _localPort; + ss << publishedPort; + ss >> _publishedPort; + + _localIpAddress = Manager::instance().getConfigString(_accountID, LOCAL_ADDRESS); + _publishedIpAddress = Manager::instance().getConfigString(_accountID, PUBLISHED_ADDRESS); _transportType = PJSIP_TRANSPORT_UDP; // Account generic @@ -421,4 +436,3 @@ std::string SIPAccount::getContactHeader(const std::string& address, const std:: return std::string(contact, len); } - diff --git a/sflphone-common/src/sip/sipaccount.h b/sflphone-common/src/sip/sipaccount.h index 7412b7170c935bc5896e1e81b9344dc0656d0875..6375f986b84d72a86db089c1070d089b04d73dea 100644 --- a/sflphone-common/src/sip/sipaccount.h +++ b/sflphone-common/src/sip/sipaccount.h @@ -73,10 +73,7 @@ class SIPAccount : public Account inline void setCredInfo(pjsip_cred_info *cred) {_cred = cred;} inline pjsip_cred_info *getCredInfo() {return _cred;} - - inline void setContact(const std::string &contact) {_contact = contact;} - inline std::string getContact() {return _contact;} - + inline std::string& getAuthenticationUsername(void) { return _authenticationUsername; } inline void setAuthenticationUsername(const std::string& username) { _authenticationUsername = username; } @@ -87,20 +84,49 @@ class SIPAccount : public Account bool fullMatch(const std::string& username, const std::string& hostname); bool userMatch(const std::string& username); bool hostnameMatch(const std::string& hostname); - - pjsip_regc* getRegistrationInfo( void ) { return _regc; } - void setRegistrationInfo( pjsip_regc *regc ) { _regc = regc; } - - inline int getCredentialCount(void) { return _credentialCount; } /* Registration flag */ bool isRegister() {return _bRegister;} void setRegister(bool result) {_bRegister = result;} + /** + * Get the registration stucture that is used + * for PJSIP in the registration process. + * Settings are loaded from configuration file. + * @param void + * @return pjsip_regc* A pointer to the registration structure + */ + pjsip_regc* getRegistrationInfo( void ) { return _regc; } + + /** + * Set the registration structure that is used + * for PJSIP in the registration process; + * @pram A pointer to the new registration structure + * @return void + */ + void setRegistrationInfo( pjsip_regc *regc ) { _regc = regc; } + + /** + * Get the number of credentials defined for + * this account. + * @param none + * @return int The number of credentials set for this account. + */ + inline int getCredentialCount(void) { return _credentialCount; } + + /** + * @return pjsip_tls_setting structure, filled from the configuration + * file, that can be used directly by PJSIP to initialize + * TLS transport. + */ inline pjsip_tls_setting * getTlsSetting(void) { return _tlsSetting; } + + /** + * @return bool Tells if current transport for that + * account is set to TLS. + */ inline bool isTlsEnabled(void) { return (_transportType == PJSIP_TRANSPORT_TLS) ? true: false; } - inline pj_uint16_t getPort(void) { return (pj_uint16_t) atoi(_port.c_str()); } - + /* * @return pj_str_t "From" uri based on account information. * From RFC3261: "The To header field first and foremost specifies the desired @@ -132,15 +158,70 @@ class SIPAccount : public Account */ std::string getServerUri(void); - /* + /** * @param port Optional port. Otherwise set to the port defined for that account. * @param hostname Optional local address. Otherwise set to the hostname defined for that account. * @return pj_str_t The contact header based on account information */ std::string getContactHeader(const std::string& address, const std::string& port); + + /** + * Get the port on which the transport/listener should use, or is + * actually using. + * @return pj_uint16 The port used for that account + */ + inline pj_uint16_t getLocalPort(void) { return (pj_uint16_t) _localPort; } - protected: - + /** + * Set the new port on which this account is running over. + * @pram port The port used by this account. + */ + inline void setLocalPort(pj_uint16_t port) { _localPort = port; } + + /** + * Get the published port, which is the port to be advertised as the port + * for the chosen SIP transport. + * @return pj_uint16 The port used for that account + */ + inline pj_uint16_t getPublishedPort(void) { return (pj_uint16_t) _publishedPort; } + + /** + * Set the published port, which is the port to be advertised as the port + * for the chosen SIP transport. + * @pram port The port used by this account. + */ + inline void setPublishedPort(pj_uint16_t port) { _publishedPort = port; } + + /** + * Get the bound address set by the user. + * @return std::string The public IPV4 address formatted in the standard dot notation. + */ + inline std::string getLocalAddress(void) { return _localIpAddress; } + + /** + * Set the bound address chosen by the user. + * @param The public IPV4 address in the standard dot notation. + * @return void + */ + inline void setLocalAddress(const std::string& address) { _localIpAddress = address; } + + /** + * Get the public IP address set by the user for this account. + * If this setting is not provided, the local bound adddress + * will be used. + * @return std::string The public IPV4 address formatted in the standard dot notation. + */ + inline std::string getPublishedAddress(void) { return _publishedIpAddress; } + + /** + * Set the public IP address to be used in Contact header. + * @param The public IPV4 address in the standard dot notation. + * @return void + */ + inline void setPublishedAddress(const std::string& publishedIpAddress) { _publishedIpAddress = publishedIpAddress; } + + private: + /* Maps a string description of the SSL method * to the corresponding enum value in pjsip_ssl_method. * @param method The string representation @@ -159,35 +240,6 @@ class SIPAccount : public Account */ int initCredential(void); - /** - * Credential information - */ - pjsip_cred_info *_cred; - - std::string _port; - - pjsip_transport_type_e _transportType; - - /** - * The TLS settings, if tls is chosen as - * a sip transport. - */ - pjsip_tls_setting * _tlsSetting; - - /** - * Special hack that is not here to stay - * See #1852 - */ - bool _resolveOnce; - - /** - * Display Name that can be used in - * SIP URI. - */ - std::string _displayName; - - private: - /** * If username is not provided, as it happens for Direct ip calls, * fetch the hostname of the machine on which the program is running @@ -205,28 +257,38 @@ class SIPAccount : public Account std::string getLoginName(void); private: - /** - * The pjsip client registration information - */ + + // The pjsip client registration information pjsip_regc *_regc; - - /** - * To check if the account is registered - */ + // To check if the account is registered bool _bRegister; + + // Network settings + std::string _registrationExpire; - /* - * SIP address - */ - std::string _contact; + std::string _localIpAddress; + std::string _publishedIpAddress; - std::string _registrationExpire; + pj_uint16_t _localPort; + pj_uint16_t _publishedPort; + pjsip_transport_type_e _transportType; + // Special hack that is not here to stay + // See #1852 + bool _resolveOnce; + + //Credential information + int _credentialCount; + pjsip_cred_info *_cred; + std::string _realm; std::string _authenticationUsername; + + // The TLS settings, if tls is chosen as + // a sip transport. + pjsip_tls_setting * _tlsSetting; - std::string _realm; - - int _credentialCount; + // Display Name that can be used in SIP URI. + std::string _displayName; }; #endif diff --git a/sflphone-common/src/sip/sipvoiplink.cpp b/sflphone-common/src/sip/sipvoiplink.cpp index 29e928c17ae88c2287645fa2c5072cb1aa27e920..9558f25502f2ab30fed28acd7c8a8a2a9e5a4a7c 100644 --- a/sflphone-common/src/sip/sipvoiplink.cpp +++ b/sflphone-common/src/sip/sipvoiplink.cpp @@ -1594,7 +1594,7 @@ bool SIPVoIPLink::pjsip_init() PJ_ASSERT_RETURN (status == PJ_SUCCESS, 1); - /* Start resolving STUN server */ + // Start resolving STUN server // if we useStun and we failed to receive something on port 5060, we try a random port // If use STUN server, firewall address setup if (!loadSIPLocalIP()) { @@ -1609,10 +1609,10 @@ bool SIPVoIPLink::pjsip_init() this->setStunServer (Manager::instance().getConfigString (SIGNALISATION, SIP_STUN_SERVER)); this->useStun(useStun); - if (useStun && !Manager::instance().behindNat (getStunServer(), port)) { + if (useStun && !Manager::instance().isBehindNat (getStunServer(), port)) { port = RANDOM_SIP_PORT; - if (!Manager::instance().behindNat (getStunServer(), port)) { + if (!Manager::instance().isBehindNat (getStunServer(), port)) { _debug ("UserAgent: Unable to check NAT setting\n"); validStunServer = false; return false; // hoho we can't use the random sip port too... @@ -1621,37 +1621,75 @@ bool SIPVoIPLink::pjsip_init() _localPort = port; + + // Retreive Direct IP Calls settings. + // This corresponds to the accountID set to + // AccountNULL + SIPAccount * account = NULL; + bool directIpCallsTlsEnabled = false; + account = dynamic_cast<SIPAccount *> (Manager::instance().getAccount(AccountNULL)); + if (account == NULL) { + _debug("Account is null"); + } else { + directIpCallsTlsEnabled = account->isTlsEnabled(); + } + if (useStun) { - // set by last behindNat() call (ish)... + // set by last isBehindNat() call (ish)... stunServerResolve(); _localExternAddress = Manager::instance().getFirewallAddress(); - _localExternPort = Manager::instance().getFirewallPort(); - errPjsip = createUDPServer(); - - if (errPjsip != 0) { - _debug ("UserAgent: Could not initialize SIP listener on port %d\n", port); - return errPjsip; - } + _localExternPort = Manager::instance().getFirewallPort(); } else { _localExternAddress = _localIPAddress; _localExternPort = _localPort; errPjsip = createUDPServer(); + } + + // Create a UDP listener meant for all accounts + // for which TLS was not enabled + errPjsip = createUDPServer(); + + // If stun was not enabled an the above UDP server + // could not be created, then give it another try + // on a random sip port + if (errPjsip != PJ_SUCCESS && !useStun) { + _debug ("UserAgent: Could not initialize SIP listener on port %d\n", _localExternPort); + _localExternPort = _localPort = RANDOM_SIP_PORT; + + _debug ("UserAgent: Try to initialize SIP listener on port %d\n", _localExternPort); + errPjsip = createUDPServer(); - if (errPjsip != 0) { - _debug ("UserAgent: Could not initialize SIP listener on port %d\n", _localExternPort); - _localExternPort = _localPort = RANDOM_SIP_PORT; - _debug ("UserAgent: Try to initialize SIP listener on port %d\n", _localExternPort); - errPjsip = createUDPServer(); - - if (errPjsip != 0) { - _debug ("UserAgent: Fail to initialize SIP listener on port %d\n", _localExternPort); - return errPjsip; - } + if (errPjsip != PJ_SUCCESS) { + _debug ("UserAgent: Fail to initialize SIP listener on port %d\n", _localExternPort); + return errPjsip; } + } + + // If we use stun and UDP server creation + // failed, then just complain and return + // since retrying on a random sip port + // would just go against the need of + // using it. + if (errPjsip != PJ_SUCCESS && useStun) { + _debug("Could not create UDP server with STUN\n"); + return errPjsip; } _debug ("UserAgent: SIP Init -- listening on port %d\n", _localExternPort); + // Create a TLS listener meant for Direct IP calls + // if the user did enabled it. + if (directIpCallsTlsEnabled) { + errPjsip = createTlsTransportRetryOnFailure(AccountNULL); + } + + if (errPjsip != PJ_SUCCESS) { + _debug("pj_init(): could not start TLS transport for Direct Calls"); + } + + // TODO: For TLS, retry on random port, just we already do above + // for UDP transport. + // Initialize transaction layer status = pjsip_tsx_layer_init_module (_endpt); PJ_ASSERT_RETURN (status == PJ_SUCCESS, 1); @@ -1912,7 +1950,46 @@ int SIPVoIPLink::findLocalPortFromUri(const std::string& uri) return port; } -int SIPVoIPLink::createTLSServer(AccountID id) + +pj_status_t SIPVoIPLink::createTlsTransportRetryOnFailure(AccountID id) +{ + pj_status_t success; + + // Create a TLS listener. + // Note that STUN cannot be used for + // TCP NAT traversal. At the moment (20/08/09) + // user must supply the public address/port + // manually. + success = createTlsTransport(id); + + if (success != PJ_SUCCESS) { + unsigned int randomPort = RANDOM_SIP_PORT; + + // Update new port in the corresponding SIPAccount + SIPAccount * account = NULL; + account = dynamic_cast<SIPAccount *> (Manager::instance().getAccount(id)); + if (account == NULL) { + _debug("createTlsTransportRetryOnFailure: Account is null. Returning"); + return !PJ_SUCCESS; + } + + account->setLocalPort((pj_uint16_t) randomPort); + + // Try to start the transport again on + // the new port. + success = createTlsTransport(id); + if (success != PJ_SUCCESS) { + _debug ("createTlsTransportRetryOnFailure: failed to retry on random port %d\n", randomPort); + return success; + } + + _debug ("createTlsTransportRetryOnFailure: TLS transport listening on port %d\n", randomPort); + } + + return PJ_SUCCESS; +} + +pj_status_t SIPVoIPLink::createTlsTransport(AccountID id) { pjsip_tpfactory *tls; pj_sockaddr_in local_addr; @@ -1934,21 +2011,23 @@ int SIPVoIPLink::createTLSServer(AccountID id) * IP interface address is not specified, * so socket will be bound to PJ_INADDR_ANY. * If user specified port is an empty string - * of if is equal to 0, then the port will + * or if it is equal to 0, then the port will * be chosen automatically by the OS. */ pj_sockaddr_in_init(&local_addr, 0, 0); - pj_uint16_t localTlsPort = account->getPort(); + pj_uint16_t localTlsPort = account->getLocalPort(); if (localTlsPort != 0) { local_addr.sin_port = pj_htons(localTlsPort); } /* Init published name */ pj_bzero(&a_name, sizeof(pjsip_host_port)); - pj_cstr(&a_name.host, _localExternAddress.c_str()); - a_name.port = (pj_uint16_t) _localExternPort; - + pj_cstr(&a_name.host, (account->getPublishedAddress()).c_str()); + a_name.port = account->getPublishedPort(); + + /* Get TLS settings. Expected to be filled */ pjsip_tls_setting * tls_setting = account->getTlsSetting(); + status = pjsip_tls_transport_start(_endpt, tls_setting, &local_addr, &a_name, 1, &tls); if (status != PJ_SUCCESS) { @@ -3144,7 +3223,7 @@ bool setCallAudioLocal (SIPCall* call, std::string localIP, bool stun, std::stri if (stun) { // If use Stun server - if (Manager::instance().behindNat (server, callLocalAudioPort)) { + if (Manager::instance().isBehindNat (server, callLocalAudioPort)) { callLocalExternAudioPort = Manager::instance().getFirewallPort(); } } diff --git a/sflphone-common/src/sip/sipvoiplink.h b/sflphone-common/src/sip/sipvoiplink.h index 14311d65bbc497644d4cf8ddc20b3cce9c8c249e..3b35f9edf014bce905d98e18cf827318782de44d 100644 --- a/sflphone-common/src/sip/sipvoiplink.h +++ b/sflphone-common/src/sip/sipvoiplink.h @@ -339,8 +339,33 @@ class SIPVoIPLink : public VoIPLink /** Create SIP UDP Listener */ int createUDPServer(); - /** Create SIP TLS Listener */ - int createTLSServer(AccountID id); + /** + * Try to create a new TLS transport + * with the settings defined in the corresponding + * SIPAccount with id "id". If creatation fails + * for whatever reason, it will try to start + * it again on a randomly chosen port. + * + * A better idea would be to list all the transports + * registered to the transport manager in order to find + * an available port. Note that creation might also fail + * for other reason than just a wrong port. + * + * @param id The account id for which a tranport must + * be created. + * @return pj_status_t PJ_SUCCESS on success + */ + pj_status_t createTlsTransportRetryOnFailure(AccountID id); + + /** + * Try to create a TLS transport with the settings + * defined in the corresponding SIPAccount with id + * "id". + * @param id The account id for which a transport must + * be created. + * @return pj_status_t PJ_SUCCESS on success + */ + pj_status_t createTlsTransport(AccountID id); bool loadSIPLocalIP();