From 452e3904f2009bdfc0821f72585f2c5b6fb6cb06 Mon Sep 17 00:00:00 2001
From: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
Date: Mon, 9 Jan 2017 11:53:56 -0500
Subject: [PATCH] dht: IPv6 support for ICE public address

This patch uses the fist IPv6 address given by DHT nodes as public address
used for ICE negotiation.
This address is used in priority, overloading any previous one registered,
in particular over IPv4 one.

Change-Id: Ie3b3d9edcfe61871adcb87b965860530ab4f1d31
Reviewed-by: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
---
 src/ice_transport.cpp       |  2 +-
 src/ringdht/ringaccount.cpp | 37 +++++++++++++++++++++++--------------
 2 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/src/ice_transport.cpp b/src/ice_transport.cpp
index c8aa56d9ab..dc359963e1 100644
--- a/src/ice_transport.cpp
+++ b/src/ice_transport.cpp
@@ -634,7 +634,7 @@ IceTransport::registerPublicIP(unsigned compId, const IpAddr& publicIP)
     // even if on the public side it have strong probabilities to not exist.
     // But as this candidate is made after initialization, it's not used during
     // negotiation, only to exchanged candidates between peers.
-    auto localIP = ip_utils::getLocalAddr();
+    auto localIP = ip_utils::getLocalAddr(publicIP.getFamily());
     auto pubIP = publicIP;
     for (const auto& addr : getLocalCandidatesAddr(compId)) {
         auto port = addr.getPort();
diff --git a/src/ringdht/ringaccount.cpp b/src/ringdht/ringaccount.cpp
index 5c64f10a82..0413efc40a 100644
--- a/src/ringdht/ringaccount.cpp
+++ b/src/ringdht/ringaccount.cpp
@@ -2981,24 +2981,33 @@ RingAccount::sendTextMessage(const std::string& to, const std::map<std::string,
 void
 RingAccount::registerDhtAddress(IceTransport& ice)
 {
-    auto ip = getPublishedAddress();
+    static const auto reg_addr =                    \
+        [](IceTransport& ice, const IpAddr& ip) {
+            RING_DBG("[dht] using public IP: %s", ip.toString().c_str());
+            for (unsigned compId = 1; compId <= ice.getComponentCount(); ++compId)
+                ice.registerPublicIP(compId, ip);
+            return ip;
+        };
 
-    // We need a public address in case of NAT'ed network
-    // Trying to use one discovered by DHT service
+    auto ip = getPublishedAddress();
     if (ip.empty()) {
-        const auto& addresses = dht_.getPublicAddress(AF_INET);
-        if (addresses.size()) {
-            ip = IpAddr {addresses[0].first};
-            setPublishedAddress(ip);
-        }
-    }
+        // We need a public address in case of NAT'ed network
+        // Trying to use one discovered by DHT service
 
-    if (!ip.empty()) {
+        // IPv4
+        const auto& addr4 = dht_.getPublicAddress(AF_INET);
+        if (addr4.size())
+            setPublishedAddress(reg_addr(ice, addr4[0].first));
+
+        // IPv6 (must be put after IPv4 as SDP support only one address, we priorize IPv6)
+        const auto& addr6 = dht_.getPublicAddress(AF_INET6);
+        if (addr6.size())
+            setPublishedAddress(reg_addr(ice, addr6[0].first));
+
+    } else {
         RING_DBG("[dht] Using pub IP: %s", ip.c_str());
-        for (unsigned compId = 1; compId <= ice.getComponentCount(); ++compId)
-            ice.registerPublicIP(compId, ip);
-    } else
-        RING_WARN("[dht] No public IP found!");
+        reg_addr(ice, ip);
+    }
 }
 
 } // namespace ring
-- 
GitLab