diff --git a/daemon/src/sip/sipvoiplink.cpp b/daemon/src/sip/sipvoiplink.cpp index 9b0d18be145d1c86ef5e7e97c07976a67919c153..3eefdad8e1914429a78400014007fb4c66292f69 100644 --- a/daemon/src/sip/sipvoiplink.cpp +++ b/daemon/src/sip/sipvoiplink.cpp @@ -1288,13 +1288,34 @@ pj_status_t SIPVoIPLink::stunServerResolve(SIPAccount *account) return status; } +#define DEFAULT_TRANSPORT_ATTEMPT 5 void SIPVoIPLink::createDefaultSipUdpTransport() { + pjsip_transport *transport = NULL; + pj_uint16_t port = 0; + int counter = 0; + SIPAccount *account = dynamic_cast<SIPAccount *>(Manager::instance().getAccount(IP2IP_PROFILE)); - createUdpTransport(account); - assert(account->transport_); + while((transport == NULL) and (counter < DEFAULT_TRANSPORT_ATTEMPT)) { + // 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); + counter++; + } + + if(transport == NULL) { + ERROR("UserAgent: Create UDP transport "); + return; + } + + DEBUG("UserAgent: Created defautl sip transport on %d", port); + + // set transport for this account + account->transport_ = transport; + + // set local udp transport localUDPTransport_ = account->transport_; } @@ -1340,6 +1361,11 @@ void SIPVoIPLink::createSipTransport(SIPAccount *account) { shutdownSipTransport(account); + if(account == NULL) { + ERROR("Acccount is NULL while creating sip transport"); + return; + } + if (account->isTlsEnabled()) { std::string remoteSipUri(account->getServerUri()); static const char SIPS_PREFIX[] = "<sips:"; @@ -1350,8 +1376,10 @@ void SIPVoIPLink::createSipTransport(SIPAccount *account) createTlsTransport(account, remoteAddr); } else if (account->isStunEnabled()) createStunTransport(account); - else - createUdpTransport(account); + 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 @@ -1366,47 +1394,70 @@ void SIPVoIPLink::createSipTransport(SIPAccount *account) } } -void SIPVoIPLink::createUdpTransport(SIPAccount *account) +#define DEFAULT_INTERFACE "default" + +pjsip_transport *SIPVoIPLink::createUdpTransport(std::string interface, unsigned int port) { + pjsip_transport *transport = NULL; std::string listeningAddress; - pj_uint16_t listeningPort = account->getLocalPort(); + pj_uint16_t listeningPort = (pj_uint16_t)port; + pj_status_t status = PJ_SUCCESS; + // init socket to bind this transport to pj_sockaddr_in bound_addr; pj_bzero(&bound_addr, sizeof(bound_addr)); bound_addr.sin_port = pj_htons(listeningPort); bound_addr.sin_family = PJ_AF_INET; - if (account->getLocalInterface() == "default") { + // determine the ip address for this transport + if (interface == DEFAULT_INTERFACE) { listeningAddress = getSIPLocalIP(); bound_addr.sin_addr.s_addr = pj_htonl(PJ_INADDR_ANY); } else { - listeningAddress = getInterfaceAddrFromName(account->getLocalInterface()); + listeningAddress = getInterfaceAddrFromName(interface); bound_addr.sin_addr = pj_inet_addr2(listeningAddress.c_str()); } + /* if (!account->getPublishedSameasLocal()) { listeningAddress = account->getPublishedAddress(); listeningPort = account->getPublishedPort(); } + */ // We must specify this here to avoid the IP2IP_PROFILE creating a // transport with the name 0.0.0.0 appearing in the via header - if (account->getAccountID() == IP2IP_PROFILE) - listeningAddress = getSIPLocalIP(); + // if (account->getAccountID() == IP2IP_PROFILE) + // listeningAddress = getSIPLocalIP(); - if (listeningAddress.empty() or listeningPort == 0) - return; + 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_udp_transport_start(endpt_, &bound_addr, &a_name, 1, &account->transport_); - pjsip_tpmgr_dump_transports(pjsip_endpt_get_tpmgr(endpt_)); // dump debug information to stdout + status = pjsip_udp_transport_start(endpt_, &bound_addr, &a_name, 1, &transport); + if(status != PJ_SUCCESS) { + ERROR("SIP: Could not create udp transport"); + return NULL; + } + + // dump debug information to stdout + pjsip_tpmgr_dump_transports(pjsip_endpt_get_tpmgr(endpt_)); + + transportMap_[listeningPort] = transport; - if (account->transport_) - transportMap_[account->getLocalPort()] = account->transport_; + return transport; } pjsip_tpselector *SIPVoIPLink::initTransportSelector(pjsip_transport *transport, pj_pool_t *tp_pool) const diff --git a/daemon/src/sip/sipvoiplink.h b/daemon/src/sip/sipvoiplink.h index 12d63f7263c5e042df537bcc679641a1ab1ba191..e43b91b03ddee34d09151338a3ff711a2f0c2afb 100644 --- a/daemon/src/sip/sipvoiplink.h +++ b/daemon/src/sip/sipvoiplink.h @@ -327,7 +327,7 @@ class SIPVoIPLink : public VoIPLink { * Create SIP UDP transport from account's setting * @param account The account for which a transport must be created. */ - void createUdpTransport(SIPAccount *account); + pjsip_transport *createUdpTransport(std::string interface, unsigned int port); /** * Create a TLS transport from the default TLS listener from