From 6f15399ef628922a3a34d2d5d9bc0dd2df551987 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Blin?= <contact@enconn.fr>
Date: Tue, 10 Apr 2018 16:57:46 -0400
Subject: [PATCH] datatransfer: reconnect to turn server when necessary

For a lot of reasons, the connection to the turn server can be lost,
we should relaunch a connection between the daemon and the turn server
to avoid to block a future transfer.

Change-Id: I02fea8a220d7d42fcc563dc5c97436b4fd55c618
---
 src/ringdht/p2p.cpp | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/src/ringdht/p2p.cpp b/src/ringdht/p2p.cpp
index df817169f3..9d09b05145 100644
--- a/src/ringdht/p2p.cpp
+++ b/src/ringdht/p2p.cpp
@@ -380,6 +380,7 @@ private:
 
     std::atomic_bool connected_ {false};
     std::mutex listenersMutex_;
+    std::mutex turnMutex_;
     std::vector<ListenerFunction> listeners_;
 
     std::future<void> processTask_;
@@ -392,7 +393,10 @@ private:
 void
 DhtPeerConnector::Impl::turnConnect()
 {
-    if (turnAuthv4_ || turnAuthv6_)
+    std::lock_guard<std::mutex> lock(clientsMutex_);
+    // Don't retry to reconnect to the TURN server if already connected
+    if (turnAuthv4_ && turnAuthv4_->isReady()
+        && turnAuthv6_ && turnAuthv6_->isReady())
         return;
 
     auto details = account.getAccountDetails();
@@ -414,6 +418,13 @@ DhtPeerConnector::Impl::turnConnect()
         else
             ctrl << makeMsg<CtrlMsgType::TURN_PEER_DISCONNECT>(peer_addr);
     };
+
+    // If a previous turn server exists, but is not ready, we should try to reconnect
+    if (turnAuthv4_ && !turnAuthv4_->isReady())
+        turnAuthv4_.release();
+    if (turnAuthv6_ && !turnAuthv6_->isReady())
+        turnAuthv6_.release();
+
     turn_param_v4.authorized_family = PJ_AF_INET;
     turnAuthv4_ = std::make_unique<TurnTransport>(turn_param_v4);
     auto turn_param_v6 = turn_param_v4;
-- 
GitLab