From 4c408d6b2377cba128d92778fe5bae3cecce4949 Mon Sep 17 00:00:00 2001
From: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
Date: Tue, 17 Apr 2012 08:40:31 -0400
Subject: [PATCH] #9623: Open TLS listener on selected interface

---
 daemon/src/sip/siptransport.cpp | 23 +++++++++++++++++------
 daemon/src/sip/siptransport.h   |  4 +++-
 daemon/src/sip/sipvoiplink.cpp  |  4 ++--
 3 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/daemon/src/sip/siptransport.cpp b/daemon/src/sip/siptransport.cpp
index e3340f4c2b..e173692794 100644
--- a/daemon/src/sip/siptransport.cpp
+++ b/daemon/src/sip/siptransport.cpp
@@ -61,6 +61,8 @@
 #include "dbus/callmanager.h"
 #include "dbus/configurationmanager.h"
 
+static const char * const DEFAULT_INTERFACE = "default";
+
 static pjsip_transport *localUDPTransport_ = NULL; /** The default transport (5060) */
 
 std::string SipTransport::getSIPLocalIP()
@@ -245,7 +247,7 @@ pj_status_t SipTransport::destroyStunResolver(const std::string &serverName)
 }
 
 
-void SipTransport::createTlsListener(pj_uint16_t tlsListenerPort, pjsip_tls_setting *tlsSetting, pjsip_tpfactory **listener)
+void SipTransport::createTlsListener(const std::string &interface, pj_uint16_t tlsListenerPort, pjsip_tls_setting *tlsSetting, pjsip_tpfactory **listener)
 {
     pj_sockaddr_in local_addr;
     pj_sockaddr_in_init(&local_addr, 0, 0);
@@ -261,13 +263,22 @@ void SipTransport::createTlsListener(pj_uint16_t tlsListenerPort, pjsip_tls_sett
         return;
     }
 
+    std::string listeningAddress;
+    if (interface == DEFAULT_INTERFACE)
+        listeningAddress = getSIPLocalIP();
+    else
+        listeningAddress = getInterfaceAddrFromName(interface);
+
+    if (listeningAddress.empty()) {
+        ERROR("SipTransport: Could not determine ip address for this transport");
+    }
+
     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()),
+        pj_str((char*) listeningAddress.c_str()),
         local_addr.sin_port
     };
 
@@ -277,6 +288,7 @@ void SipTransport::createTlsListener(pj_uint16_t tlsListenerPort, pjsip_tls_sett
 
 pjsip_transport *
 SipTransport::createTlsTransport(const std::string &remoteAddr,
+                                const std::string &interface,
                                 pj_uint16_t tlsListenerPort,
                                 pjsip_tls_setting *tlsSettings)
 {
@@ -292,7 +304,7 @@ SipTransport::createTlsTransport(const std::string &remoteAddr,
     static pjsip_tpfactory *localTlsListener = NULL;
 
     if (localTlsListener == NULL)
-        createTlsListener(tlsListenerPort, tlsSettings, &localTlsListener);
+        createTlsListener(interface, tlsListenerPort, tlsSettings, &localTlsListener);
 
     pjsip_endpt_acquire_transport(endpt_, PJSIP_TRANSPORT_TLS, &rem_addr,
                                   sizeof rem_addr, NULL, &transport);
@@ -319,7 +331,7 @@ void SipTransport::createSipTransport(SIPAccount *account)
         size_t trns = remoteSipUri.find(";transport");
         std::string remoteAddr(remoteSipUri.substr(sips, trns-sips));
 
-        pjsip_transport *transport = createTlsTransport(remoteAddr, account->getTlsListenerPort(), account->getTlsSetting());
+        pjsip_transport *transport = createTlsTransport(remoteAddr, account->getLocalInterface(), account->getTlsListenerPort(), account->getTlsSetting());
         account->transport_ = transport;
     } else if (account->isStunEnabled()) {
         pjsip_transport *transport = createStunTransport(account->getStunServerName(), account->getStunPort());
@@ -392,7 +404,6 @@ SipTransport::createUdpTransport(const std::string &interface, unsigned int port
     DEBUG("SipTransport: Create UDP transport on %s:%d", interface.c_str(), port);
 
     // determine the ip address for this transport
-    static const char * const DEFAULT_INTERFACE = "default";
     std::string listeningAddress;
     if (interface == DEFAULT_INTERFACE)
         listeningAddress = getSIPLocalIP();
diff --git a/daemon/src/sip/siptransport.h b/daemon/src/sip/siptransport.h
index 21e2c87801..7b2d4d107e 100644
--- a/daemon/src/sip/siptransport.h
+++ b/daemon/src/sip/siptransport.h
@@ -131,6 +131,7 @@ class SipTransport {
         /**
          * 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
@@ -140,7 +141,7 @@ class SipTransport {
          *      - 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 **);
+        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.
@@ -153,6 +154,7 @@ class SipTransport {
          */
         pjsip_transport *
         createTlsTransport(const std::string &remoteAddr,
+                           const std::string &interface,
                            pj_uint16_t tlsListenerPort,
                            pjsip_tls_setting *tlsSetting);
 
diff --git a/daemon/src/sip/sipvoiplink.cpp b/daemon/src/sip/sipvoiplink.cpp
index ab728da213..57a046a44b 100644
--- a/daemon/src/sip/sipvoiplink.cpp
+++ b/daemon/src/sip/sipvoiplink.cpp
@@ -1149,8 +1149,8 @@ bool SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to)
         }
 
         sipTransport.shutdownSipTransport(account);
-        pjsip_transport *transport = sipTransport.createTlsTransport(remoteAddr, account->getTlsListenerPort(),
-                                                              account->getTlsSetting());
+        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");
-- 
GitLab