From 2ff18b8d4e0699fcabc316dec19d581322491719 Mon Sep 17 00:00:00 2001 From: Aleksandr Lysikov <lysikov@inbox.ru> Date: Sun, 17 Feb 2019 19:08:15 +0500 Subject: [PATCH] add uthash to the list of established connections --- dap_chain_node_cli_cmd.c | 18 +++++-- dap_chain_node_cli_cmd.h | 8 +++ dap_chain_node_remote.c | 103 ++++++++++++++++++++++++++++----------- dap_chain_node_remote.h | 25 +++++----- 4 files changed, 111 insertions(+), 43 deletions(-) diff --git a/dap_chain_node_cli_cmd.c b/dap_chain_node_cli_cmd.c index f17c9383dc..f5ea1f6896 100644 --- a/dap_chain_node_cli_cmd.c +++ b/dap_chain_node_cli_cmd.c @@ -124,7 +124,7 @@ static bool del_alias(const char *alias) * * return addr, NULL if not found */ -static dap_chain_node_addr_t* get_name_by_alias(const char *alias) +dap_chain_node_addr_t* get_name_by_alias(const char *alias) { dap_chain_node_addr_t *addr = NULL; if(!alias) @@ -733,7 +733,7 @@ int com_node(int argc, const char ** argv, char **str_reply) if(!node_info) { return -1; } - int timeout_ms = 100000; //100 sec. + int timeout_ms = 10000; //10 sec. // start handshake chain_node_client_t *client = chain_node_client_connect(node_info); if(!client) { @@ -753,8 +753,18 @@ int com_node(int argc, const char ** argv, char **str_reply) DAP_DELETE(node_info); //Add new established connection in the list - chain_node_client_list_add(client); - + int ret = chain_node_client_list_add(&address, client); + switch (ret) + { + case -1: + chain_node_client_close(client); + set_reply_text(str_reply, "connection established, but not saved"); + return -1; + case -2: + chain_node_client_close(client); + set_reply_text(str_reply, "connection already present"); + return -1; + } set_reply_text(str_reply, "connection established"); break; } diff --git a/dap_chain_node_cli_cmd.h b/dap_chain_node_cli_cmd.h index c27e7ec822..3303207c5f 100644 --- a/dap_chain_node_cli_cmd.h +++ b/dap_chain_node_cli_cmd.h @@ -21,8 +21,16 @@ #pragma once +#include "dap_chain_node.h" #include "dap_chain_node_cli.h" +/** + * Find in base addr by alias + * + * return addr, NULL if not found + */ +dap_chain_node_addr_t* get_name_by_alias(const char *alias); + /** * Look up NAME as the name of a command, and return a pointer to that * command. Return a NULL pointer if NAME isn't a command name. diff --git a/dap_chain_node_remote.c b/dap_chain_node_remote.c index 914a847221..dcb72890a6 100644 --- a/dap_chain_node_remote.c +++ b/dap_chain_node_remote.c @@ -22,69 +22,116 @@ #include <stdint.h> #include <stdlib.h> #include <string.h> -#include <glib.h> #include <pthread.h> +#include "uthash.h" #include "dap_chain_node_remote.h" +typedef struct dap_chain_item { + dap_chain_node_addr_t address; + chain_node_client_t *client; + UT_hash_handle hh; +} list_linked_item_t; // List of connections -static GList *connect_list = NULL; +static list_linked_item_t *conn_list = NULL; // for separate access to connect_list static pthread_mutex_t connect_list_mutex = PTHREAD_MUTEX_INITIALIZER; /** - * Add new established connection in the list + * Add new established connection to the list + * + * return 0 OK, -1 error, -2 already present */ -bool chain_node_client_list_add(chain_node_client_t *client) +int chain_node_client_list_add(dap_chain_node_addr_t *address, chain_node_client_t *client) { - if(!client) - return false; + int ret = 0; + if(!address || !client) + return -1; + list_linked_item_t *item_tmp; pthread_mutex_lock(&connect_list_mutex); - connect_list = g_list_append(connect_list, client); + HASH_FIND(hh, conn_list, address, sizeof(dap_chain_node_addr_t), item_tmp); // address already in the hash? + if(item_tmp == NULL) { + item_tmp = DAP_NEW(list_linked_item_t); + item_tmp->address.uint64 = address->uint64; + item_tmp->client = client; + HASH_ADD(hh, conn_list, address, sizeof(dap_chain_node_addr_t), item_tmp); // address: name of key field + ret = 0; + } + // connection already present + else + ret = -2; + //connect_list = g_list_append(connect_list, client); pthread_mutex_unlock(&connect_list_mutex); - return true; + return ret; } /** * Delete established connection from the list + * + * return 0 OK, -1 error, -2 address not found */ -bool chain_node_client_list_del(chain_node_client_t *client) +int chain_node_client_list_del(dap_chain_node_addr_t *address) { + int ret = -1; + if(!address) + return -1; + list_linked_item_t *item_tmp; pthread_mutex_lock(&connect_list_mutex); - GList *list = g_list_find(connect_list, client); - // found - if(list) - connect_list = g_list_remove(connect_list, client); + HASH_FIND(hh, conn_list, address, sizeof(dap_chain_node_addr_t), item_tmp); + if(item_tmp != NULL) { + HASH_DEL(conn_list, item_tmp); + ret = 0; + } + else + // address not found in the hash + ret = -2; pthread_mutex_unlock(&connect_list_mutex); - if(list) - return true; - return false; + if(!ret) { + // close connection + chain_node_client_close(item_tmp->client); + // del struct for hash + DAP_DELETE(item_tmp); + } + return ret; } /** - * Get one established connection - * - * n - the position of the established connection, counting from 0 - * - * return client, or NULL if the position is off the end of the list + * Delete all established connection from the list */ -chain_node_client_t* chain_node_client_list_get_item(int n) +void chain_node_client_list_del_all(void) { + int ret = -1; + list_linked_item_t *iter_current, *item_tmp; pthread_mutex_lock(&connect_list_mutex); - chain_node_client_t *client = g_list_nth_data(connect_list, (guint) n); + HASH_ITER(hh, conn_list , iter_current, item_tmp) { + // close connection + chain_node_client_close(iter_current->client); + // del struct for hash + HASH_DEL(conn_list, iter_current); + } pthread_mutex_unlock(&connect_list_mutex); - return client; } + /** - * Get the number of established connections + * Get present established connection + * + * return client, or NULL if the position is off the end of the list */ -int chain_node_client_list_count(void) +const chain_node_client_t* chain_node_client_find(dap_chain_node_addr_t *address) { + int ret = 0; + if(!address) + return NULL; + chain_node_client_t *client_ret = NULL; + list_linked_item_t *item_tmp; pthread_mutex_lock(&connect_list_mutex); - int len = g_list_length(connect_list); + HASH_FIND(hh, conn_list, address, sizeof(dap_chain_node_addr_t), item_tmp); // address already in the hash? + if(item_tmp != NULL) { + client_ret = item_tmp->client; + } pthread_mutex_unlock(&connect_list_mutex); - return len; + return client_ret; } diff --git a/dap_chain_node_remote.h b/dap_chain_node_remote.h index ef7f4c5ef5..f0ff4d92cb 100644 --- a/dap_chain_node_remote.h +++ b/dap_chain_node_remote.h @@ -23,28 +23,31 @@ #include <stdbool.h> +#include "dap_chain_node.h" #include "dap_chain_node_cli_connect.h" /** - * Add new established connection in the list + * Add new established connection to the list + * + * return 0 OK, -1 error, -2 already present */ -bool chain_node_client_list_add(chain_node_client_t *client); +int chain_node_client_list_add(dap_chain_node_addr_t *address, chain_node_client_t *client); /** * Delete established connection from the list + * + * return 0 OK, -1 error, -2 address not found */ -bool chain_node_client_list_del(chain_node_client_t *client); +int chain_node_client_list_del(dap_chain_node_addr_t *address); /** - * Get one established connection - * - * n - the position of the established connection, counting from 0 - * - * return client, or NULL if the position is off the end of the list + * Delete all established connection from the list */ -chain_node_client_t* chain_node_client_list_get_item(int n); +void chain_node_client_list_del_all(void); /** - * Get the number of established connections + * Get present established connection + * + * return client, or NULL if the position is off the end of the list */ -int chain_node_client_list_count(void); +const chain_node_client_t* chain_node_client_find(dap_chain_node_addr_t *address); -- GitLab