From 2572785bfc0a38b97b6dbe9c122bb510b2ff2d38 Mon Sep 17 00:00:00 2001
From: Roman Khlopkov <roman.khlopkov@demlabs.net>
Date: Thu, 16 Dec 2021 13:04:51 +0300
Subject: [PATCH] [*] Network links fixes

---
 dap-sdk/core/include/dap_math_ops.h         |  2 +-
 dap-sdk/net/client/dap_client_pvt.c         | 11 ++--
 modules/net/dap_chain_net.c                 | 60 ++++++++++-----------
 modules/net/dap_chain_node_client.c         | 17 +++---
 modules/net/include/dap_chain_node_client.h |  2 +-
 5 files changed, 43 insertions(+), 49 deletions(-)

diff --git a/dap-sdk/core/include/dap_math_ops.h b/dap-sdk/core/include/dap_math_ops.h
index b7bd03b4b9..652f3467cc 100755
--- a/dap-sdk/core/include/dap_math_ops.h
+++ b/dap-sdk/core/include/dap_math_ops.h
@@ -5,7 +5,7 @@
 
 #if defined(__GNUC__) || defined (__clang__)
 
-#if __SIZEOF_INT128__ == 16
+#if __SIZEOF_INT128__ == 8
 
 #define DAP_GLOBAL_IS_INT128
 typedef __int128 _dap_int128_t;
diff --git a/dap-sdk/net/client/dap_client_pvt.c b/dap-sdk/net/client/dap_client_pvt.c
index 885c157150..76509fce56 100644
--- a/dap-sdk/net/client/dap_client_pvt.c
+++ b/dap-sdk/net/client/dap_client_pvt.c
@@ -79,7 +79,7 @@
 #define DAP_ENC_KS_KEY_ID_SIZE 33
 #endif
 
-static int s_max_attempts = 5;
+static int s_max_attempts = 3;
 static int s_timeout = 20;
 static bool s_debug_more = false;
 static time_t s_client_timeout_read_after_connect_seconds = 5;
@@ -124,10 +124,11 @@ static bool s_stream_timer_timeout_check(void * a_arg);
  */
 int dap_client_pvt_init()
 {
-    s_max_attempts = dap_config_get_item_int32_default(g_config,"dap_client","max_tries",5);
-    s_timeout = dap_config_get_item_int32_default(g_config,"dap_client","timeout",10);
-    s_debug_more = dap_config_get_item_bool_default(g_config,"dap_client","debug_more",false);
-    s_client_timeout_read_after_connect_seconds = (time_t) dap_config_get_item_uint32_default(g_config,"dap_client","timeout_read_after_connect",5);
+    s_max_attempts = dap_config_get_item_int32_default(g_config, "dap_client", "max_tries", s_max_attempts);
+    s_timeout = dap_config_get_item_int32_default(g_config, "dap_client", "timeout", s_timeout);
+    s_debug_more = dap_config_get_item_bool_default(g_config, "dap_client", "debug_more", false);
+    s_client_timeout_read_after_connect_seconds = (time_t) dap_config_get_item_uint32_default(g_config,
+                                                  "dap_client","timeout_read_after_connect", s_client_timeout_read_after_connect_seconds);
 
     return 0;
 }
diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index ba65a5fbd9..a729dcf41b 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -532,16 +532,13 @@ static void s_node_link_callback_connected(dap_chain_node_client_t * a_node_clie
     }
 
     a_node_client->resync_gdb = l_net_pvt->flags & F_DAP_CHAIN_NET_SYNC_FROM_ZERO;
-    if (!a_node_client->is_reconnecting) {
-        if ( s_debug_more )
-        log_it(L_NOTICE, "Established connection with %s."NODE_ADDR_FP_STR,l_net->pub.name,
-               NODE_ADDR_FP_ARGS_S(a_node_client->remote_node_addr));
-        pthread_rwlock_wrlock(&l_net_pvt->rwlock);
-        l_net_pvt->links = dap_list_append(l_net_pvt->links, a_node_client);
-        l_net_pvt->links_connected_count++;
-        s_net_links_notify(l_net);
-    }
-
+    if ( s_debug_more )
+    log_it(L_NOTICE, "Established connection with %s."NODE_ADDR_FP_STR,l_net->pub.name,
+           NODE_ADDR_FP_ARGS_S(a_node_client->remote_node_addr));
+    pthread_rwlock_wrlock(&l_net_pvt->rwlock);
+    l_net_pvt->links_connected_count++;
+    a_node_client->is_connected = true;
+    s_net_links_notify(l_net);
     if(l_net_pvt->state == NET_STATE_LINKS_CONNECTING ){
         l_net_pvt->state = NET_STATE_LINKS_ESTABLISHED;
         dap_proc_queue_add_callback_inter(a_node_client->stream_worker->worker->proc_queue_input,s_net_states_proc,l_net );
@@ -560,21 +557,18 @@ static void s_node_link_callback_disconnected(dap_chain_node_client_t * a_node_c
     dap_chain_net_t * l_net = (dap_chain_net_t *) a_arg;
     dap_chain_net_pvt_t * l_net_pvt = PVT(l_net);
     pthread_rwlock_wrlock(&l_net_pvt->rwlock);
-    if (l_net_pvt->state_target != NET_STATE_OFFLINE) {
-        if(s_debug_more)
-            log_it(L_NOTICE, "%s."NODE_ADDR_FP_STR" disconnected, reconnecting back...",
-                                l_net->pub.name,
-                                NODE_ADDR_FP_ARGS_S(a_node_client->remote_node_addr) );
-        a_node_client->is_reconnecting = true;
-
-        dap_chain_net_client_create_n_connect(l_net, a_node_client->info);
-    } else {
-        if(l_net_pvt->links_connected_count) {
-            s_node_link_callback_delete(a_node_client,a_arg);
+    if (a_node_client->is_connected) {
+        a_node_client->is_connected = false;
+        log_it(L_INFO, "%s."NODE_ADDR_FP_STR" disconnected.%s",l_net->pub.name,
+               NODE_ADDR_FP_ARGS_S(a_node_client->info->hdr.address),
+               l_net_pvt->state_target == NET_STATE_OFFLINE ? "" : " Reconnecting back...");
+        if (l_net_pvt->links_connected_count)
             l_net_pvt->links_connected_count--;
-        } else
-            log_it(L_CRITICAL,"Links count is zero in disconnected callback, looks smbd decreased it twice or forget to increase on connect/reconnect");
-        log_it(L_INFO, "%s."NODE_ADDR_FP_STR" disconnected",l_net->pub.name,NODE_ADDR_FP_ARGS_S(a_node_client->info->hdr.address));
+        else
+            log_it(L_ERROR, "Links count is zero in disconnected callback, looks smbd decreased it twice or forget to increase on connect/reconnect");
+    }
+    if (l_net_pvt->state_target != NET_STATE_OFFLINE) {
+        a_node_client->keep_connection = true;
     }
     pthread_rwlock_unlock(&l_net_pvt->rwlock);
 }
@@ -981,16 +975,18 @@ static bool s_net_states_proc(dap_proc_thread_t *a_thread, void *a_arg)
             log_it(L_INFO, "%s.state: NET_STATE_LINKS_CONNECTING",l_net->pub.name);
             for (dap_list_t *l_tmp = l_net_pvt->links_info; l_tmp; l_tmp = dap_list_next(l_tmp)) {
                 dap_chain_node_info_t *l_link_info = (dap_chain_node_info_t *)l_tmp->data;
-                (void) dap_chain_net_client_create_n_connect(l_net,l_link_info);
+                dap_chain_node_client_t *l_client = dap_chain_net_client_create_n_connect(l_net, l_link_info);
+                l_client->keep_connection = false;
+                l_net_pvt->links = dap_list_append(l_net_pvt->links, l_client);
+                if (dap_list_length(l_net_pvt->links) == s_required_links_count)
+                    break;
             }
         } break;
+
         case NET_STATE_LINKS_ESTABLISHED:{
             log_it(L_INFO,"%s.state: NET_STATE_LINKS_ESTABLISHED", l_net->pub.name);
-            for (dap_list_t *l_tmp = l_net_pvt->links ; l_tmp; l_tmp = dap_list_next(l_tmp)) {
-                //dap_chain_node_client_t *l_link = (dap_chain_node_client_t *)l_tmp->data;
-                //
-            }
         }break;
+
         case NET_STATE_SYNC_GDB :{
             log_it(L_INFO,"%s.state: NET_STATE_SYNC_GDB", l_net->pub.name);
         }break;
@@ -999,11 +995,11 @@ static bool s_net_states_proc(dap_proc_thread_t *a_thread, void *a_arg)
             log_it(L_INFO,"%s.state: NET_STATE_SYNC_CHAINS", l_net->pub.name);
         }break;
 
-
         case NET_STATE_ONLINE: {
             log_it(L_NOTICE,"%s.state: NET_STATE_ONLINE", l_net->pub.name);
         }
         break;
+
         default: log_it (L_DEBUG, "Unprocessed state");
     }
     s_net_states_notify(l_net);
@@ -1187,8 +1183,8 @@ void s_set_reply_text_node_status(char **a_str_reply, dap_chain_net_t * a_net){
     char* l_sync_current_link_text_block = NULL;
     if (PVT(a_net)->state != NET_STATE_OFFLINE)
         l_sync_current_link_text_block = dap_strdup_printf(", active links %u from %u",
-                                                           dap_list_length(PVT(a_net)->links),
-                                                           dap_list_length(PVT(a_net)->links_info));
+                                                           PVT(a_net)->links_connected_count,
+                                                           dap_list_length(PVT(a_net)->links));
     dap_chain_node_cli_set_reply_text(a_str_reply,
                                       "Network \"%s\" has state %s (target state %s)%s%s",
                                       a_net->pub.name, c_net_states[PVT(a_net)->state],
diff --git a/modules/net/dap_chain_node_client.c b/modules/net/dap_chain_node_client.c
index d4934ddf60..a286d8f400 100644
--- a/modules/net/dap_chain_node_client.c
+++ b/modules/net/dap_chain_node_client.c
@@ -154,7 +154,6 @@ static void s_stage_status_error_callback(dap_client_t *a_client, void *a_arg)
     // check for last attempt
     bool l_is_last_attempt = a_arg ? true : false;
     if (l_is_last_attempt) {
-        dap_chain_node_client_state_t l_prev_state = l_node_client->state;
         pthread_mutex_lock(&l_node_client->wait_mutex);
         l_node_client->state = NODE_CLIENT_STATE_DISCONNECTED;
 #ifndef _WIN32
@@ -165,15 +164,15 @@ static void s_stage_status_error_callback(dap_client_t *a_client, void *a_arg)
         pthread_mutex_unlock(&l_node_client->wait_mutex);
         l_node_client->esocket_uuid = 0;
 
-        if (l_prev_state >= NODE_CLIENT_STATE_ESTABLISHED && l_node_client->callbacks.disconnected) {
+        if (l_node_client->callbacks.disconnected) {
             l_node_client->callbacks.disconnected(l_node_client, l_node_client->callbacks_arg);
-        } else if (l_node_client->keep_connection) {
-            dap_events_socket_uuid_t *l_uuid = DAP_NEW(dap_events_socket_uuid_t);
-            memcpy(l_uuid, &l_node_client->uuid, sizeof(dap_events_socket_uuid_t));
+        }
+        if (l_node_client->keep_connection) {
+            dap_events_socket_uuid_t *l_uuid = DAP_DUP(&l_node_client->uuid);
             dap_timerfd_start_on_worker(l_node_client->stream_worker
                                              ? l_node_client->stream_worker->worker
                                              : dap_events_worker_get_auto(),
-                                        s_timer_update_states*1000,
+                                        s_timer_update_states * 1000,
                                         s_timer_update_states_callback,
                                         l_uuid);
         }
@@ -251,7 +250,8 @@ static bool s_timer_update_states_callback(void *a_arg)
     l_me->state = NODE_CLIENT_STATE_DISCONNECTED;
     if (l_me->keep_connection) {
         log_it(L_INFO, "Reconnecting node client with peer "NODE_ADDR_FP_STR, NODE_ADDR_FP_ARGS_S(l_me->remote_node_addr));
-        dap_chain_node_client_connect_internal(l_me, "CN"); // isn't always CN here?
+        l_me->state = NODE_CLIENT_STATE_CONNECTING ;
+        dap_client_go_stage(l_me->client, STAGE_STREAM_STREAMING, s_stage_connected_callback);
     }
     DAP_DELETE(l_uuid);
     return false;
@@ -671,7 +671,6 @@ static bool dap_chain_node_client_connect_internal(dap_chain_node_client_t *a_no
 {
     a_node_client->client = dap_client_new(a_node_client->events, s_stage_status_callback,
             s_stage_status_error_callback);
-    a_node_client->keep_connection = true;
     dap_client_set_is_always_reconnect(a_node_client->client, false);
     a_node_client->client->_inheritor = a_node_client;
     dap_client_set_active_channels_unsafe(a_node_client->client, a_active_channels);
@@ -696,8 +695,6 @@ static bool dap_chain_node_client_connect_internal(dap_chain_node_client_t *a_no
     }
     dap_client_set_uplink_unsafe(a_node_client->client, strdup(host), a_node_client->info->hdr.ext_port);
     a_node_client->state = NODE_CLIENT_STATE_CONNECTING ;
-    // ref pvt client
-    //dap_client_pvt_ref(DAP_CLIENT_PVT(a_node_client->client));
     // Handshake & connect
     dap_client_go_stage(a_node_client->client, STAGE_STREAM_STREAMING, s_stage_connected_callback);
     return true;
diff --git a/modules/net/include/dap_chain_node_client.h b/modules/net/include/dap_chain_node_client.h
index 92a7ba56d3..21902259e9 100644
--- a/modules/net/include/dap_chain_node_client.h
+++ b/modules/net/include/dap_chain_node_client.h
@@ -114,7 +114,7 @@ typedef struct dap_chain_node_client {
 
     bool keep_connection;
 
-    bool is_reconnecting;
+    bool is_connected;
     // callbacks
     dap_chain_node_client_callbacks_t callbacks;
     void * callbacks_arg;
-- 
GitLab