From 7591c528d0be464a13dcd7f39dc9906a502fbfcc Mon Sep 17 00:00:00 2001
From: moneromooo-monero <moneromooo-monero@users.noreply.github.com>
Date: Wed, 9 Aug 2017 22:44:39 +0100
Subject: [PATCH] p2p: fallback on seed nodes if we can't make a connection

This avoids failing to connect to the network in case all
known peers are unavailable (which can happen if the peer
list is small).
---
 src/p2p/net_node.h   |  1 +
 src/p2p/net_node.inl | 31 +++++++++++++++++++++++++------
 2 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h
index 4e1e60d27..22ae5ec26 100644
--- a/src/p2p/net_node.h
+++ b/src/p2p/net_node.h
@@ -226,6 +226,7 @@ namespace nodetool
     bool is_addr_recently_failed(const epee::net_utils::network_address& addr);
     bool is_priority_node(const epee::net_utils::network_address& na);
     std::set<std::string> get_seed_nodes(bool testnet) const;
+    bool connect_to_seed();
 
     template <class Container>
     bool connect_to_peerlist(const Container& peers);
diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl
index 58a7f3563..376d45afa 100644
--- a/src/p2p/net_node.inl
+++ b/src/p2p/net_node.inl
@@ -1171,14 +1171,11 @@ namespace nodetool
   }
   //-----------------------------------------------------------------------------------
   template<class t_payload_net_handler>
-  bool node_server<t_payload_net_handler>::connections_maker()
+  bool node_server<t_payload_net_handler>::connect_to_seed()
   {
-    if (!connect_to_peerlist(m_exclusive_peers)) return false;
+      if (m_seed_nodes.empty())
+        return true;
 
-    if (!m_exclusive_peers.empty()) return true;
-
-    if(!m_peerlist.get_white_peers_count() && m_seed_nodes.size())
-    {
       size_t try_count = 0;
       size_t current_index = crypto::rand<size_t>()%m_seed_nodes.size();
       bool fallback_nodes_added = false;
@@ -1211,6 +1208,21 @@ namespace nodetool
         if(++current_index >= m_seed_nodes.size())
           current_index = 0;
       }
+      return true;
+  }
+  //-----------------------------------------------------------------------------------
+  template<class t_payload_net_handler>
+  bool node_server<t_payload_net_handler>::connections_maker()
+  {
+    if (!connect_to_peerlist(m_exclusive_peers)) return false;
+
+    if (!m_exclusive_peers.empty()) return true;
+
+    size_t start_conn_count = get_outgoing_connections_count();
+    if(!m_peerlist.get_white_peers_count() && m_seed_nodes.size())
+    {
+      if (!connect_to_seed())
+        return false;
     }
 
     if (!connect_to_peerlist(m_priority_peers)) return false;
@@ -1242,6 +1254,13 @@ namespace nodetool
       }
     }
 
+    if (start_conn_count == get_outgoing_connections_count() && start_conn_count < m_config.m_net_config.connections_count)
+    {
+      MINFO("Failed to connect to any, trying seeds");
+      if (!connect_to_seed())
+        return false;
+    }
+
     return true;
   }
   //-----------------------------------------------------------------------------------