From b15a96ad76919ccc3471a3869cb658bb3aa56ae3 Mon Sep 17 00:00:00 2001
From: Roman Khlopkov <roman.khlopkov@demlabs.net>
Date: Fri, 20 Aug 2021 17:24:32 +0300
Subject: [PATCH] [*] Modules dynamic reworked

---
 dap-sdk/crypto/src/oaes/oaes_lib.c            |  3 +-
 .../http_server/http_client/dap_http_client.c |  4 +-
 .../cdb/dap_modules_dynamic_cdb.c             | 59 ++++++++++++-------
 .../cdb/include/dap_modules_dynamic_cdb.h     |  3 +-
 modules/net/dap_chain_net.c                   |  2 +-
 modules/net/dap_chain_node_client.c           |  3 +
 modules/net/srv/CMakeLists.txt                |  2 +-
 modules/net/srv/dap_chain_net_srv.c           | 41 +++----------
 modules/service/vpn/CMakeLists.txt            |  2 +-
 .../service/vpn/dap_chain_net_vpn_client.c    |  1 +
 .../dap_chain_net_srv_vpn_cdb_server_list.h   |  6 ++
 11 files changed, 64 insertions(+), 62 deletions(-)

diff --git a/dap-sdk/crypto/src/oaes/oaes_lib.c b/dap-sdk/crypto/src/oaes/oaes_lib.c
index 96d06863ee..326cbf8b50 100755
--- a/dap-sdk/crypto/src/oaes/oaes_lib.c
+++ b/dap-sdk/crypto/src/oaes/oaes_lib.c
@@ -615,8 +615,9 @@ static OAES_RET oaes_key_gen( OAES_CTX * ctx, size_t key_size )
 		return OAES_RET_ARG1;
 	
 	oaes_key_destroy( &(_ctx->key_flat) );
-    if(_key == NULL)
+    if(_key == NULL) {
         return OAES_RET_ARG1;
+    }
 
 	_key->data_len = key_size;
 	
diff --git a/dap-sdk/net/server/http_server/http_client/dap_http_client.c b/dap-sdk/net/server/http_server/http_client/dap_http_client.c
index 6a93998d27..f3bbcc5f93 100644
--- a/dap-sdk/net/server/http_server/http_client/dap_http_client.c
+++ b/dap-sdk/net/server/http_server/http_client/dap_http_client.c
@@ -647,9 +647,9 @@ void dap_http_client_out_header_generate(dap_http_client_t *a_http_client)
             log_it(L_DEBUG,"output: Content-Type = '%s'",a_http_client->out_content_type);
         }
         if ( a_http_client->out_content_length ) {
-            dap_snprintf(buf,sizeof(buf),"%"DAP_UINT64_FORMAT_U"",(unsigned long long)a_http_client->out_content_length);
+            dap_snprintf(buf,sizeof(buf),"%"DAP_UINT64_FORMAT_u"",a_http_client->out_content_length);
             dap_http_header_add(&a_http_client->out_headers,"Content-Length",buf);
-            log_it(L_DEBUG,"output: Content-Length = %"DAP_UINT64_FORMAT_U"",a_http_client->out_content_length);
+            log_it(L_DEBUG,"output: Content-Length = %"DAP_UINT64_FORMAT_u"",a_http_client->out_content_length);
         }
     }else
         if (s_debug_http)
diff --git a/modules/modules_dynamic/cdb/dap_modules_dynamic_cdb.c b/modules/modules_dynamic/cdb/dap_modules_dynamic_cdb.c
index 079cd913b5..4b234c34f7 100644
--- a/modules/modules_dynamic/cdb/dap_modules_dynamic_cdb.c
+++ b/modules/modules_dynamic/cdb/dap_modules_dynamic_cdb.c
@@ -32,38 +32,53 @@
 #define LOG_TAG "dap_http"
 
 static const char * s_default_path_modules = "var/modules";
+static void *s_cdb_handle = NULL;
 
-int dap_modules_dynamic_load_cdb(dap_http_t * a_server){
+void dap_modules_dynamic_close_cdb()
+{
+    if (s_cdb_handle) {
+        dlclose(s_cdb_handle);
+        s_cdb_handle = NULL;
+    }
+}
+
+void *dap_modules_dynamic_get_cdb_func(const char *a_func_name)
+{
     char l_lib_path[MAX_PATH] = {'\0'};
+    void *l_ref_func = NULL;
+    //  find func from dynamic library
 #if defined (DAP_OS_LINUX) && !defined (__ANDROID__)
     const char * l_cdb_so_name = "libcellframe-node-cdb.so";
-    dap_sprintf(l_lib_path, "%s/%s/%s", g_sys_dir_path, s_default_path_modules, l_cdb_so_name);
+    if (!s_cdb_handle) {
+        dap_sprintf(l_lib_path, "%s/%s/%s", g_sys_dir_path, s_default_path_modules, l_cdb_so_name);
 
-    void* l_cdb_handle = NULL;
-    l_cdb_handle = dlopen(l_lib_path, RTLD_NOW);
-    if(!l_cdb_handle){
-        log_it(L_ERROR,"Can't load %s module: %s", l_cdb_so_name, dlerror());
-        return -1;
+        s_cdb_handle = dlopen(l_lib_path, RTLD_NOW);
+        if (!s_cdb_handle) {
+            log_it(L_ERROR,"Can't load %s module: %s", l_cdb_so_name, dlerror());
+            return NULL;
+        }
     }
 
-    int (*dap_chain_net_srv_vpn_cdb_init)(dap_http_t*);
-    const char * l_init_func_name = "dap_chain_net_srv_vpn_cdb_init";
-    *(void **) (&dap_chain_net_srv_vpn_cdb_init) = dlsym(l_cdb_handle, l_init_func_name);
-    char* error;
-    if (( error = dlerror()) != NULL) {
-        log_it(L_ERROR,"%s module: %s error loading (%s)", l_cdb_so_name, l_init_func_name, error);
-        return -2;
-     }
+    l_ref_func = dlsym(s_cdb_handle, a_func_name);
 
-    int l_init_res = (*dap_chain_net_srv_vpn_cdb_init)(a_server);
-    if(l_init_res){
-        log_it(L_ERROR,"%s: %s returns %d", l_cdb_so_name, l_init_func_name, error);
-        return -3;
+    if (!l_ref_func) {
+        log_it(L_ERROR,"%s module: %s error loading (%s)", l_cdb_so_name, a_func_name, dlerror());
+        return NULL;
     }
-
-    return 0;
 #else
     log_it(L_ERROR,"%s: module is not supported on current platfrom", __PRETTY_FUNCTION__);
-    return -3;
 #endif
+    return l_ref_func;
+}
+
+int dap_modules_dynamic_load_cdb(dap_http_t * a_server)
+{
+    int (*dap_chain_net_srv_vpn_cdb_init)(dap_http_t *);
+    dap_chain_net_srv_vpn_cdb_init = dap_modules_dynamic_get_cdb_func("dap_chain_net_srv_vpn_cdb_init");
+    int l_init_res = dap_chain_net_srv_vpn_cdb_init(a_server);
+    if (l_init_res) {
+        log_it(L_ERROR,"dap_modules_dynamic: dap_chain_net_srv_vpn_cdb_init returns %d", l_init_res);
+        return -3;
+    }
+    return 0;
 }
diff --git a/modules/modules_dynamic/cdb/include/dap_modules_dynamic_cdb.h b/modules/modules_dynamic/cdb/include/dap_modules_dynamic_cdb.h
index 492b98c711..5f395b833a 100644
--- a/modules/modules_dynamic/cdb/include/dap_modules_dynamic_cdb.h
+++ b/modules/modules_dynamic/cdb/include/dap_modules_dynamic_cdb.h
@@ -26,4 +26,5 @@
 #include "dap_http.h"
 
 int dap_modules_dynamic_load_cdb(dap_http_t * a_server);
-
+void *dap_modules_dynamic_get_cdb_func(const char *a_func_name);
+void dap_modules_dynamic_close_cdb();
diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index 6dfd45a8ef..a54f91f39d 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -392,7 +392,7 @@ static void s_chain_callback_notify(void * a_arg, dap_chain_t *a_chain, dap_chai
         pthread_rwlock_rdlock(&PVT(l_net)->rwlock);
         for (dap_list_t *l_tmp = PVT(l_net)->links; l_tmp; l_tmp = dap_list_next(l_tmp)) {
             dap_chain_node_client_t *l_node_client = (dap_chain_node_client_t *)l_tmp->data;
-            dap_worker_t * l_worker = dap_client_get_stream_worker( l_node_client->client);
+            dap_stream_worker_t * l_worker = dap_client_get_stream_worker( l_node_client->client);
             if(l_worker)
                 dap_stream_ch_chain_pkt_write_mt(l_worker, l_node_client->ch_chain_uuid, DAP_STREAM_CH_CHAIN_PKT_TYPE_CHAIN,
                                               l_net->pub.id.uint64, a_chain->id.uint64, a_id.uint64, a_atom, a_atom_size);
diff --git a/modules/net/dap_chain_node_client.c b/modules/net/dap_chain_node_client.c
index 0fb8a84e7a..b5db413d42 100644
--- a/modules/net/dap_chain_node_client.c
+++ b/modules/net/dap_chain_node_client.c
@@ -271,6 +271,7 @@ static void s_stage_connected_callback(dap_client_t *a_client, void *a_arg)
         dap_stream_t * l_stream  = dap_client_get_stream(a_client);
         if (l_stream) {
             l_node_client->esocket_uuid = l_stream->esocket->uuid;
+            l_node_client->stream_worker = l_stream->stream_worker;
             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));
@@ -691,7 +692,9 @@ void dap_chain_node_client_close(dap_chain_node_client_t *a_client)
         inet_ntop(AF_INET, &a_client->info->hdr.ext_addr_v4, l_node_addr_str, INET_ADDRSTRLEN);
         log_it(L_INFO, "Closing node client to uplink %s:%d", l_node_addr_str, a_client->info->hdr.ext_port);
         // clean client
+        DAP_CLIENT_PVT(a_client->client)->stage_status_error_callback = NULL;
         a_client->client->_inheritor = NULL;
+        dap_events_socket_remove_and_delete_mt(a_client->stream_worker->worker, a_client->esocket_uuid);
         dap_client_delete_mt(a_client->client);
 #ifndef _WIN32
         pthread_cond_destroy(&a_client->wait_cond);
diff --git a/modules/net/srv/CMakeLists.txt b/modules/net/srv/CMakeLists.txt
index 54d4d4be1e..70e34da697 100644
--- a/modules/net/srv/CMakeLists.txt
+++ b/modules/net/srv/CMakeLists.txt
@@ -7,7 +7,7 @@ file(GLOB DAP_CHAIN_NET_SRV_HEADERS include/*.h libmaxminddb/*.h)
 
 add_library(${PROJECT_NAME} STATIC ${DAP_CHAIN_NET_SRV_SRCS} ${DAP_CHAIN_NET_SRV_HEADERS})
 
-target_link_libraries(dap_chain_net_srv dap_core dap_crypto dap_chain dap_chain_net dap_chain_wallet)
+target_link_libraries(dap_chain_net_srv dap_core dap_crypto dap_chain dap_chain_net dap_chain_wallet dap_modules_dynamic_cdb)
 
 target_include_directories(dap_chain_net_srv INTERFACE .)
 target_include_directories(${PROJECT_NAME} PUBLIC include)
diff --git a/modules/net/srv/dap_chain_net_srv.c b/modules/net/srv/dap_chain_net_srv.c
index a3de7a17fb..abec2696ae 100644
--- a/modules/net/srv/dap_chain_net_srv.c
+++ b/modules/net/srv/dap_chain_net_srv.c
@@ -60,6 +60,7 @@
 #include "dap_chain_net_srv.h"
 #include "dap_chain_net_srv_order.h"
 #include "dap_chain_net_srv_stream_session.h"
+#include "dap_modules_dynamic_cdb.h"
 
 #include "dap_chain_node_cli_cmd.h"
 
@@ -178,29 +179,6 @@ void dap_chain_net_srv_deinit(void)
     dap_chain_net_srv_del_all();
 }
 
-
-static void* get_cdb_func(const char *func_name)
-{
-    void *l_ref_func = NULL;
-    //  find func from dynamic library
-#if defined (DAP_OS_LINUX) && !defined (__ANDROID__) && defined(DAP_MODULES_DYNAMIC)
-    const char * s_default_path_modules = "var/modules";
-    const char * l_cdb_so_name = "libcellframe-node-cdb.so";
-    char *l_lib_path = dap_strdup_printf("%s/%s/%s", g_sys_dir_path, s_default_path_modules, l_cdb_so_name);
-    void* l_cdb_handle = NULL;
-    l_cdb_handle = dlopen(l_lib_path, RTLD_NOW);
-    DAP_DELETE(l_lib_path);
-    if(!l_cdb_handle) {
-        log_it(L_ERROR, "Can't load %s module: %s", l_cdb_so_name, dlerror());
-    }
-    else {
-        l_ref_func = dlsym(l_cdb_handle, func_name);
-        dlclose(l_cdb_handle);
-    }
-#endif
-    return l_ref_func;
-}
-
 /**
  * @brief s_cli_net_srv
  * @param argc
@@ -554,10 +532,9 @@ static int s_cli_net_srv( int argc, char **argv, void *arg_func, char **a_str_re
             }
         }else if( dap_strcmp( l_order_str, "recheck" ) == 0 ){
             //int dap_chain_net_srv_vpn_cdb_server_list_check_orders(dap_chain_net_t *a_net);
-            int (*dap_chain_net_srv_vpn_cdb_server_list_check_orders)(dap_chain_net_t *a_net) = NULL;
-            *(void **) (&dap_chain_net_srv_vpn_cdb_server_list_check_orders) = get_cdb_func("dap_chain_net_srv_vpn_cdb_server_list_check_orders");
-            int l_init_res = dap_chain_net_srv_vpn_cdb_server_list_check_orders ? (*dap_chain_net_srv_vpn_cdb_server_list_check_orders)(l_net) : -5;
-            //int l_init_res = dap_chain_net_srv_vpn_cdb_server_list_check_orders(l_net);
+            int (*dap_chain_net_srv_vpn_cdb_server_list_check_orders)(dap_chain_net_t *a_net);
+            dap_chain_net_srv_vpn_cdb_server_list_check_orders = dap_modules_dynamic_get_cdb_func("dap_chain_net_srv_vpn_cdb_server_list_check_orders");
+            int l_init_res = dap_chain_net_srv_vpn_cdb_server_list_check_orders ? dap_chain_net_srv_vpn_cdb_server_list_check_orders(l_net) : -5;
             ret = (l_init_res > 0) ? 0 : -10;
 
         }else if( dap_strcmp( l_order_str, "static" ) == 0 ){
@@ -570,12 +547,11 @@ static int s_cli_net_srv( int argc, char **argv, void *arg_func, char **a_str_re
             int (*dap_chain_net_srv_vpn_cdb_server_list_static_delete)(dap_chain_net_t *a_net) = NULL;
             //  find func from dinamic library
             if(l_subcmd_save || l_subcmd_del) {
-                *(void **) (&dap_chain_net_srv_vpn_cdb_server_list_static_create) = get_cdb_func("dap_chain_net_srv_vpn_cdb_server_list_static_create");
-                *(void **) (&dap_chain_net_srv_vpn_cdb_server_list_static_delete) = get_cdb_func("dap_chain_net_srv_vpn_cdb_server_list_static_delete");
+                dap_chain_net_srv_vpn_cdb_server_list_static_create = dap_modules_dynamic_get_cdb_func("dap_chain_net_srv_vpn_cdb_server_list_static_create");
+                dap_chain_net_srv_vpn_cdb_server_list_static_delete = dap_modules_dynamic_get_cdb_func("dap_chain_net_srv_vpn_cdb_server_list_static_delete");
             }
             if(l_subcmd_save) {
-                int l_init_res = dap_chain_net_srv_vpn_cdb_server_list_static_create ? (*dap_chain_net_srv_vpn_cdb_server_list_static_create)(l_net) : -5;
-                //int l_init_res = dap_chain_net_srv_vpn_cdb_server_list_static_create(l_net);
+                int l_init_res = dap_chain_net_srv_vpn_cdb_server_list_static_create ? dap_chain_net_srv_vpn_cdb_server_list_static_create(l_net) : -5;
                 if(l_init_res >= 0){
                     dap_string_append_printf(l_string_ret, "Static node list saved, %d orders in list\n", l_init_res);
                     ret = 0;
@@ -586,8 +562,7 @@ static int s_cli_net_srv( int argc, char **argv, void *arg_func, char **a_str_re
                 }
 
             } else if(l_subcmd_del) {
-                int l_init_res = dap_chain_net_srv_vpn_cdb_server_list_static_delete ? (*dap_chain_net_srv_vpn_cdb_server_list_static_delete)(l_net) : -5;
-                //int l_init_res = dap_chain_net_srv_vpn_cdb_server_list_static_delete(l_net);
+                int l_init_res = dap_chain_net_srv_vpn_cdb_server_list_static_delete ? dap_chain_net_srv_vpn_cdb_server_list_static_delete(l_net) : -5;
                 if(!l_init_res){
                     dap_string_append_printf(l_string_ret, "Static node list deleted\n");
                     ret = 0;
diff --git a/modules/service/vpn/CMakeLists.txt b/modules/service/vpn/CMakeLists.txt
index 9383e4082f..30e2258599 100644
--- a/modules/service/vpn/CMakeLists.txt
+++ b/modules/service/vpn/CMakeLists.txt
@@ -15,7 +15,7 @@ endif()
 
 add_library(${PROJECT_NAME} STATIC ${DAP_CHAIN_NET_SRV_VPN_SRCS} ${DAP_CHAIN_NET_SRV_VPN_HEADERS})
 
-target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_stream dap_stream_ch_chain_net_srv dap_chain dap_chain_crypto dap_chain_net dap_chain_net_srv)
+target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_stream dap_stream_ch_chain_net_srv dap_chain dap_chain_crypto dap_chain_net dap_chain_net_srv dap_modules_dynamic_cdb)
 add_definitions("-DDAP_TUN_IN_WORKER")
 
 target_include_directories(${PROJECT_NAME} INTERFACE .)
diff --git a/modules/service/vpn/dap_chain_net_vpn_client.c b/modules/service/vpn/dap_chain_net_vpn_client.c
index 988387f818..8574096e29 100644
--- a/modules/service/vpn/dap_chain_net_vpn_client.c
+++ b/modules/service/vpn/dap_chain_net_vpn_client.c
@@ -68,6 +68,7 @@
 #include "dap_chain_net_srv_vpn_cmd.h"
 #include "dap_chain_net_srv_vpn_cdb_server_list.h"
 //#include "dap_chain_net_vpn_client_data.h"
+#include "dap_modules_dynamic_cdb.h"
 
 /*
  #if !defined( dap_http_client_state_t )
diff --git a/modules/service/vpn/include/dap_chain_net_srv_vpn_cdb_server_list.h b/modules/service/vpn/include/dap_chain_net_srv_vpn_cdb_server_list.h
index 1aa4f8be6c..88878e94fc 100644
--- a/modules/service/vpn/include/dap_chain_net_srv_vpn_cdb_server_list.h
+++ b/modules/service/vpn/include/dap_chain_net_srv_vpn_cdb_server_list.h
@@ -27,10 +27,16 @@
 #pragma once
 
 #include "dap_enc_http.h"
+#include "dap_chain_net.h"
 #include <stdbool.h>
 
 struct dap_http;
 
+typedef struct dap_orders_callback_params {
+    dap_chain_net_t *net;
+    int multiplicity;
+} dap_orders_callback_params_t;
+
 int get_order_state(dap_chain_node_addr_t a_node_addr);
 
 int dap_chain_net_srv_vpn_cdb_server_list_init(void);
-- 
GitLab