diff --git a/src/ice_transport.cpp b/src/ice_transport.cpp
index b0af4ac9c35a18ca370c96ee6b1e0cc0624b104a..4ecdbcce67782de2d2919d39702fe394c431ddbc 100644
--- a/src/ice_transport.cpp
+++ b/src/ice_transport.cpp
@@ -634,10 +634,6 @@ IceTransport::registerPublicIP(unsigned compId, const IpAddr& publicIP)
     if (not isInitialized())
         return false;
 
-    // Register only if no NAT traversal methods exists
-    if (upnp_ or config_.stun.port > 0 or config_.turn.port > 0)
-        return false;
-
     // Find the local candidate corresponding to local host,
     // then register a rflx candidate using given public address
     // and this local address as base. It's port is used for both address
@@ -661,13 +657,54 @@ IceTransport::registerPublicIP(unsigned compId, const IpAddr& publicIP)
 void
 IceTransport::addReflectiveCandidate(int comp_id, const IpAddr& base, const IpAddr& addr)
 {
+    // HACK-HACK-HACK-HACK-HACK-HACK-HACK-HACK-HACK-HACK-HACK-HACK-HACK-HACK-HACK-HACK-HACK-HACK
+    // WARNING: following implementation is a HACK of PJNATH !!
+    // ice_strans doesn't have any API that permit to inject ICE any kind of candidates.
+    // So, the hack consists in accessing hidden ICE session using a patched PJPNATH
+    // library with a new API exposing this session (pj_ice_strans_get_ice_sess).
+    // Then call pj_ice_sess_add_cand() with a carfully forged candidate:
+    // the transport_id field uses an index in ICE transport STUN servers array
+    // corresponding to a STUN server with the same address familly.
+    // This implies we hope they'll not be modification of transport_id meaning in future
+    // and no conflics with the borrowed STUN config.
+    // HACK-HACK-HACK-HACK-HACK-HACK-HACK-HACK-HACK-HACK-HACK-HACK-HACK-HACK-HACK-HACK-HACK-HACK
+
+    // borrowed from pjproject/pjnath/ice_strans.c, modified to be C++11'ized.
+    static auto CREATE_TP_ID = [](pj_uint8_t type, pj_uint8_t idx) {
+        return (pj_uint8_t)((type << 6) | idx);
+    };
+    static constexpr int SRFLX_PREF = 65535;
+    static constexpr int TP_STUN = 1;
+
+    // find a compatible STUN host with same address familly, normally all system enabled
+    // host addresses are represented, so we expect to always found this host
+    int idx = -1;
+    auto af = addr.getFamily();
+    if (af == AF_UNSPEC) {
+        RING_ERR("[ice] Unable to add reflective IP %s: unknown addess familly",
+                 addr.toString().c_str());
+        return;
+    }
+
+    for (unsigned i=0; i < config_.stun_tp_cnt; ++i) {
+        if (config_.stun_tp[i].af == af) {
+            idx = i;
+            break;
+        }
+    }
+    if (idx < 0) {
+        RING_ERR("[ice] Unable to add reflective IP %s: no suitable local STUN host found",
+                 addr.toString().c_str());
+        return;
+    }
+
     pj_ice_sess_cand cand;
 
     cand.type = PJ_ICE_CAND_TYPE_SRFLX;
-    cand.status = PJ_EPENDING; /* not used */
+    cand.status = PJ_EPENDING; // not used
     cand.comp_id = comp_id;
-    cand.transport_id = 1; /* 1 = STUN */
-    cand.local_pref = 65535; /* host */
+    cand.transport_id = CREATE_TP_ID(TP_STUN, idx); // HACK!!
+    cand.local_pref = SRFLX_PREF; // reflective
     /* cand.foundation = ? */
     /* cand.prio = calculated by ice session */
     /* make base and addr the same since we're not going through a server */