From 0783ba715d28b71d6c2c7fb8ea2df4ad0d5bb894 Mon Sep 17 00:00:00 2001 From: Aleksandr Lysikov <lysikov@inbox.ru> Date: Mon, 29 Apr 2019 22:46:43 +0500 Subject: [PATCH] added hash table for services --- CMakeLists.txt | 4 +- dap_chain_net_srv.c | 116 ++++++++++++++++++++++++++++++++++--- dap_chain_net_srv.h | 44 +++----------- dap_chain_net_srv_common.c | 62 ++++++++++++++++++++ dap_chain_net_srv_common.h | 44 ++++++++++++++ 5 files changed, 224 insertions(+), 46 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d3b84f..4ee838e 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,10 +11,12 @@ set(DAP_CHAIN_NET_SRV_HEADERS dap_chain_net_srv_common.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_crypto dap_chain_net ) +target_link_libraries(dap_chain_net_srv dap_core dap_crypto dap_chain dap_chain_crypto dap_chain_net) +#target_link_libraries(dap_chain_net_srv dap_core dap_crypto dap_chain dap_chain_crypto dap_chain_net dap_server_http_db_auth) target_include_directories(dap_chain_net_srv INTERFACE .) set(${PROJECT_NAME}_DEFINITIONS CACHE INTERNAL "${PROJECT_NAME}: Definitions" FORCE) diff --git a/dap_chain_net_srv.c b/dap_chain_net_srv.c index f1fec03..e5a6389 100755 --- a/dap_chain_net_srv.c +++ b/dap_chain_net_srv.c @@ -22,8 +22,11 @@ along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. */ -#include "utlist.h" +#include <pthread.h> +#include "uthash.h" +#include "utlist.h" +#include "dap_list.h" #include "dap_chain_net_srv.h" #define LOG_TAG "chain_net_srv" @@ -31,11 +34,22 @@ size_t m_uid_count; dap_chain_net_srv_uid_t * m_uid; +typedef struct service_list { + dap_chain_net_srv_uid_t uid; + dap_chain_net_srv_t * srv; + UT_hash_handle hh; +} service_list_t; + +// list of active services +static service_list_t *s_srv_list = NULL; +// for separate access to s_srv_list +static pthread_mutex_t s_srv_list_mutex = PTHREAD_MUTEX_INITIALIZER; + /** * @brief dap_chain_net_srv_init * @return */ -int dap_chain_net_srv_init() +int dap_chain_net_srv_init(void) { m_uid = NULL; m_uid_count = 0; @@ -46,9 +60,11 @@ int dap_chain_net_srv_init() /** * @brief dap_chain_net_srv_deinit */ -void dap_chain_net_srv_deinit() +void dap_chain_net_srv_deinit(void) { + // TODO Stop all services + dap_chain_net_srv_del_all(); } /** @@ -57,7 +73,49 @@ void dap_chain_net_srv_deinit() */ void dap_chain_net_srv_add(dap_chain_net_srv_t * a_srv) { + service_list_t *l_sdata = NULL; + pthread_mutex_lock(&s_srv_list_mutex); + HASH_FIND(hh, s_srv_list, &(a_srv->uid), sizeof(a_srv->uid), l_sdata); + if(l_sdata == NULL) { + l_sdata = DAP_NEW_Z(service_list_t); + memcpy(&l_sdata->uid, &a_srv->uid, sizeof(dap_chain_net_srv_uid_t)); + l_sdata->srv = DAP_NEW(dap_chain_net_srv_t); + memcpy(&l_sdata->srv, a_srv, sizeof(dap_chain_net_srv_t)); ; + HASH_ADD(hh, s_srv_list, uid, sizeof(a_srv->uid), l_sdata); + } + pthread_mutex_unlock(&s_srv_list_mutex); +} +/** + * @brief dap_chain_net_srv_del + * @param a_srv + */ +void dap_chain_net_srv_del(dap_chain_net_srv_t * a_srv) +{ + service_list_t *l_sdata; + pthread_mutex_lock(&s_srv_list_mutex); + HASH_FIND(hh, s_srv_list, a_srv, sizeof(dap_chain_net_srv_uid_t), l_sdata); + if(l_sdata) { + DAP_DELETE(l_sdata); + HASH_DEL(s_srv_list, l_sdata); + } + pthread_mutex_unlock(&s_srv_list_mutex); +} + +/** + * @brief dap_chain_net_srv_del_all + * @param a_srv + */ +void dap_chain_net_srv_del_all(void) +{ + service_list_t *l_sdata, *l_sdata_tmp; + pthread_mutex_lock(&s_srv_list_mutex); + HASH_ITER(hh, s_srv_list , l_sdata, l_sdata_tmp) + { + DAP_DELETE(l_sdata); + HASH_DEL(s_srv_list, l_sdata); + } + pthread_mutex_unlock(&s_srv_list_mutex); } /** @@ -65,25 +123,65 @@ void dap_chain_net_srv_add(dap_chain_net_srv_t * a_srv) * @param a_uid * @return */ -dap_chain_net_srv_t * dap_chain_net_srv_get(dap_chain_net_srv_uid_t a_uid) +dap_chain_net_srv_t * dap_chain_net_srv_get(dap_chain_net_srv_uid_t *a_uid) { - + service_list_t *l_sdata = NULL; + pthread_mutex_lock(&s_srv_list_mutex); + HASH_FIND(hh, s_srv_list, &a_uid, sizeof(dap_chain_net_srv_uid_t), l_sdata); + pthread_mutex_unlock(&s_srv_list_mutex); + return (l_sdata) ? l_sdata->srv : NULL; } /** * @brief dap_chain_net_srv_count * @return */ -const size_t dap_chain_net_srv_count() +const size_t dap_chain_net_srv_count(void) { - + size_t l_count = 0; + service_list_t *l_sdata, *l_sdata_tmp; + pthread_mutex_lock(&s_srv_list_mutex); + HASH_ITER(hh, s_srv_list , l_sdata, l_sdata_tmp) + { + l_count++; + } + pthread_mutex_unlock(&s_srv_list_mutex); + return l_count; } /** * @brief dap_chain_net_srv_list * @return */ -const dap_chain_net_srv_uid_t * dap_chain_net_srv_list() +const dap_chain_net_srv_uid_t * dap_chain_net_srv_list(void) { - + static dap_chain_net_srv_uid_t *l_srv_uids = NULL; + static size_t l_count_last = 0; + size_t l_count_cur = 0; + dap_list_t *l_list = NULL; + service_list_t *l_sdata, *l_sdata_tmp; + pthread_mutex_lock(&s_srv_list_mutex); + // count the number of services and save them in list + HASH_ITER(hh, s_srv_list , l_sdata, l_sdata_tmp) + { + l_list = dap_list_append(l_list, l_sdata); + l_count_cur++; + } + // fill the output array + if(l_count_cur > 0) { + if(l_count_cur != l_count_last) { + DAP_DELETE(l_srv_uids); + l_srv_uids = DAP_NEW_SIZE(dap_chain_net_srv_uid_t, sizeof(dap_chain_net_srv_uid_t) * l_count_cur); + } + for(size_t i = 0; i < l_count_cur; i++) { + service_list_t *l_sdata = l_list->data; + memcpy(l_srv_uids + i, &l_sdata->uid, sizeof(dap_chain_net_srv_uid_t)); + } + } + // save new number of services + l_count_last = l_count_cur; + pthread_mutex_unlock(&s_srv_list_mutex); + dap_list_free(l_list); + return l_srv_uids; } + diff --git a/dap_chain_net_srv.h b/dap_chain_net_srv.h index bd9c5ea..64ff680 100755 --- a/dap_chain_net_srv.h +++ b/dap_chain_net_srv.h @@ -26,53 +26,25 @@ #include "dap_chain_node_ctl.h" #include "dap_chain_net_srv_common.h" -//Classes of services -enum { - SERV_CLASS_ONCE = 1, // one-time service - SERV_CLASS_PERMANENT = 2 -}; - -//Types of services -enum { - SERV_ID_VPN = 1, -}; - typedef struct dap_chain_net_srv { dap_chain_node_ctl_t * node; dap_chain_net_srv_uid_t uid; // Unique ID for service. + dap_chain_net_srv_abstract_t srv_common; void * _internal; void * _inhertor; } dap_chain_net_srv_t; -typedef struct dap_chain_net_srv_abstract -{ - uint64_t proposal_id; // id trade proposal. Must be unique to the node. - - uint8_t class; //Class of service - uint8_t type_id; //Type of service - union { - struct { - int bandwith; - int abuse_resistant; - int limit_bytes; - } vpn; - struct { - int value; - } other_srv; - } proposal_params; - uint64_t price; // service price, for SERV_CLASS_ONCE ONCE for the whole service, for SERV_CLASS_PERMANENT for one unit. - uint8_t price_units; // Unit of service (seconds, megabytes, etc.) Only for SERV_CLASS_PERMANENT - char decription[128]; -} DAP_ALIGN_PACKED dap_chain_net_srv_abstract_t; -int dap_chain_net_srv_init(); -void dap_chain_net_srv_deinit(); +int dap_chain_net_srv_init(void); +void dap_chain_net_srv_deinit(void); void dap_chain_net_srv_add(dap_chain_net_srv_t * a_srv); -dap_chain_net_srv_t * dap_chain_net_srv_get(dap_chain_net_srv_uid_t a_uid); -const size_t dap_chain_net_srv_count(); -const dap_chain_net_srv_uid_t * dap_chain_net_srv_list(); +void dap_chain_net_srv_del(dap_chain_net_srv_t * a_srv); +void dap_chain_net_srv_del_all(void); +dap_chain_net_srv_t * dap_chain_net_srv_get(dap_chain_net_srv_uid_t *a_uid); +const size_t dap_chain_net_srv_count(void); +const dap_chain_net_srv_uid_t * dap_chain_net_srv_list(void); diff --git a/dap_chain_net_srv_common.c b/dap_chain_net_srv_common.c index e69de29..cd1709e 100755 --- a/dap_chain_net_srv_common.c +++ b/dap_chain_net_srv_common.c @@ -0,0 +1,62 @@ +#include <stdint.h> +#include "rand/dap_rand.h" +#include "dap_chain_net_srv_common.h" +#include "dap_chain_datum_tx_items.h" +#include "dap_chain_utxo.h" + +/** + * Generate unique id for service + */ +bool dap_chain_net_srv_gen_uid(dap_chain_net_srv_uid_t *a_srv) +{ + if(!a_srv) + return false; + randombytes(a_srv, sizeof(dap_chain_net_srv_uid_t)); + return true; +} + +/** + * + */ +uint64_t dap_chain_net_srv_client_auth(char *a_addr_base58, uint8_t *a_sign, size_t a_sign_size, + const dap_chain_net_srv_abstract_t **a_cond_out) +{ + dap_chain_addr_t *l_addr = (a_addr_base58) ? dap_chain_str_to_addr(a_addr_base58) : NULL; + dap_chain_tx_out_cond_t *l_tx_out_cond = NULL; + + // Search all value in transactions with l_addr in 'out_cond' item + uint64_t l_value = 0;//!!!dap_chain_node_datum_tx_cache_get_out_cond_value(l_addr, &l_tx_out_cond); + DAP_DELETE(l_addr); + // not found transaction with l_addr in 'out_cond' item + if(!l_value) + return 0; + + size_t l_pkey_size = 0; + size_t l_cond_size = 0; + uint8_t *l_cond = dap_chain_datum_tx_out_cond_item_get_pkey(l_tx_out_cond, &l_cond_size); + uint8_t *l_pkey = dap_chain_datum_tx_out_cond_item_get_cond(l_tx_out_cond, &l_pkey_size); + + // create l_chain_sign for check a_sign + dap_chain_sign_t *l_chain_sign = DAP_NEW_Z_SIZE(dap_chain_sign_t, + sizeof(dap_chain_sign_t) + a_sign_size + l_pkey_size); + l_chain_sign->header.type = l_addr->sig_type; + l_chain_sign->header.sign_size = l_pkey_size; + l_chain_sign->header.sign_pkey_size = l_pkey_size; + // write serialized public key to dap_chain_sign_t + memcpy(l_chain_sign->pkey_n_sign, l_pkey, l_pkey_size); + // write serialized signature to dap_chain_sign_t + memcpy(l_chain_sign->pkey_n_sign + l_pkey_size, a_sign, a_sign_size); + + // check signature + if(dap_chain_sign_verify(l_chain_sign, a_sign, a_sign_size) != 1) { + // invalid signature + return 0; + } + + if(l_cond_size != sizeof(dap_chain_net_srv_abstract_t)) { + return 0; + } + if(a_cond_out) + *a_cond_out = (const dap_chain_net_srv_abstract_t*) l_cond; + return l_value; +} diff --git a/dap_chain_net_srv_common.h b/dap_chain_net_srv_common.h index 5140363..ee68355 100755 --- a/dap_chain_net_srv_common.h +++ b/dap_chain_net_srv_common.h @@ -1,5 +1,6 @@ #pragma once #include <stdint.h> +#include <stdbool.h> #include "dap_common.h" #include "dap_math_ops.h" @@ -13,3 +14,46 @@ typedef union{ dap_uint128_t raw_ui128[1]; #endif } dap_chain_net_srv_uid_t; + + +//Classes of services +enum { + SERV_CLASS_ONCE = 1, // one-time service + SERV_CLASS_PERMANENT = 2 +}; + +//Types of services +enum { + SERV_ID_VPN = 1, +}; + +typedef struct dap_chain_net_srv_abstract +{ + uint64_t proposal_id; // id trade proposal. Must be unique to the node. + + uint8_t class; //Class of service + uint8_t type_id; //Type of service + union { + struct { + int bandwith; + int abuse_resistant; + int limit_bytes; + } vpn; + /*struct { + int value; + } another_srv;*/ + } proposal_params; + + //size_t pub_key_data_size; + //void * pub_key_data; + + uint64_t price; // service price, for SERV_CLASS_ONCE ONCE for the whole service, for SERV_CLASS_PERMANENT for one unit. + uint8_t price_units; // Unit of service (seconds, megabytes, etc.) Only for SERV_CLASS_PERMANENT + char decription[128]; +} DAP_ALIGN_PACKED dap_chain_net_srv_abstract_t; + +// generate new dap_chain_net_srv_uid_t +bool dap_chain_net_srv_gen_uid(dap_chain_net_srv_uid_t *a_srv); + +uint64_t dap_chain_net_srv_client_auth(char *a_addr_base58, uint8_t *a_sign, size_t a_sign_size, + const dap_chain_net_srv_abstract_t **a_cond_out); -- GitLab