diff --git a/daemon/src/sip/siptransport.cpp b/daemon/src/sip/siptransport.cpp index 48273c745f256e7d3feeb7cb062b9ba84ceaaaa9..64b12780f7e4832717c73f22ec9033640a06ed67 100644 --- a/daemon/src/sip/siptransport.cpp +++ b/daemon/src/sip/siptransport.cpp @@ -251,68 +251,62 @@ pj_status_t SipTransport::destroyStunResolver(const std::string &serverName) } -void SipTransport::createTlsListener(const std::string &interface, pj_uint16_t tlsListenerPort, pjsip_tls_setting *tlsSetting, pjsip_tpfactory **listener) +pjsip_tpfactory* SipTransport::createTlsListener(SIPAccount &account) { - pj_status_t status; pj_sockaddr_in local_addr; pj_sockaddr_in_init(&local_addr, 0, 0); - local_addr.sin_port = pj_htons(tlsListenerPort); - - DEBUG("SipTransport: Create TLS listener %s:%d", interface.c_str(), tlsListenerPort); + local_addr.sin_port = pj_htons(account.getTlsListenerPort()); - if (tlsSetting == NULL) { + if (account.getTlsSetting() == NULL) { ERROR("SipTransport: Error TLS settings not specified"); - return; - } - - if (listener == NULL) { - ERROR("SipTransport: Error no pointer to store new TLS listener"); - return; + return NULL; } + std::string interface(account.getLocalInterface()); std::string listeningAddress; if (interface == DEFAULT_INTERFACE) listeningAddress = getSIPLocalIP(); else listeningAddress = getInterfaceAddrFromName(interface); - if (listeningAddress.empty()) { + if (listeningAddress.empty()) ERROR("SipTransport: Could not determine ip address for this transport"); - } pj_str_t pjAddress; pj_cstr(&pjAddress, listeningAddress.c_str()); pj_sockaddr_in_set_str_addr(&local_addr, &pjAddress); - pj_sockaddr_in_set_port(&local_addr, tlsListenerPort); + pj_sockaddr_in_set_port(&local_addr, account.getTlsListenerPort()); - status = pjsip_tls_transport_start(endpt_, tlsSetting, &local_addr, NULL, 1, listener); - if(status != PJ_SUCCESS) + pjsip_tpfactory *listener = NULL; + if (pjsip_tls_transport_start(endpt_, account.getTlsSetting(), &local_addr, + NULL, 1, &listener) != PJ_SUCCESS) { ERROR("SipTransport: Error Failed to start tls listener"); + listener = NULL; + } + return listener; } pjsip_transport * -SipTransport::createTlsTransport(const std::string &remoteAddr, - const std::string &interface, - pj_uint16_t tlsListenerPort, - pjsip_tls_setting *tlsSettings) +SipTransport::createTlsTransport(SIPAccount &account) { - pjsip_transport *transport = NULL; + 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)); std::string ipAddr = ""; int port = DEFAULT_SIP_TLS_PORT; // parse c string size_t pos = remoteAddr.find(":"); - if(pos != std::string::npos) { + if (pos != std::string::npos) { ipAddr = remoteAddr.substr(0, pos); - port = atoi(remoteAddr.substr(pos+1, remoteAddr.length() - pos).c_str()); - } - else { + port = atoi(remoteAddr.substr(pos + 1, remoteAddr.length() - pos).c_str()); + } else { ipAddr = remoteAddr; } - DEBUG("SipTransport: Create sip transport on %s:%d at destination %s:%d", interface.c_str(), tlsListenerPort, ipAddr.c_str(), port); - pj_str_t remote; pj_cstr(&remote, ipAddr.c_str()); @@ -323,66 +317,51 @@ SipTransport::createTlsTransport(const std::string &remoteAddr, static pjsip_tpfactory *localTlsListener = NULL; if (localTlsListener == NULL) - createTlsListener(interface, tlsListenerPort, tlsSettings, &localTlsListener); + localTlsListener = createTlsListener(account); DEBUG("SipTransport: Get new tls transport from transport manager"); + pjsip_transport *transport = NULL; pjsip_endpt_acquire_transport(endpt_, PJSIP_TRANSPORT_TLS, &rem_addr, sizeof rem_addr, NULL, &transport); - if (transport == NULL) ERROR("SipTransport: Could not create new TLS transport\n"); return transport; } -void SipTransport::createSipTransport(SIPAccount *account) +void SipTransport::createSipTransport(SIPAccount &account) { - if (account == NULL) { - ERROR("SipTransport: 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->getLocalInterface(), account->getTlsListenerPort(), account->getTlsSetting()); - account->transport_ = transport; - } else if (account->isStunEnabled()) { - pjsip_transport *transport = createSTUNTransport(*account); - if(transport == NULL) - transport = createUdpTransport(account->getLocalInterface(), account->getLocalPort()); - account->transport_ = transport; - } - else { - pjsip_transport *transport = createUdpTransport(account->getLocalInterface(), account->getLocalPort()); - account->transport_ = transport; + if (account.isTlsEnabled()) { + account.transport_ = createTlsTransport(account); + } else if (account.isStunEnabled()) { + account.transport_ = createStunTransport(account); + if (account.transport_ == NULL) { + WARN("SipTransport: falling back to UDP transport"); + account.transport_ = createUdpTransport(account.getLocalInterface(), account.getLocalPort()); + } + } else { + account.transport_ = createUdpTransport(account.getLocalInterface(), account.getLocalPort()); } - - - if (!account->transport_) { + if (!account.transport_) { DEBUG("SipTransport: Looking into previously created transport map for %s:%d", - account->getLocalInterface().c_str(), account->getLocalPort()); + account.getLocalInterface().c_str(), account.getLocalPort()); // 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 *cachedTransport = transportMap_[account.getLocalPort()]; + + if (cachedTransport) { + account.transport_ = cachedTransport; + pjsip_transport_add_ref(account.transport_); + } else { + if (account.isTlsEnabled()) + throw std::runtime_error("SipTransport: Could not create TLS connection"); + assert(localUDPTransport_); + account.transport_ = localUDPTransport_; + account.setLocalPort(localUDPTransport_->local_name.port); } } - - if(account->transport_ == NULL) - ERROR("SipTransport: Could not create transport on %s:%d", - account->getLocalInterface().c_str(), account->getLocalPort()); } void SipTransport::createDefaultSipUdpTransport() @@ -482,7 +461,7 @@ pjsip_tpselector *SipTransport::initTransportSelector(pjsip_transport *transport return tp; } -pjsip_transport *SipTransport::createSTUNTransport(SIPAccount &account) +pjsip_transport *SipTransport::createStunTransport(SIPAccount &account) { pj_str_t serverName = account.getStunServerName(); pj_uint16_t port = account.getStunPort(); @@ -534,17 +513,17 @@ pjsip_transport *SipTransport::createSTUNTransport(SIPAccount &account) return transport; } -void SipTransport::shutdownSipTransport(SIPAccount *account) +void SipTransport::shutdownSipTransport(SIPAccount &account) { - if (account->isStunEnabled()) { - pj_str_t stunServerName = account->getStunServerName(); + 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; + if (account.transport_) { + pjsip_transport_dec_ref(account.transport_); + account.transport_ = NULL; } } diff --git a/daemon/src/sip/siptransport.h b/daemon/src/sip/siptransport.h index aaa5d2c20e4f38f1552f2b9ad1c9f719f511e8fd..ace2d3478b0c5eb624358408649beada800cdc0d 100644 --- a/daemon/src/sip/siptransport.h +++ b/daemon/src/sip/siptransport.h @@ -107,7 +107,7 @@ class SipTransport { * transport type specified in account settings * @param account The account for which a transport must be created. */ - void createSipTransport(SIPAccount *account); + void createSipTransport(SIPAccount &account); void createDefaultSipUdpTransport(); @@ -126,40 +126,10 @@ class SipTransport { */ pjsip_tpselector *initTransportSelector(pjsip_transport *transport, pj_pool_t *tp_pool) const; - /** - * 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 interface to bind this listener to - * @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(const std::string &interface, 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, - const std::string &interface, - pj_uint16_t tlsListenerPort, - pjsip_tls_setting *tlsSetting); - /** * This function unset the transport for a given account. */ - void shutdownSipTransport(SIPAccount *account); + void shutdownSipTransport(SIPAccount &account); /** * Get the correct address to use (ie advertised) from @@ -174,7 +144,26 @@ class SipTransport { private: NON_COPYABLE(SipTransport); - pjsip_transport *createSTUNTransport(SIPAccount &account); + pjsip_transport * + createStunTransport(SIPAccount &account); + /** + * 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 account that is creating the TLS transport + */ + pjsip_transport * + createTlsTransport(SIPAccount &account); + + /** + * 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 SIPAccount for which we are creating the TLS listener + * @return a pointer to the new listener + */ + pjsip_tpfactory * + createTlsListener(SIPAccount &account); /** * UDP Transports are stored in this map in order to retreive them in case diff --git a/daemon/src/sip/sipvoiplink.cpp b/daemon/src/sip/sipvoiplink.cpp index c1ec38d55276c1424e83c810cc41165592c75589..10474dd4ad563d72ef0c858737f426dc02243b68 100644 --- a/daemon/src/sip/sipvoiplink.cpp +++ b/daemon/src/sip/sipvoiplink.cpp @@ -489,7 +489,9 @@ bool SIPVoIPLink::getEvent() void SIPVoIPLink::sendRegister(Account *a) { SIPAccount *account = dynamic_cast<SIPAccount*>(a); - sipTransport.createSipTransport(account); + if (!account) + throw VoipLinkException("SipVoipLink: Account is not SIPAccount"); + sipTransport.createSipTransport(*account); account->setRegister(true); account->setRegistrationState(Trying); @@ -1136,37 +1138,6 @@ bool SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to) call->getLocalSDP()->setLocalIP(localAddress); call->getLocalSDP()->createOffer(account->getActiveCodecs()); - // Init TLS transport if enabled - if (account->isTlsEnabled()) { - size_t at = toUri.find("@"); - size_t trns = toUri.find(";transport"); - if (at == std::string::npos or trns == std::string::npos) { - ERROR("UserAgent: Error \"@\" or \";transport\" not in URI %s", toUri.c_str()); - delete call; - return false; - } - - std::string remoteAddr(toUri.substr(at + 1, trns - at - 1)); - - if (toUri.find("sips:") != 1) { - DEBUG("UserAgent: Error \"sips\" scheme required for TLS call"); - delete call; - return false; - } - - sipTransport.shutdownSipTransport(account); - pjsip_transport *transport = sipTransport.createTlsTransport(account->getLocalInterface(), remoteAddr, - account->getTlsListenerPort(), account->getTlsSetting()); - - if (transport == NULL) { - ERROR("Error could not create TLS transport for IP2IP call"); - delete call; - return false; - } - - account->transport_ = transport; - } - if (!SIPStartCall(call)) { delete call; return false; @@ -1581,7 +1552,7 @@ void registration_cb(pjsip_regc_cbparam *param) account->setRegistrationState(ErrorAuth); account->setRegister(false); - SIPVoIPLink::instance()->sipTransport.shutdownSipTransport(account); + SIPVoIPLink::instance()->sipTransport.shutdownSipTransport(*account); return; } @@ -1615,14 +1586,14 @@ void registration_cb(pjsip_regc_cbparam *param) account->setRegister(false); - SIPVoIPLink::instance()->sipTransport.shutdownSipTransport(account); + SIPVoIPLink::instance()->sipTransport.shutdownSipTransport(*account); } else { if (account->isRegistered()) account->setRegistrationState(Registered); else { account->setRegistrationState(Unregistered); - SIPVoIPLink::instance()->sipTransport.shutdownSipTransport(account); + SIPVoIPLink::instance()->sipTransport.shutdownSipTransport(*account); } } }