diff --git a/dap_chain_net_srv.c b/dap_chain_net_srv.c index 117c511d285f5a64c3ec1a75c243ae08cab2d9b4..652031deb5c78961b7af64e1e045efd87f70e1c1 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" @@ -42,3 +45,143 @@ 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(void) +{ + m_uid = NULL; + m_uid_count = 0; + + return 0; +} + +/** + * @brief dap_chain_net_srv_deinit + */ +void dap_chain_net_srv_deinit(void) +{ + // TODO Stop all services + + dap_chain_net_srv_del_all(); +} + +/** + * @brief dap_chain_net_srv_add + * @param a_srv + */ +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); +} + +/** + * @brief dap_chain_net_srv_get + * @param a_uid + * @return + */ +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 + */ + 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(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 566250415be7ff32e06cf45f165e7679f616e595..9f326f319150dafc9c1e5f434ba86878db6fe65d 100755 --- a/dap_chain_net_srv.h +++ b/dap_chain_net_srv.h @@ -25,46 +25,16 @@ #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_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); void dap_chain_net_srv_deinit(void); diff --git a/dap_chain_net_srv_common.c b/dap_chain_net_srv_common.c index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..cd1709eef82484bf4919439e5851c57512d953e1 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 51403634cc1cf2032011cbe4efe3d4857841ca8f..ee6835544d2aff9491dac791246f37e8d1670cc5 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);