From 6f3bffff9fcb6e0d40830a73e3e4ef6ab14a40b9 Mon Sep 17 00:00:00 2001 From: Alexandre Savard <alexandre.savard@savoirfairelinux.com> Date: Tue, 27 Mar 2012 09:06:36 -0400 Subject: [PATCH] #9547: Extract all the transport layer from SIPVoIPLink to new SipTransport Class --- daemon/src/dbus/configurationmanager.cpp | 7 +- daemon/src/managerimpl.cpp | 4 +- daemon/src/sip/Makefile.am | 2 + daemon/src/sip/sipaccount.cpp | 4 +- daemon/src/sip/sipvoiplink.cpp | 529 ++--------------------- daemon/src/sip/sipvoiplink.h | 124 +----- 6 files changed, 38 insertions(+), 632 deletions(-) diff --git a/daemon/src/dbus/configurationmanager.cpp b/daemon/src/dbus/configurationmanager.cpp index f1043603cb..fe6b4c3a6a 100644 --- a/daemon/src/dbus/configurationmanager.cpp +++ b/daemon/src/dbus/configurationmanager.cpp @@ -37,6 +37,7 @@ #include "config.h" #include "../manager.h" #include "sip/sipvoiplink.h" +#include "sip/siptransport.h" #include "account.h" #include "sip/sipaccount.h" @@ -411,17 +412,17 @@ std::vector<std::map<std::string, std::string> > ConfigurationManager::getHistor std::string ConfigurationManager::getAddrFromInterfaceName(const std::string& interface) { - return SIPVoIPLink::getInterfaceAddrFromName(interface); + return SipTransport::getInterfaceAddrFromName(interface); } std::vector<std::string> ConfigurationManager::getAllIpInterface() { - return SIPVoIPLink::getAllIpInterface(); + return SipTransport::getAllIpInterface(); } std::vector<std::string> ConfigurationManager::getAllIpInterfaceByName() { - return SIPVoIPLink::getAllIpInterfaceByName(); + return SipTransport::getAllIpInterfaceByName(); } std::map<std::string, std::string> ConfigurationManager::getShortcuts() diff --git a/daemon/src/managerimpl.cpp b/daemon/src/managerimpl.cpp index 3cb0d6cac8..a22b5c6989 100644 --- a/daemon/src/managerimpl.cpp +++ b/daemon/src/managerimpl.cpp @@ -2563,7 +2563,7 @@ void ManagerImpl::loadDefaultAccountMap() { // build a default IP2IP account with default parameters accountMap_[SIPAccount::IP2IP_PROFILE] = new SIPAccount(SIPAccount::IP2IP_PROFILE); - SIPVoIPLink::instance()->createDefaultSipUdpTransport(); + SIPVoIPLink::instance()->sipTransport.createDefaultSipUdpTransport(); accountMap_[SIPAccount::IP2IP_PROFILE]->registerVoIPLink(); } @@ -2627,7 +2627,7 @@ void ManagerImpl::loadAccountMap(Conf::YamlParser &parser) // Initialize default UDP transport according to // IP to IP settings (most likely using port 5060) - SIPVoIPLink::instance()->createDefaultSipUdpTransport(); + SIPVoIPLink::instance()->sipTransport.createDefaultSipUdpTransport(); // Force IP2IP settings to be loaded to be loaded // No registration in the sense of the REGISTER method is performed. diff --git a/daemon/src/sip/Makefile.am b/daemon/src/sip/Makefile.am index bc3fdf7ba2..6ad33a74a4 100644 --- a/daemon/src/sip/Makefile.am +++ b/daemon/src/sip/Makefile.am @@ -9,12 +9,14 @@ libsiplink_la_SOURCES = \ sipaccount.cpp \ sipcall.cpp \ sipvoiplink.cpp \ + siptransport.cpp \ pattern.h \ sdes_negotiator.h \ sdp.h \ sipaccount.h \ sipcall.h \ sipvoiplink.h \ + siptransport.h \ sip_utils.cpp \ sip_utils.h diff --git a/daemon/src/sip/sipaccount.cpp b/daemon/src/sip/sipaccount.cpp index 5750f57e4e..a59aaf39e0 100644 --- a/daemon/src/sip/sipaccount.cpp +++ b/daemon/src/sip/sipaccount.cpp @@ -407,7 +407,7 @@ void SIPAccount::setAccountDetails(std::map<std::string, std::string> details) publishedPort_ = atoi(details[CONFIG_PUBLISHED_PORT].c_str()); if(stunServer_ != details[CONFIG_STUN_SERVER]) { DEBUG("Stun server changed!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); - link_->destroyStunResolver(stunServer_); + link_->sipTransport.destroyStunResolver(stunServer_); // pj_stun_sock_destroy(pj_stun_sock *stun_sock); } stunServer_ = details[CONFIG_STUN_SERVER]; @@ -816,7 +816,7 @@ std::string SIPAccount::getContactHeader() const // Else we determine this infor based on transport information std::string address, port; - link_->findLocalAddressFromTransport(transport_, transportType, address, port); + link_->sipTransport.findLocalAddressFromTransport(transport_, transportType, address, port); // UDP does not require the transport specification std::string scheme; diff --git a/daemon/src/sip/sipvoiplink.cpp b/daemon/src/sip/sipvoiplink.cpp index 2780bbb9a4..23c69e833f 100644 --- a/daemon/src/sip/sipvoiplink.cpp +++ b/daemon/src/sip/sipvoiplink.cpp @@ -76,8 +76,6 @@ using namespace sfl; namespace { -static pjsip_transport *localUDPTransport_ = NULL; /** The default transport (5060) */ - /** A map to retreive SFLphone internal call id * Given a SIP call ID (usefull for transaction sucha as transfer)*/ static std::map<std::string, std::string> transferCallID; @@ -121,18 +119,6 @@ int SIPSessionReinvite(SIPCall *); */ void onCallTransfered(pjsip_inv_session *inv, pjsip_rx_data *rdata); -std::string getSIPLocalIP() -{ - pj_sockaddr ip_addr; - - if (pj_gethostip(pj_AF_INET(), &ip_addr) == PJ_SUCCESS) - return pj_inet_ntoa(ip_addr.ipv4.sin_addr); - else { - ERROR("SIPVoIPLink: Could not get local IP"); - return ""; - } -} - pjsip_route_hdr *createRouteSet(const std::string &route, pj_pool_t *hdr_pool) { int port = 0; @@ -309,15 +295,15 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata) Manager::instance().associateCallToAccount(call->getCallId(), account_id); // May use the published address as well - std::string addrToUse = SIPVoIPLink::instance()->getInterfaceAddrFromName(account->getLocalInterface()); + std::string addrToUse = SipTransport::getInterfaceAddrFromName(account->getLocalInterface()); std::string addrSdp = account->isStunEnabled() ? account->getPublishedAddress() : addrToUse; - pjsip_tpselector *tp = SIPVoIPLink::instance()->initTransportSelector(account->transport_, call->getMemoryPool()); + pjsip_tpselector *tp = SIPVoIPLink::instance()->sipTransport.initTransportSelector(account->transport_, call->getMemoryPool()); if (addrToUse == "0.0.0.0") - addrToUse = getSIPLocalIP(); + addrToUse = SipTransport::getSIPLocalIP(); if (addrSdp == "0.0.0.0") addrSdp = addrToUse; @@ -427,7 +413,7 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata) /*************************************************************************************************/ -SIPVoIPLink::SIPVoIPLink() : transportMap_(), stunSocketMap_(), evThread_(new EventThread(this)) +SIPVoIPLink::SIPVoIPLink() : sipTransport(endpt_, cp_, pool_), evThread_(new EventThread(this)) { #define TRY(ret) do { \ if (ret != PJ_SUCCESS) \ @@ -450,7 +436,11 @@ SIPVoIPLink::SIPVoIPLink() : transportMap_(), stunSocketMap_(), evThread_(new Ev TRY(pjsip_endpt_create(&cp_->factory, pj_gethostname()->ptr, &endpt_)); - if (getSIPLocalIP().empty()) + sipTransport.setEndpoint(endpt_); + sipTransport.setCachingPool(cp_); + sipTransport.setPool(pool_); + + if (SipTransport::getSIPLocalIP().empty()) throw VoipLinkException("UserAgent: Unable to determine network capabilities"); TRY(pjsip_tsx_layer_init_module(endpt_)); @@ -540,7 +530,7 @@ SIPVoIPLink::getEvent() void SIPVoIPLink::sendRegister(Account *a) { SIPAccount *account = dynamic_cast<SIPAccount*>(a); - createSipTransport(account); + sipTransport.createSipTransport(account); account->setRegister(true); account->setRegistrationState(Trying); @@ -588,7 +578,7 @@ void SIPVoIPLink::sendRegister(Account *a) if (pjsip_regc_register(regc, PJ_TRUE, &tdata) != PJ_SUCCESS) throw VoipLinkException("Unable to initialize transaction data for account registration"); - if (pjsip_regc_set_transport(regc, initTransportSelector(account->transport_, pool_)) != PJ_SUCCESS) + if (pjsip_regc_set_transport(regc, sipTransport.initTransportSelector(account->transport_, pool_)) != PJ_SUCCESS) throw VoipLinkException("Unable to set transport"); // decrease transport's ref count, counter incrementation is managed when acquiring transport @@ -683,20 +673,20 @@ Call *SIPVoIPLink::newOutgoingCall(const std::string& id, const std::string& toU toUri = account->getToUri(toUrl); call->setPeerNumber(toUri); - std::string localAddr(getInterfaceAddrFromName(account->getLocalInterface())); + std::string localAddr(SipTransport::getInterfaceAddrFromName(account->getLocalInterface())); if (localAddr == "0.0.0.0") - localAddr = getSIPLocalIP(); + localAddr = SipTransport::getSIPLocalIP(); setCallMediaLocal(call, localAddr); // May use the published address as well std::string addrSdp = account->isStunEnabled() ? account->getPublishedAddress() : - getInterfaceAddrFromName(account->getLocalInterface()); + SipTransport::getInterfaceAddrFromName(account->getLocalInterface()); if (addrSdp == "0.0.0.0") - addrSdp = getSIPLocalIP(); + addrSdp = SipTransport::getSIPLocalIP(); // Initialize the session using ULAW as default codec in case of early media // The session should be ready to receive media once the first INVITE is sent, before @@ -1094,7 +1084,7 @@ SIPVoIPLink::SIPStartCall(SIPCall *call) if (pjsip_inv_invite(call->inv, &tdata) != PJ_SUCCESS) return false; - pjsip_tpselector *tp = initTransportSelector(account->transport_, call->inv->pool); + pjsip_tpselector *tp = sipTransport.initTransportSelector(account->transport_, call->inv->pool); if (pjsip_dlg_set_transport(dialog, tp) != PJ_SUCCESS) return false; @@ -1164,10 +1154,10 @@ bool SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to) call->setIPToIP(true); call->initRecFilename(to); - std::string localAddress(getInterfaceAddrFromName(account->getLocalInterface())); + std::string localAddress(SipTransport::getInterfaceAddrFromName(account->getLocalInterface())); if (localAddress == "0.0.0.0") - localAddress = getSIPLocalIP(); + localAddress = SipTransport::getSIPLocalIP(); setCallMediaLocal(call, localAddress); @@ -1205,8 +1195,8 @@ bool SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to) return false; } - shutdownSipTransport(account); - pjsip_transport *transport = createTlsTransport(remoteAddr, account->getTlsListenerPort(), + sipTransport.shutdownSipTransport(account); + pjsip_transport *transport = sipTransport.createTlsTransport(remoteAddr, account->getTlsListenerPort(), account->getTlsSetting()); if (transport == NULL) { @@ -1231,410 +1221,6 @@ bool SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to) // Private functions /////////////////////////////////////////////////////////////////////////////// -pj_bool_t -stun_sock_on_status_cb(pj_stun_sock * /*stun_sock*/, pj_stun_sock_op op, - pj_status_t status) -{ - switch (op) { - case PJ_STUN_SOCK_DNS_OP: - DEBUG("UserAgent: Stun operation dns resolution"); - break; - case PJ_STUN_SOCK_BINDING_OP: - DEBUG("UserAgent: Stun operation binding"); - break; - case PJ_STUN_SOCK_KEEP_ALIVE_OP: - DEBUG("UserAgent: Stun operation keep alive"); - break; - case PJ_STUN_SOCK_MAPPED_ADDR_CHANGE: - DEBUG("UserAgent: Stun operation address mapping change"); - break; - default: - DEBUG("UserAgent: Stun unknown operation"); - break; - } - - if (status == PJ_SUCCESS) { - DEBUG("UserAgent: Stun operation success"); - } else { - ERROR("UserAgent: Stun operation failure"); - } - - // Always return true so the stun transport registration retry even on failure - return true; -} - -static pj_bool_t -stun_sock_on_rx_data_cb(pj_stun_sock * /*stun_sock*/, void * /*pkt*/, - unsigned /*pkt_len*/, - const pj_sockaddr_t * /*src_addr*/, - unsigned /*addr_len*/) -{ - return PJ_TRUE; -} - - -pj_status_t SIPVoIPLink::createStunResolver(pj_str_t serverName, pj_uint16_t port) -{ - pj_stun_config stunCfg; - pj_stun_config_init(&stunCfg, &cp_->factory, 0, pjsip_endpt_get_ioqueue(endpt_), pjsip_endpt_get_timer_heap(endpt_)); - - DEBUG("***************** Create Stun Resolver *********************"); - - static const pj_stun_sock_cb stun_sock_cb = { - stun_sock_on_rx_data_cb, - NULL, - stun_sock_on_status_cb - }; - - pj_stun_sock *stun_sock; - std::string stunResolverName(serverName.ptr, serverName.slen); - pj_status_t status = pj_stun_sock_create(&stunCfg, stunResolverName.c_str(), pj_AF_INET(), &stun_sock_cb, NULL, NULL, &stun_sock); - - // store socket inside list - DEBUG(" insert %s resolver in map", stunResolverName.c_str()); - stunSocketMap_.insert(std::pair<std::string, pj_stun_sock *>(stunResolverName, stun_sock)); - - if (status != PJ_SUCCESS) { - char errmsg[PJ_ERR_MSG_SIZE]; - pj_strerror(status, errmsg, sizeof(errmsg)); - ERROR("UserAgent: Error creating STUN socket for %.*s: %s", (int) serverName.slen, serverName.ptr, errmsg); - return status; - } - - status = pj_stun_sock_start(stun_sock, &serverName, port, NULL); - - if (status != PJ_SUCCESS) { - char errmsg[PJ_ERR_MSG_SIZE]; - pj_strerror(status, errmsg, sizeof(errmsg)); - DEBUG("UserAgent: Error starting STUN socket for %.*s: %s", (int) serverName.slen, serverName.ptr, errmsg); - pj_stun_sock_destroy(stun_sock); - } - - return status; -} - -pj_status_t SIPVoIPLink::destroyStunResolver(const std::string serverName) -{ - std::map<std::string, pj_stun_sock *>::iterator it; - it = stunSocketMap_.find(serverName); - - DEBUG("***************** Destroy Stun Resolver *********************"); - - if (it != stunSocketMap_.end()) { - DEBUG("UserAgent: Deleting stun resolver %s", it->first.c_str()); - pj_stun_sock_destroy(it->second); - stunSocketMap_.erase(it); - } - - return PJ_SUCCESS; -} - -void SIPVoIPLink::createDefaultSipUdpTransport() -{ - pj_uint16_t port = 0; - int counter = 0; - - SIPAccount *account = Manager::instance().getIP2IPAccount(); - - pjsip_transport *transport = NULL; - static const int DEFAULT_TRANSPORT_ATTEMPTS = 5; - for (; transport == NULL and counter < DEFAULT_TRANSPORT_ATTEMPTS; ++counter) { - // if default udp transport fails to init on 5060, try other ports - // with 2 step size increment (i.e. 5062, 5064, ...) - port = account->getLocalPort() + (counter * 2); - transport = createUdpTransport(account->getLocalInterface(), port); - } - - if (transport == NULL) { - ERROR("UserAgent: Create UDP transport"); - return; - } - - DEBUG("UserAgent: Created default sip transport on %d", port); - - // set transport for this account - account->transport_ = transport; - - // set local udp transport - localUDPTransport_ = account->transport_; -} - -void SIPVoIPLink::createTlsListener(pj_uint16_t tlsListenerPort, pjsip_tls_setting *tlsSetting, pjsip_tpfactory **listener) -{ - pj_sockaddr_in local_addr; - pj_sockaddr_in_init(&local_addr, 0, 0); - local_addr.sin_port = pj_htons(tlsListenerPort); - - if (tlsSetting == NULL) { - ERROR("Error TLS settings not specified"); - return; - } - - if (listener == NULL) { - ERROR("Error no pointer to store new TLS listener"); - return; - } - - pj_str_t pjAddress; - pj_cstr(&pjAddress, PJ_INADDR_ANY); - pj_sockaddr_in_set_str_addr(&local_addr, &pjAddress); - std::string localIP(getSIPLocalIP()); - - pjsip_host_port a_name = { - pj_str((char*) localIP.c_str()), - local_addr.sin_port - }; - - pjsip_tls_transport_start(endpt_, tlsSetting, &local_addr, &a_name, 1, listener); -} - - -pjsip_transport * -SIPVoIPLink::createTlsTransport(const std::string &remoteAddr, - pj_uint16_t tlsListenerPort, - pjsip_tls_setting *tlsSettings) -{ - pjsip_transport *transport = NULL; - - pj_str_t remote; - pj_cstr(&remote, remoteAddr.c_str()); - - pj_sockaddr_in rem_addr; - pj_sockaddr_in_init(&rem_addr, &remote, (pj_uint16_t) DEFAULT_SIP_TLS_PORT); - - // The local tls listener - static pjsip_tpfactory *localTlsListener = NULL; - - if (localTlsListener == NULL) - createTlsListener(tlsListenerPort, tlsSettings, &localTlsListener); - - pjsip_endpt_acquire_transport(endpt_, PJSIP_TRANSPORT_TLS, &rem_addr, - sizeof rem_addr, NULL, &transport); - - if (transport == NULL) - ERROR("Error: Could not create new TLS transport\n"); - - return transport; -} - -void SIPVoIPLink::createSipTransport(SIPAccount *account) -{ - if (account == NULL) { - ERROR("UserAgent: Account is NULL while creating sip transport"); - return; - } - - shutdownSipTransport(account); - - if (account->isTlsEnabled()) { - std::string remoteSipUri(account->getServerUri()); - static const char SIPS_PREFIX[] = "<sips:"; - size_t sips = remoteSipUri.find(SIPS_PREFIX) + (sizeof SIPS_PREFIX) - 1; - size_t trns = remoteSipUri.find(";transport"); - std::string remoteAddr(remoteSipUri.substr(sips, trns-sips)); - - pjsip_transport *transport = createTlsTransport(remoteAddr, account->getTlsListenerPort(), account->getTlsSetting()); - account->transport_ = transport; - } else if (account->isStunEnabled()) { - pjsip_transport *transport = createStunTransport(account->getStunServerName(), account->getStunPort()); - account->transport_ = transport; - } - else { - pjsip_transport *transport = createUdpTransport(account->getLocalInterface(), account->getLocalPort()); - account->transport_ = transport; - } - - if (!account->transport_) { - // Could not create new transport, this transport may already exists - account->transport_ = transportMap_[account->getLocalPort()]; - - if (account->transport_) - pjsip_transport_add_ref(account->transport_); - else { - account->transport_ = localUDPTransport_; - account->setLocalPort(localUDPTransport_->local_name.port); - } - } -} - -pjsip_transport *SIPVoIPLink::createUdpTransport(std::string interface, unsigned int port) -{ - // init socket to bind this transport to - pj_sockaddr_in bound_addr; - pj_bzero(&bound_addr, sizeof(bound_addr)); - pj_uint16_t listeningPort = (pj_uint16_t) port; - bound_addr.sin_port = pj_htons(listeningPort); - bound_addr.sin_family = PJ_AF_INET; - - // determine the ip address for this transport - static const char * const DEFAULT_INTERFACE = "default"; - std::string listeningAddress; - if (interface == DEFAULT_INTERFACE) { - listeningAddress = getSIPLocalIP(); - bound_addr.sin_addr.s_addr = pj_htonl(PJ_INADDR_ANY); - } else { - listeningAddress = getInterfaceAddrFromName(interface); - bound_addr.sin_addr = pj_inet_addr2(listeningAddress.c_str()); - } - - if (listeningAddress.empty()) { - ERROR("SIP: Could not determine ip address for this transport"); - return NULL; - } - - if (listeningPort == 0) { - ERROR("SIP: Could not determine port for this transport"); - return NULL; - } - - // The published address for this transport - const pjsip_host_port a_name = { - pj_str((char*) listeningAddress.c_str()), - listeningPort - }; - - pjsip_transport *transport = NULL; - pj_status_t status = pjsip_udp_transport_start(endpt_, &bound_addr, &a_name, 1, &transport); - if (status != PJ_SUCCESS) { - ERROR("SIP: Could not create UDP transport for port %u", port); - return NULL; - } - - // dump debug information to stdout - pjsip_tpmgr_dump_transports(pjsip_endpt_get_tpmgr(endpt_)); - transportMap_[listeningPort] = transport; - - return transport; -} - -pjsip_tpselector *SIPVoIPLink::initTransportSelector(pjsip_transport *transport, pj_pool_t *tp_pool) const -{ - assert(transport); - pjsip_tpselector *tp = (pjsip_tpselector *) pj_pool_zalloc(tp_pool, sizeof(pjsip_tpselector)); - tp->type = PJSIP_TPSELECTOR_TRANSPORT; - tp->u.transport = transport; - return tp; -} - -pjsip_transport *SIPVoIPLink::createStunTransport(pj_str_t serverName, pj_uint16_t port) -{ - pjsip_transport *transport; - - DEBUG("UserAgent: Create stun transport server name: %s, port: %d", serverName, port);// account->getStunPort()); - if (createStunResolver(serverName, port) != PJ_SUCCESS) { - ERROR("UserAgent: Can't resolve STUN server"); - Manager::instance().getDbusManager()->getConfigurationManager()->stunStatusFailure(""); - return NULL; - } - - pj_sock_t sock = PJ_INVALID_SOCKET; - - pj_sockaddr_in boundAddr; - - if (pj_sockaddr_in_init(&boundAddr, &serverName, 0) != PJ_SUCCESS) { - ERROR("UserAgent: Can't initialize IPv4 socket on %*s:%i", serverName.slen, serverName.ptr, port); - Manager::instance().getDbusManager()->getConfigurationManager()->stunStatusFailure(""); - return NULL; - } - - if (pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &sock) != PJ_SUCCESS) { - ERROR("UserAgent: Can't create or bind socket"); - Manager::instance().getDbusManager()->getConfigurationManager()->stunStatusFailure(""); - return NULL; - } - - // Query the mapped IP address and port on the 'outside' of the NAT - pj_sockaddr_in pub_addr; - - if (pjstun_get_mapped_addr(&cp_->factory, 1, &sock, &serverName, port, &serverName, port, &pub_addr) != PJ_SUCCESS) { - ERROR("UserAgent: Can't contact STUN server"); - pj_sock_close(sock); - Manager::instance().getDbusManager()->getConfigurationManager()->stunStatusFailure(""); - return NULL; - } - - pjsip_host_port a_name = { - pj_str(pj_inet_ntoa(pub_addr.sin_addr)), - pj_ntohs(pub_addr.sin_port) - }; - - pjsip_udp_transport_attach2(endpt_, PJSIP_TRANSPORT_UDP, sock, &a_name, 1, - &transport); - - pjsip_tpmgr_dump_transports(pjsip_endpt_get_tpmgr(endpt_)); - - return transport; -} - -void SIPVoIPLink::shutdownSipTransport(SIPAccount *account) -{ - if (account->isStunEnabled()) { - pj_str_t stunServerName = account->getStunServerName(); - std::string server(stunServerName.ptr, stunServerName.slen); - destroyStunResolver(server); - } - - if (account->transport_) { - pjsip_transport_dec_ref(account->transport_); - account->transport_ = NULL; - } -} - -void SIPVoIPLink::findLocalAddressFromTransport(pjsip_transport *transport, pjsip_transport_type_e transportType, std::string &addr, std::string &port) const -{ - // Initialize the sip port with the default SIP port - std::stringstream ss; - ss << DEFAULT_SIP_PORT; - port = ss.str(); - - // Initialize the sip address with the hostname - const pj_str_t *pjMachineName = pj_gethostname(); - addr = std::string(pjMachineName->ptr, pjMachineName->slen); - - // Update address and port with active transport - if (!transport) { - ERROR("SIPVoIPLink: Transport is NULL in findLocalAddress, using local address %s:%s", addr.c_str(), port.c_str()); - return; - } - - // get the transport manager associated with the SIP enpoint - pjsip_tpmgr *tpmgr = pjsip_endpt_get_tpmgr(endpt_); - if (!tpmgr) { - ERROR("SIPVoIPLink: Transport manager is NULL in findLocalAddress, using local address %s:%s", addr.c_str(), port.c_str()); - return; - } - - // initialize a transport selector - // TODO Need to determine why we exclude TLS here... - // if (transportType == PJSIP_TRANSPORT_UDP and transport_) - pjsip_tpselector *tp_sel = initTransportSelector(transport, pool_); - if (!tp_sel) { - ERROR("SIPVoIPLink: Could not initialize transport selector, using local address %s:%s", addr.c_str(), port.c_str()); - return; - } - - pj_str_t localAddress = {0,0}; - int i_port = 0; - - // Find the local address and port for this transport - if (pjsip_tpmgr_find_local_addr(tpmgr, pool_, transportType, tp_sel, &localAddress, &i_port) != PJ_SUCCESS) { - WARN("SIPVoIPLink: Could not retrieve local address and port from transport, using %s:%s", addr.c_str(), port.c_str()); - return; - } - - // Update local address based on the transport type - addr = std::string(localAddress.ptr, localAddress.slen); - - // Fallback on local ip provided by pj_gethostip() - if (addr == "0.0.0.0") - addr = getSIPLocalIP(); - - // Determine the local port based on transport information - ss.str(""); - ss << i_port; - port = ss.str(); -} - namespace { int SIPSessionReinvite(SIPCall *call) { @@ -1725,11 +1311,11 @@ void sdp_create_offer_cb(pjsip_inv_session *inv, pjmedia_sdp_session **p_offer) SIPAccount *account = dynamic_cast<SIPAccount *>(Manager::instance().getAccount(accountid)); - std::string localAddress(SIPVoIPLink::instance()->getInterfaceAddrFromName(account->getLocalInterface())); + std::string localAddress(SipTransport::getInterfaceAddrFromName(account->getLocalInterface())); std::string addrSdp(localAddress); if (localAddress == "0.0.0.0") - localAddress = getSIPLocalIP(); + localAddress = SipTransport::getSIPLocalIP(); if (addrSdp == "0.0.0.0") addrSdp = localAddress; @@ -1984,7 +1570,7 @@ void update_contact_header(pjsip_regc_cbparam *param, SIPAccount *account) std::string recvContactPort = ss.str(); std::string currentAddress, currentPort; - siplink->findLocalAddressFromTransport(account->transport_, PJSIP_TRANSPORT_UDP, currentAddress, currentPort); + siplink->sipTransport.findLocalAddressFromTransport(account->transport_, PJSIP_TRANSPORT_UDP, currentAddress, currentPort); bool updateContact = false; std::string currentContactHeader = account->getContactHeader(); @@ -2037,7 +1623,7 @@ void registration_cb(pjsip_regc_cbparam *param) account->setRegistrationState(ErrorAuth); account->setRegister(false); - SIPVoIPLink::instance()->shutdownSipTransport(account); + SIPVoIPLink::instance()->sipTransport.shutdownSipTransport(account); return; } @@ -2071,14 +1657,14 @@ void registration_cb(pjsip_regc_cbparam *param) account->setRegister(false); - SIPVoIPLink::instance()->shutdownSipTransport(account); + SIPVoIPLink::instance()->sipTransport.shutdownSipTransport(account); } else { if (account->isRegistered()) account->setRegistrationState(Registered); else { account->setRegistrationState(Unregistered); - SIPVoIPLink::instance()->shutdownSipTransport(account); + SIPVoIPLink::instance()->sipTransport.shutdownSipTransport(account); } } } @@ -2183,66 +1769,3 @@ void setCallMediaLocal(SIPCall* call, const std::string &localIP) call->getLocalSDP()->setLocalPublishedAudioPort(callLocalExternAudioPort); } } // end anonymous namespace - -std::vector<std::string> SIPVoIPLink::getAllIpInterfaceByName() -{ - static ifreq ifreqs[20]; - ifconf ifconf; - - std::vector<std::string> ifaceList; - ifaceList.push_back("default"); - - ifconf.ifc_buf = (char*) (ifreqs); - ifconf.ifc_len = sizeof(ifreqs); - - int sock = socket(AF_INET,SOCK_STREAM,0); - - if (sock >= 0) { - if (ioctl(sock, SIOCGIFCONF, &ifconf) >= 0) - for (unsigned i = 0; i < ifconf.ifc_len / sizeof(ifreq); ++i) - ifaceList.push_back(std::string(ifreqs[i].ifr_name)); - - close(sock); - } - - return ifaceList; -} - -std::string SIPVoIPLink::getInterfaceAddrFromName(const std::string &ifaceName) -{ - int fd = socket(AF_INET, SOCK_DGRAM,0); - - if (fd < 0) { - ERROR("UserAgent: Error: could not open socket: %m"); - return ""; - } - - ifreq ifr; - strcpy(ifr.ifr_name, ifaceName.c_str()); - memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr)); - ifr.ifr_addr.sa_family = AF_INET; - - ioctl(fd, SIOCGIFADDR, &ifr); - close(fd); - - sockaddr_in *saddr_in = (sockaddr_in *) &ifr.ifr_addr; - return inet_ntoa(saddr_in->sin_addr); -} - -std::vector<std::string> SIPVoIPLink::getAllIpInterface() -{ - pj_sockaddr addrList[16]; - unsigned addrCnt = PJ_ARRAY_SIZE(addrList); - - std::vector<std::string> ifaceList; - - if (pj_enum_ip_interface(pj_AF_INET(), &addrCnt, addrList) == PJ_SUCCESS) { - for (unsigned i = 0; i < addrCnt; i++) { - char addr[PJ_INET_ADDRSTRLEN]; - pj_sockaddr_print(&addrList[i], addr, sizeof(addr), 0); - ifaceList.push_back(std::string(addr)); - } - } - - return ifaceList; -} diff --git a/daemon/src/sip/sipvoiplink.h b/daemon/src/sip/sipvoiplink.h index 863f93d215..c7f65aa731 100644 --- a/daemon/src/sip/sipvoiplink.h +++ b/daemon/src/sip/sipvoiplink.h @@ -49,6 +49,7 @@ #include "sipaccount.h" #include "voiplink.h" +#include "siptransport.h" class EventThread; class SIPCall; @@ -211,49 +212,6 @@ class SIPVoIPLink : public VoIPLink { */ std::string getUseragentName(SIPAccount *) const; - /** - * List all the interfaces on the system and return - * a vector list containing their IPV4 address. - * @param void - * @return std::vector<std::string> A std::string vector - * of IPV4 address available on all of the interfaces on - * the system. - */ - static std::vector<std::string> getAllIpInterface(); - - /** - * List all the interfaces on the system and return - * a vector list containing their name (eth0, eth0:1 ...). - * @param void - * @return std::vector<std::string> A std::string vector - * of interface name available on all of the interfaces on - * the system. - */ - static std::vector<std::string> getAllIpInterfaceByName(); - - /** - * List all the interfaces on the system and return - * a vector list containing their name (eth0, eth0:1 ...). - * @param void - * @return std::vector<std::string> A std::string vector - * of interface name available on all of the interfaces on - * the system. - */ - static std::string getInterfaceAddrFromName(const std::string &ifaceName); - - /** - * Initialize the transport selector - * @param transport A transport associated with an account - * - * @return A pointer to the transport selector structure - */ - pjsip_tpselector *initTransportSelector(pjsip_transport *, pj_pool_t *) const; - - /** - * This function unset the transport for a given account. - */ - void shutdownSipTransport(SIPAccount *account); - /** * Send a SIP message to a call identified by its callid * @@ -270,26 +228,7 @@ class SIPVoIPLink : public VoIPLink { */ void createDefaultSipUdpTransport(); - /** - * Get the correct address to use (ie advertised) from - * a uri. The corresponding transport that should be used - * with that uri will be discovered. - * - * @param uri The uri from which we want to discover the address to use - * @param transport The transport to use to discover the address - */ - void findLocalAddressFromTransport(pjsip_transport *transport, pjsip_transport_type_e transportType, std::string &address, std::string &port) const; - - /** - * Create a new stun resolver. Store it inside the array. Resolve public address for this - * server name. - * @param serverName The name of the stun server - * @param port number - */ - pj_status_t createStunResolver(pj_str_t serverName, pj_uint16_t port); - - pj_status_t destroyStunResolver(const std::string serverName); - + SipTransport sipTransport; private: /** * Start a SIP Call @@ -304,65 +243,6 @@ class SIPVoIPLink : public VoIPLink { SIPVoIPLink(); - /** - * General Sip transport creation method according to the - * transport type specified in account settings - * @param account The account for which a transport must be created. - */ - void createSipTransport(SIPAccount *account); - - /** - * Create SIP UDP transport from account's setting - * @param account The account for which a transport must be created. - */ - pjsip_transport *createUdpTransport(std::string interface, unsigned int port); - - /** - * Create The default TLS listener which is global to the application. This means that - * only one TLS connection can be established for the momment. - * @param the port number to create the TCP socket - * @param pjsip's tls settings for the transport to be created which contains: - * - path to ca certificate list file - * - path to certertificate file - * - path to private key file - * - the password for the file - * - the TLS method - * @param a pointer to store the listener created, in our case this is a static pointer - */ - void createTlsListener(pj_uint16_t, pjsip_tls_setting *, pjsip_tpfactory **); - - /** - * Create a connection oriented TLS transport and register to the specified remote address. - * First, initialize the TLS listener sole instance. This means that, for the momment, only one TLS transport - * is allowed to be created in the application. Any subsequent account attempting to - * register a new using this transport even if new settings are specified. - * @param the remote address for this transport to be connected - * @param the local port to initialize the TCP socket - * @param pjsip's tls transport parameters - */ - pjsip_transport * - createTlsTransport(const std::string &remoteAddr, - pj_uint16_t tlsListenerPort, - pjsip_tls_setting *tlsSetting); - - /** - * Create a UDP transport using stun server to resove public address - * @param account The account for which a transport must be created. - */ - pjsip_transport *createStunTransport(pj_str_t serverName, pj_uint16_t port); - - /** - * UDP Transports are stored in this map in order to retreive them in case - * several accounts would share the same port number. - */ - std::map<pj_uint16_t, pjsip_transport*> transportMap_; - - /** - * Stun resolver array - */ - std::map<std::string, pj_stun_sock *> stunSocketMap_; - - /** * Threading object */ -- GitLab