diff --git a/daemon/src/client/configurationmanager.cpp b/daemon/src/client/configurationmanager.cpp index 35b7e57f3d95f984ba125d0a437b6f96f1e8dc0b..1937577e66af839bcc00d203d0c234594c30398c 100644 --- a/daemon/src/client/configurationmanager.cpp +++ b/daemon/src/client/configurationmanager.cpp @@ -41,17 +41,16 @@ #include "account_schema.h" #include "manager.h" #include "sip/sipvoiplink.h" -#include "sip/siptransport.h" #if HAVE_TLS #include "sip/security_evaluator.h" #endif #include "logger.h" #include "fileutils.h" +#include "ip_utils.h" #include "sip/sipaccount.h" #include "history/historynamecache.h" #include "audio/audiolayer.h" - std::map<std::string, std::string> ConfigurationManager::getIp2IpDetails() { SIPAccount *sipaccount = Manager::instance().getIP2IPAccount(); @@ -495,17 +494,17 @@ std::vector<std::map<std::string, std::string> > ConfigurationManager::getHistor std::string ConfigurationManager::getAddrFromInterfaceName(const std::string& interface) { - return SipTransport::getInterfaceAddrFromName(interface); + return ip_utils::addrToStr(ip_utils::getInterfaceAddr(interface)); } std::vector<std::string> ConfigurationManager::getAllIpInterface() { - return SipTransport::getAllIpInterface(); + return ip_utils::getAllIpInterface(); } std::vector<std::string> ConfigurationManager::getAllIpInterfaceByName() { - return SipTransport::getAllIpInterfaceByName(); + return ip_utils::getAllIpInterfaceByName(); } std::map<std::string, std::string> ConfigurationManager::getShortcuts() diff --git a/daemon/src/ip_utils.cpp b/daemon/src/ip_utils.cpp index 7262686739a92f5e50dd051401b8d7660a62cdcf..5e23d56d0d2fb8dd194b0c0fbcd0506a0604a157 100644 --- a/daemon/src/ip_utils.cpp +++ b/daemon/src/ip_utils.cpp @@ -32,10 +32,13 @@ #include "ip_utils.h" #include "logger.h" +#include <arpa/inet.h> +#include <netdb.h> +#include <net/if.h> #include <sys/types.h> #include <sys/socket.h> -#include <netdb.h> -#include <arpa/inet.h> +#include <sys/ioctl.h> +#include <unistd.h> std::vector<pj_sockaddr> ip_utils::getAddrList(const std::string &name) @@ -114,12 +117,110 @@ ip_utils::strToAddr(const std::string& str) pj_sockaddr ip_utils::getAnyHostAddr(pj_uint16_t family) { - if (family == pj_AF_UNSPEC()) family = pj_AF_INET(); + if (family == pj_AF_UNSPEC()) family = pj_AF_INET6(); pj_sockaddr addr = {}; addr.addr.sa_family = family; return addr; } +pj_sockaddr +ip_utils::getLocalAddr(pj_uint16_t family) +{ + if (family == pj_AF_UNSPEC()) family = pj_AF_INET6(); + pj_sockaddr ip_addr; + pj_status_t status = pj_gethostip(family, &ip_addr); + if (status == PJ_SUCCESS) return ip_addr; + WARN("Could not get preferred address familly (%s)", (family == pj_AF_INET6()) ? "IPv6" : "IPv4"); + family = (family == pj_AF_INET()) ? pj_AF_INET6() : pj_AF_INET(); + status = pj_gethostip(family, &ip_addr); + if (status == PJ_SUCCESS) return ip_addr; + ERROR("Could not get local IP"); + ip_addr.addr.sa_family = pj_AF_UNSPEC(); + return ip_addr; +} + +pj_sockaddr +ip_utils::getInterfaceAddr(const std::string &interface, pj_uint16_t family) +{ + ERROR("getInterfaceAddr: %s %d", interface.c_str(), family); + if (interface == DEFAULT_INTERFACE) + return getLocalAddr(family); + auto unix_family = (family == pj_AF_INET()) ? AF_INET : AF_INET6; + int fd = socket(unix_family, SOCK_DGRAM, 0); + if(unix_family == AF_INET6) { + int val = (family == pj_AF_UNSPEC()) ? 0 : 1; + setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&val, sizeof(val)); + } + pj_sockaddr saddr; + if(fd < 0) { + ERROR("Could not open socket: %m", fd); + saddr.addr.sa_family = pj_AF_UNSPEC(); + return saddr; + } + ifreq ifr; + strncpy(ifr.ifr_name, interface.c_str(), sizeof ifr.ifr_name); + // guarantee that ifr_name is NULL-terminated + ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; + + memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr)); + ifr.ifr_addr.sa_family = unix_family; + + ioctl(fd, SIOCGIFADDR, &ifr); + close(fd); + + sockaddr* unix_addr = &ifr.ifr_addr; + memcpy(&saddr, &ifr.ifr_addr, sizeof(pj_sockaddr)); + if ((ifr.ifr_addr.sa_family == AF_INET && IN_IS_ADDR_UNSPECIFIED(&((sockaddr_in *)unix_addr)->sin_addr )) + || (ifr.ifr_addr.sa_family == AF_INET6 && IN6_IS_ADDR_UNSPECIFIED(&((sockaddr_in6*)unix_addr)->sin6_addr))) { + return getLocalAddr(saddr.addr.sa_family); + } + return saddr; +} + +std::vector<std::string> +ip_utils::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_INET6, 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::vector<std::string> +ip_utils::getAllIpInterface() +{ + pj_sockaddr addrList[16]; + unsigned addrCnt = PJ_ARRAY_SIZE(addrList); + + std::vector<std::string> ifaceList; + + if (pj_enum_ip_interface(pj_AF_UNSPEC(), &addrCnt, addrList) == PJ_SUCCESS) { + for (unsigned i = 0; i < addrCnt; i++) { + char addr[PJ_INET6_ADDRSTRLEN]; + pj_sockaddr_print(&addrList[i], addr, sizeof(addr), 0); + ifaceList.push_back(std::string(addr)); + } + } + + return ifaceList; +} + bool ip_utils::isIPv6(const std::string &address) { diff --git a/daemon/src/ip_utils.h b/daemon/src/ip_utils.h index cdae791fa403692e575ff749ae9b316137a61e67..d48da727227856796aeb47469bff8e3a6d940e2e 100644 --- a/daemon/src/ip_utils.h +++ b/daemon/src/ip_utils.h @@ -37,7 +37,15 @@ #include <string> #include <vector> + +/* An IPv4 equivalent to IN6_IS_ADDR_UNSPECIFIED */ +#ifndef IN_IS_ADDR_UNSPECIFIED +#define IN_IS_ADDR_UNSPECIFIED(a) (((long int) (a)->s_addr) == 0x00000000) +#endif /* IN_IS_ADDR_UNSPECIFIED */ + namespace ip_utils { + const std::string DEFAULT_INTERFACE = "default"; + /** * Convert a binary IP address to a standard string representation. */ @@ -56,22 +64,64 @@ namespace ip_utils { */ pj_sockaddr strToAddr(const std::string& str); + /** + * Return the generic "any host" IP address of the specified family. + * If family is unspecified, default to pj_AF_INET6() (IPv6). + */ pj_sockaddr getAnyHostAddr(pj_uint16_t family = pj_AF_UNSPEC()); /** - * Returns true if address is a valid IPv6. + * Return the first host IP address of the specified family. + * If no address of the specified family is found, another family will + * be tried. + * Ex. : if family is pj_AF_INET6() (IPv6/default) and the system does not + * have an IPv6 address, an IPv4 address will be returned if available. + * + * If family is unspcified, default to pj_AF_INET6() (IPv6). */ - bool isIPv6(const std::string &address); + pj_sockaddr getLocalAddr(pj_uint16_t family = pj_AF_UNSPEC()); /** - * Return true if address is a valid IP address of specified family (if provided) or of any kind (default). + * Get the IP address of the network interface interface with the specified + * address family, or of any address family if unspecified (default). */ - bool isValidAddr(const std::string &address, pj_uint16_t family = pj_AF_UNSPEC()); + pj_sockaddr getInterfaceAddr(const std::string &interface, pj_uint16_t family = pj_AF_UNSPEC()); + + /** + * 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. + */ + std::vector<std::string> getAllIpInterfaceByName(); + + /** + * List all the interfaces on the system and return + * a vector list containing their IP address. + * @param void + * @return std::vector<std::string> A std::string vector + * of IP address available on all of the interfaces on + * the system. + */ + std::vector<std::string> getAllIpInterface(); std::vector<pj_sockaddr> getAddrList(const std::string &name); bool haveCommonAddr(const std::vector<pj_sockaddr>& a, const std::vector<pj_sockaddr>& b); + /** + * Return true if address is a valid IP address of specified family (if provided) or of any kind (default). + */ + bool isValidAddr(const std::string &address, pj_uint16_t family = pj_AF_UNSPEC()); + + /** + * Return true if address is a valid IPv6. + */ + bool isIPv6(const std::string &address); + + } #endif // IP_UTILS_H_ diff --git a/daemon/src/sip/siptransport.cpp b/daemon/src/sip/siptransport.cpp index 60853fb52d63299077671ca13ff3faa34925cdff..55899a2d11075273b775787c5473e72eb9c10c83 100644 --- a/daemon/src/sip/siptransport.cpp +++ b/daemon/src/sip/siptransport.cpp @@ -50,132 +50,15 @@ #include <pjlib.h> #include <pjlib-util.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <resolv.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <arpa/inet.h> -#include <net/if.h> -#include <unistd.h> - #include <stdexcept> #include <sstream> -static const char * const DEFAULT_INTERFACE = "default"; - #define RETURN_IF_FAIL(A, VAL, M, ...) if (!(A)) { ERROR(M, ##__VA_ARGS__); return (VAL); } -pj_sockaddr SipTransport::getSIPLocalIP(pj_uint16_t family) -{ - if (family == pj_AF_UNSPEC()) family = pj_AF_INET6(); - pj_sockaddr ip_addr; - pj_status_t status = pj_gethostip(family, &ip_addr); - if (status == PJ_SUCCESS) return ip_addr; - WARN("Could not get preferred IP version (%s)", (family == pj_AF_INET6()) ? "IPv6" : "IPv4"); - family = (family == pj_AF_INET()) ? pj_AF_INET6() : pj_AF_INET(); - status = pj_gethostip(family, &ip_addr); - if (status == PJ_SUCCESS) return ip_addr; - ERROR("Could not get local IP"); - ip_addr.addr.sa_family = pj_AF_UNSPEC(); - return ip_addr; -} - -std::vector<std::string> SipTransport::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_INET6, 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; -} - -pj_sockaddr SipTransport::getInterfaceAddr(const std::string &ifaceName, pj_uint16_t family) -{ - ERROR("getInterfaceAddr: %s %d", ifaceName.c_str(), family); - if (ifaceName == DEFAULT_INTERFACE) - return getSIPLocalIP(family); - auto unix_family = (family == pj_AF_INET()) ? AF_INET : AF_INET6; - int fd = socket(unix_family, SOCK_DGRAM, 0); - if(unix_family == AF_INET6) { - int val = (family == pj_AF_UNSPEC()) ? 0 : 1; - setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&val, sizeof(val)); - } - pj_sockaddr saddr; - if(fd < 0) { - ERROR("Could not open socket: %m", fd); - saddr.addr.sa_family = pj_AF_UNSPEC(); - return saddr; - } - ifreq ifr; - strncpy(ifr.ifr_name, ifaceName.c_str(), sizeof ifr.ifr_name); - // guarantee that ifr_name is NULL-terminated - ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; - - memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr)); - ifr.ifr_addr.sa_family = unix_family; - - ioctl(fd, SIOCGIFADDR, &ifr); - close(fd); - - sockaddr* unix_addr = &ifr.ifr_addr; - memcpy(&saddr, &ifr.ifr_addr, sizeof(pj_sockaddr)); - if ((ifr.ifr_addr.sa_family == AF_INET && IN_IS_ADDR_UNSPECIFIED(&((sockaddr_in *)unix_addr)->sin_addr )) - || (ifr.ifr_addr.sa_family == AF_INET6 && IN6_IS_ADDR_UNSPECIFIED(&((sockaddr_in6*)unix_addr)->sin6_addr))) { - return getSIPLocalIP(saddr.addr.sa_family); - } - return saddr; -} - -std::string SipTransport::getInterfaceAddrFromName(const std::string &ifaceName, bool forceIPv6) -{ - return ip_utils::addrToStr(getInterfaceAddr(ifaceName, forceIPv6 ? pj_AF_INET6() : pj_AF_INET())); -} - -std::vector<std::string> SipTransport::getAllIpInterface() -{ - pj_sockaddr addrList[16]; - unsigned addrCnt = PJ_ARRAY_SIZE(addrList); - - std::vector<std::string> ifaceList; - - if (pj_enum_ip_interface(pj_AF_UNSPEC(), &addrCnt, addrList) == PJ_SUCCESS) { - for (unsigned i = 0; i < addrCnt; i++) { - char addr[PJ_INET6_ADDRSTRLEN]; - pj_sockaddr_print(&addrList[i], addr, sizeof(addr), 0); - ifaceList.push_back(std::string(addr)); - } - } - - return ifaceList; -} - -void tp_state_callback(pjsip_transport *tp, pjsip_transport_state state, const pjsip_transport_state_info* /* info */) -{ - SipTransport& this_ = *SIPVoIPLink::instance().sipTransport; - this_.transportStateChanged(tp, state); -} - SipTransport::SipTransport(pjsip_endpoint *endpt, pj_caching_pool& cp, pj_pool_t& pool, std::function<void(pjsip_transport*)> transportDestroyed) : transportMap_(), transportDestroyedCb_(transportDestroyed), cp_(cp), pool_(pool), endpt_(endpt) { - auto status = pjsip_tpmgr_set_state_cb(pjsip_endpt_get_tpmgr(endpt_), tp_state_callback); + auto status = pjsip_tpmgr_set_state_cb(pjsip_endpt_get_tpmgr(endpt_), SipTransport::tp_state_callback); if (status != PJ_SUCCESS) { ERROR("Can't set transport callback"); sip_utils::sip_strerror(status); @@ -197,6 +80,14 @@ std::string transportMapKey(const std::string &interface, int port, pjsip_transp } } +/** Static tranport state change callback */ +void +SipTransport::tp_state_callback(pjsip_transport *tp, pjsip_transport_state state, const pjsip_transport_state_info* /* info */) +{ + SipTransport& this_ = *SIPVoIPLink::instance().sipTransport; + this_.transportStateChanged(tp, state); +} + void SipTransport::transportStateChanged(pjsip_transport* tp, pjsip_transport_state state) { @@ -284,10 +175,10 @@ pjsip_transport * SipTransport::createUdpTransport(const std::string &interface, pj_uint16_t port, pj_uint16_t family) { pj_sockaddr listeningAddress; - if (interface == DEFAULT_INTERFACE) + if (interface == ip_utils::DEFAULT_INTERFACE) listeningAddress = ip_utils::getAnyHostAddr(family); else - listeningAddress = getInterfaceAddr(interface, family); + listeningAddress = ip_utils::getInterfaceAddr(interface, family); RETURN_IF_FAIL(not listeningAddress.addr.sa_family == pj_AF_UNSPEC(), nullptr, "Could not determine ip address for this transport"); RETURN_IF_FAIL(port != 0, nullptr, "Could not determine port for this transport"); @@ -326,10 +217,10 @@ SipTransport::createTlsListener(SIPAccount &account, pj_uint16_t family) std::string interface(account.getLocalInterface()); pj_sockaddr listeningAddress; - if (interface == DEFAULT_INTERFACE) + if (interface == ip_utils::DEFAULT_INTERFACE) listeningAddress = ip_utils::getAnyHostAddr(family); else - listeningAddress = getInterfaceAddr(interface, family==pj_AF_INET6()); + listeningAddress = ip_utils::getInterfaceAddr(interface, family); pj_sockaddr_set_port(&listeningAddress, account.getTlsListenerPort()); @@ -368,22 +259,19 @@ SipTransport::createTlsTransport(SIPAccount &account) } else ipAddr = remoteAddr; - pj_str_t remote; - pj_cstr(&remote, ipAddr.c_str()); + pj_sockaddr rem_addr = ip_utils::strToAddr(ipAddr); + pj_sockaddr_set_port(&rem_addr, port); - pj_sockaddr_in rem_addr; - pj_sockaddr_in_init(&rem_addr, &remote, (pj_uint16_t) port); - - DEBUG("Get new tls transport/listener from transport manager"); + DEBUG("Get new tls transport/listener from transport manager to %s", ip_utils::addrToStr(rem_addr, true, true).c_str()); // The local tls listener // FIXME: called only once as it is static -> that's why parameters are not saved - pjsip_tpfactory *localTlsListener = createTlsListener(account); + pjsip_tpfactory *localTlsListener = createTlsListener(account, rem_addr.addr.sa_family); pjsip_transport *transport = nullptr; - pj_status_t status = pjsip_endpt_acquire_transport(endpt_, PJSIP_TRANSPORT_TLS, &rem_addr, - sizeof rem_addr, NULL, &transport); - RETURN_IF_FAIL(transport != nullptr and status == PJ_SUCCESS, nullptr, - "Could not create new TLS transport"); + pj_status_t status = pjsip_endpt_acquire_transport(endpt_, PJSIP_TRANSPORT_TLS, &rem_addr, pj_sockaddr_get_len(&rem_addr), nullptr, &transport); + if (status != PJ_SUCCESS) + sip_utils::sip_strerror(status); + RETURN_IF_FAIL(transport != nullptr and status == PJ_SUCCESS, nullptr, "Could not create new TLS transport"); //pjsip_tpmgr_dump_transports(pjsip_endpt_get_tpmgr(endpt_)); return transport; diff --git a/daemon/src/sip/siptransport.h b/daemon/src/sip/siptransport.h index 595ee0ff477114e22ead450a2bc5104a3f3ba397..74cd7e8598778652a75a0292e3fddd652a972d7a 100644 --- a/daemon/src/sip/siptransport.h +++ b/daemon/src/sip/siptransport.h @@ -55,45 +55,12 @@ class SIPAccount; -/* An IPv4 equivalent to IN6_IS_ADDR_UNSPECIFIED */ -#ifndef IN_IS_ADDR_UNSPECIFIED -#define IN_IS_ADDR_UNSPECIFIED(a) (((long int) (a)->s_addr) == 0x00000000) -#endif /* IN_IS_ADDR_UNSPECIFIED */ class SipTransport { public: SipTransport(pjsip_endpoint *endpt, pj_caching_pool& cp, pj_pool_t& pool, std::function<void(pjsip_transport*)> transportDestroyed = std::function<void(pjsip_transport*)>()); ~SipTransport(); - static pj_sockaddr getSIPLocalIP(pj_uint16_t family = pj_AF_UNSPEC()); - - /** - * Get the IP for the network interface named ifaceName - * @param forceIPv6 If IPv4 and IPv6 are available, will force to IPv6. - */ - static std::string getInterfaceAddrFromName(const std::string &ifaceName, bool forceIPv6 = false); - static pj_sockaddr getInterfaceAddr(const std::string &ifaceName, pj_uint16_t family = pj_AF_UNSPEC()); - - /** - * 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 IP address. - * @param void - * @return std::vector<std::string> A std::string vector - * of IP address available on all of the interfaces on - * the system. - */ - static std::vector<std::string> getAllIpInterface(); - /** * General Sip transport creation method according to the * transport type specified in account settings @@ -114,9 +81,7 @@ class SipTransport { /** * This function returns a list of STUN mapped sockets for * a given set of socket file descriptors */ - std::vector<pj_sockaddr> - getSTUNAddresses(const SIPAccount &account, - std::vector<long> &socks) const; + std::vector<pj_sockaddr> getSTUNAddresses(const SIPAccount &account, std::vector<long> &socks) const; /** * Get the correct address to use (ie advertised) from @@ -172,6 +137,8 @@ class SipTransport { pjsip_transport *createUdpTransport(const std::string &interface, pj_uint16_t port, pj_uint16_t family = pj_AF_UNSPEC()); + static void tp_state_callback(pjsip_transport *, pjsip_transport_state, const pjsip_transport_state_info *); + /** * UDP Transports are stored in this map in order to retreive them in case * several accounts would share the same port number. diff --git a/daemon/src/sip/sipvoiplink.cpp b/daemon/src/sip/sipvoiplink.cpp index 7dc3dfd5601fbd45d025856548f3b2f70dad86ef..234d644746b695c30c480a6634df75be754b61fc 100644 --- a/daemon/src/sip/sipvoiplink.cpp +++ b/daemon/src/sip/sipvoiplink.cpp @@ -315,7 +315,7 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata) // FIXME : for now, use the same address family as the SIP tranport auto family = pjsip_transport_type_get_af(account->getTransportType()); - auto addrToUse = SipTransport::getInterfaceAddr(account->getLocalInterface(), family); + auto addrToUse = ip_utils::getInterfaceAddr(account->getLocalInterface(), family); // May use the published address as well auto addrSdp = account->isStunEnabled() or (not account->getPublishedSameasLocal()) @@ -559,7 +559,7 @@ SIPVoIPLink::SIPVoIPLink() : sipTransport(), sipAccountMap_(), } })); - if (SipTransport::getSIPLocalIP().addr.sa_family == pj_AF_UNSPEC()) + if (ip_utils::getLocalAddr().addr.sa_family == pj_AF_UNSPEC()) throw VoipLinkException("UserAgent: Unable to determine network capabilities"); TRY(pjsip_tsx_layer_init_module(endpt_)); @@ -932,7 +932,7 @@ Call *SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to call->setIPToIP(true); call->initRecFilename(to); - auto localAddress = SipTransport::getInterfaceAddr(account->getLocalInterface(), ipv6 ? pj_AF_INET6() : pj_AF_INET()); + auto localAddress = ip_utils::getInterfaceAddr(account->getLocalInterface(), ipv6 ? pj_AF_INET6() : pj_AF_INET()); setCallMediaLocal(call, localAddress); @@ -998,7 +998,7 @@ Call *SIPVoIPLink::newRegisteredAccountCall(const std::string& id, const std::st // FIXME : for now, use the same address family as the SIP tranport auto family = pjsip_transport_type_get_af(account->getTransportType()); - auto localAddr = SipTransport::getInterfaceAddr(account->getLocalInterface(), family); + auto localAddr = ip_utils::getInterfaceAddr(account->getLocalInterface(), family); setCallMediaLocal(call, localAddr); // May use the published address as well @@ -1877,7 +1877,7 @@ void sdp_create_offer_cb(pjsip_inv_session *inv, pjmedia_sdp_session **p_offer) // FIXME : for now, use the same address family as the SIP tranport auto family = pjsip_transport_type_get_af(account->getTransportType()); auto address = account->getPublishedSameasLocal() - ? SipTransport::getInterfaceAddr(account->getLocalInterface(), family) + ? ip_utils::getInterfaceAddr(account->getLocalInterface(), family) : account->getPublishedIpAddress(); setCallMediaLocal(call, address);