diff --git a/src/account.cpp b/src/account.cpp
index 5ed2b5c8197bd8be660b0832d7305af6f7920bbe..a9a123ebdbb3043a9ebc659bc1446a91118c523a 100644
--- a/src/account.cpp
+++ b/src/account.cpp
@@ -52,6 +52,7 @@
 #include "string_utils.h"
 #include "config/yamlparser.h"
 #include "system_codec_container.h"
+#include "ice_transport.h"
 
 #include <yaml-cpp/yaml.h>
 
@@ -539,4 +540,12 @@ Account::getActiveAccountCodecInfoList(MediaType mediaType) const
     return accountCodecList;
 }
 
+const IceTransportOptions
+Account::getIceOptions() const noexcept
+{
+    IceTransportOptions opts;
+    opts.upnpEnable = getUPnPActive();
+    return opts;
+}
+
 } // namespace ring
diff --git a/src/account.h b/src/account.h
index ff49a467ea76cc036c881a22ac7529d94e6f0211..470a59f5a5c2606a4f0c22fa1a31cca78badb6d5 100644
--- a/src/account.h
+++ b/src/account.h
@@ -68,6 +68,7 @@ namespace ring {
 
 class Call;
 class SystemCodecContainer;
+class IceTransportOptions;
 
 class VoipLinkException : public std::runtime_error
 {
@@ -271,6 +272,8 @@ class Account : public Serializable, public std::enable_shared_from_this<Account
          */
         IpAddr getUPnPIpAddress() const;
 
+        virtual const IceTransportOptions getIceOptions() const noexcept;
+
     private:
         NON_COPYABLE(Account);
 
diff --git a/src/call.cpp b/src/call.cpp
index e2f359e053943681958c6c64c8d189bda577d96b..99886a158aa2b07901a57126a2497b23aaadc194 100644
--- a/src/call.cpp
+++ b/src/call.cpp
@@ -271,8 +271,9 @@ bool
 Call::initIceTransport(bool master, unsigned channel_num)
 {
     auto& iceTransportFactory = Manager::instance().getIceTransportFactory();
-    iceTransport_ = iceTransportFactory.createTransport(getCallId().c_str(), channel_num,
-                                                        master, account_.getUPnPActive());
+    iceTransport_ = iceTransportFactory.createTransport(getCallId().c_str(),
+                                                        channel_num, master,
+                                                        account_.getIceOptions());
     return static_cast<bool>(iceTransport_);
 }
 
diff --git a/src/ice_transport.cpp b/src/ice_transport.cpp
index cc04f170835bc204ce4d4f2a395cdf03cb4cef82..293c7891cf4531b856c245267899281ff348553c 100644
--- a/src/ice_transport.cpp
+++ b/src/ice_transport.cpp
@@ -96,21 +96,21 @@ IceTransport::cb_on_ice_complete(pj_ice_strans* ice_st,
         RING_WARN("null IceTransport");
 }
 
-IceTransport::IceTransport(const char* name, int component_count,
-                           bool master, bool upnp_enabled,
-                           IceTransportCompleteCb on_initdone_cb,
-                           IceTransportCompleteCb on_negodone_cb)
+
+IceTransport::IceTransport(const char* name, int component_count, bool master,
+                           const IceTransportOptions& options)
     : pool_(nullptr, pj_pool_release)
-    , on_initdone_cb_(on_initdone_cb)
-    , on_negodone_cb_(on_negodone_cb)
+    , on_initdone_cb_(options.onInitDone)
+    , on_negodone_cb_(options.onNegoDone)
     , component_count_(component_count)
     , compIO_(component_count)
     , initiator_session_(master)
 {
-    if (upnp_enabled)
+    if (options.upnpEnable)
         upnp_.reset(new upnp::Controller());
 
     auto& iceTransportFactory = Manager::instance().getIceTransportFactory();
+    config_ = iceTransportFactory.getIceCfg();
 
     pool_.reset(pj_pool_create(iceTransportFactory.getPoolFactory(),
                                "IceTransport.pool", 512, 512, NULL));
@@ -122,11 +122,46 @@ IceTransport::IceTransport(const char* name, int component_count,
     icecb.on_rx_data = cb_on_rx_data;
     icecb.on_ice_complete = cb_on_ice_complete;
 
+    /* STUN */
+    if (not options.stunServer.empty()) {
+        const auto n = options.stunServer.rfind(':');
+        if (n != std::string::npos) {
+            const auto p = options.stunServer.c_str();
+            pj_strset(&config_.stun.server, (char*)p, n);
+            config_.stun.port = (pj_uint16_t)std::atoi(p+n+1);
+        } else {
+            pj_cstr(&config_.stun.server, options.stunServer.c_str());
+            config_.stun.port = PJ_STUN_PORT;
+        }
+        RING_WARN("ICE: STUN='%s', PORT=%d", options.stunServer.c_str(),
+                 config_.stun.port);
+    }
+
+    /* TURN */
+    if (not options.turnServer.empty()) {
+        const auto n = options.turnServer.rfind(':');
+        if (n != std::string::npos) {
+            const auto p = options.turnServer.c_str();
+            pj_strset(&config_.turn.server, (char*)p, n);
+            config_.turn.port = (pj_uint16_t)std::atoi(p+n+1);
+        } else {
+            pj_cstr(&config_.turn.server, options.turnServer.c_str());
+            config_.turn.port = PJ_STUN_PORT;
+        }
+
+        // No authorization yet
+        //config_.turn.auth_cred.type = PJ_STUN_AUTH_STATIC;
+
+        // Only UDP yet
+        config_.turn.conn_type = PJ_TURN_TP_UDP;
+
+        RING_WARN("ICE: TURN='%s', PORT=%d", options.turnServer.c_str(),
+                 config_.turn.port);
+    }
+
     pj_ice_strans* icest = nullptr;
-    pj_status_t status = pj_ice_strans_create(name,
-                                              iceTransportFactory.getIceCfg(),
-                                              component_count, this, &icecb,
-                                              &icest);
+    pj_status_t status = pj_ice_strans_create(name, &config_, component_count,
+                                              this, &icecb, &icest);
     if (status != PJ_SUCCESS || icest == nullptr)
         throw std::runtime_error("pj_ice_strans_create() failed");
 }
@@ -762,10 +797,6 @@ IceTransportFactory::IceTransportFactory()
     ice_cfg_.turn.cfg.max_pkt_size = 8192;
     //ice_cfg_.stun.max_host_cands = icedemo.opt.max_host;
     ice_cfg_.opt.aggressive = PJ_FALSE;
-
-    // TODO: STUN server candidate
-
-    // TODO: TURN server candidate
 }
 
 IceTransportFactory::~IceTransportFactory()
@@ -841,17 +872,13 @@ IceTransportFactory::processThread()
 }
 
 std::shared_ptr<IceTransport>
-IceTransportFactory::createTransport(const char* name,
-                                     int component_count,
+IceTransportFactory::createTransport(const char* name, int component_count,
                                      bool master,
-                                     bool upnp_enabled,
-                                     IceTransportCompleteCb&& on_initdone_cb,
-                                     IceTransportCompleteCb&& on_negodone_cb)
+                                     const IceTransportOptions& options)
 {
     try {
-        return std::make_shared<IceTransport>(name, component_count, master, upnp_enabled,
-                                              std::forward<IceTransportCompleteCb>(on_initdone_cb),
-                                              std::forward<IceTransportCompleteCb>(on_negodone_cb));
+        return std::make_shared<IceTransport>(name, component_count, master,
+                                              options);
     } catch(const std::exception& e) {
         RING_ERR("%s",e.what());
         return nullptr;
diff --git a/src/ice_transport.h b/src/ice_transport.h
index 9420d960c39394df2c4588e11d79d194a480fb1a..c11d070e0238ac96ecc2a5cb49617bd6ea508dc1 100644
--- a/src/ice_transport.h
+++ b/src/ice_transport.h
@@ -59,6 +59,14 @@ using IceTransportCompleteCb = std::function<void(IceTransport&, bool)>;
 using IceRecvCb = std::function<ssize_t(unsigned char* buf, size_t len)>;
 using IceCandidate = pj_ice_sess_cand;
 
+struct IceTransportOptions {
+        bool upnpEnable {false};
+        IceTransportCompleteCb onInitDone {};
+        IceTransportCompleteCb onNegoDone {};
+        std::string stunServer {};
+        std::string turnServer {};
+};
+
 class IceTransport {
     public:
         using Attribute = struct {
@@ -69,11 +77,8 @@ class IceTransport {
         /**
          * Constructor
          */
-        IceTransport(const char* name, int component_count,
-                     bool master,
-                     bool upnp_enabled = false,
-                     IceTransportCompleteCb on_initdone_cb={},
-                     IceTransportCompleteCb on_negodone_cb={});
+        IceTransport(const char* name, int component_count, bool master,
+                     const IceTransportOptions& options = {});
 
         /**
          * Destructor
@@ -215,6 +220,7 @@ class IceTransport {
         pj_sockaddr remoteAddr_;
         std::condition_variable iceCV_ {};
         mutable std::mutex iceMutex_ {};
+        pj_ice_strans_cfg config_;
 
         struct Packet {
                 Packet(void *pkt, pj_size_t size);
@@ -258,16 +264,14 @@ class IceTransportFactory {
         std::shared_ptr<IceTransport> createTransport(const char* name,
                                                       int component_count,
                                                       bool master,
-                                                      bool upnp_enabled = false,
-                                                      IceTransportCompleteCb&& on_initdone_cb={},
-                                                      IceTransportCompleteCb&& on_negodone_cb={});
+                                                      const IceTransportOptions& options = {});
 
         int processThread();
 
         /**
          * PJSIP specifics
          */
-        const pj_ice_strans_cfg* getIceCfg() const { return &ice_cfg_; }
+        pj_ice_strans_cfg getIceCfg() const { return ice_cfg_; }
         pj_pool_factory* getPoolFactory() { return &cp_.factory; }
 
     private:
diff --git a/src/ringdht/ringaccount.cpp b/src/ringdht/ringaccount.cpp
index 24e756fd4ec0e24ce12a11d3981e5c89061ac7b6..cbd16d7f649a2f3f75f2446e511aaa291d406ce3 100644
--- a/src/ringdht/ringaccount.cpp
+++ b/src/ringdht/ringaccount.cpp
@@ -163,7 +163,7 @@ RingAccount::newOutgoingCall(const std::string& toUrl)
     // Create an ICE transport for SIP channel
     auto& tfactory = manager.getIceTransportFactory();
     auto ice = tfactory.createTransport(("sip:" + call->getCallId()).c_str(),
-                                        ICE_COMPONENTS, true, getUPnPActive());
+                                        ICE_COMPONENTS, true, getIceOptions());
     if (not ice) {
         call->removeCall();
         return nullptr;
@@ -840,11 +840,7 @@ void RingAccount::incomingCall(dht::IceCandidates&& msg)
     RING_WARN("Received incoming DHT call request from %s", from.c_str());
     auto call = Manager::instance().callFactory.newCall<SIPCall, RingAccount>(*this, Manager::instance().getNewCallID(), Call::INCOMING);
     auto ice = Manager::instance().getIceTransportFactory().createTransport(
-        ("sip:"+call->getCallId()).c_str(),
-        ICE_COMPONENTS,
-        false,
-        getUPnPActive()
-    );
+        ("sip:"+call->getCallId()).c_str(), ICE_COMPONENTS, false, getIceOptions());
     if (ice->waitForInitialization(ICE_INIT_TIMEOUT) <= 0)
         throw std::runtime_error("Can't initialize ICE..");
 
diff --git a/src/sip/sipaccountbase.cpp b/src/sip/sipaccountbase.cpp
index 798957761b21710d42e8c2fd072a3f1ef5b9a243..9a182c5a119cd4fc452a5edcbfca2d5de4940002 100644
--- a/src/sip/sipaccountbase.cpp
+++ b/src/sip/sipaccountbase.cpp
@@ -39,6 +39,7 @@
 
 #include "account_schema.h"
 #include "manager.h"
+#include "ice_transport.h"
 
 #include "config/yamlparser.h"
 #include <yaml-cpp/yaml.h>
@@ -324,4 +325,15 @@ SIPAccountBase::generateVideoPort() const
 }
 #endif
 
+const IceTransportOptions
+SIPAccountBase::getIceOptions() const noexcept
+{
+    auto opts = Account::getIceOptions();
+    if (stunEnabled_)
+        opts.stunServer = stunServer_;
+    if (turnEnabled_)
+        opts.turnServer = turnServer_;
+    return opts;
+}
+
 } // namespace ring
diff --git a/src/sip/sipaccountbase.h b/src/sip/sipaccountbase.h
index 0a837e9e10b721aa4a4b0e7ea58bed5869067464..7d9f9f80a25b023e1fbbc0338c9c92cc147a26fa 100644
--- a/src/sip/sipaccountbase.h
+++ b/src/sip/sipaccountbase.h
@@ -242,6 +242,8 @@ public:
         stunServer_ = srv;
     }
 
+    const IceTransportOptions getIceOptions() const noexcept override;
+
 protected:
     virtual void serialize(YAML::Emitter &out);
     virtual void serializeTls(YAML::Emitter &out);