diff --git a/dap_chain_node.c b/dap_chain_node.c index 76979a5a73167eef0711f926d3a71c689de95389..8679b44e87a679efcb0292f069520edb4dcb9b97 100644 --- a/dap_chain_node.c +++ b/dap_chain_node.c @@ -22,6 +22,7 @@ #include <sys/socket.h> #include <netinet/in.h> #include <string.h> +#include <assert.h> #include "dap_hash.h" #include "rand/dap_rand.h" @@ -116,6 +117,16 @@ int hex2bin(char *out, const unsigned char *in, int len) return len; } +/** + * Calculate size of struct dap_chain_node_info_t + */ +size_t dap_chain_node_info_get_size(dap_chain_node_info_t *node_info) +{ + if(!node_info) + return 0; + return (sizeof(dap_chain_node_info_t) + node_info->hdr.uplinks_number * sizeof(dap_chain_addr_t)); +} + /** * Serialize dap_chain_node_info_t * size[out] - length of output string @@ -152,6 +163,7 @@ dap_chain_node_info_t* dap_chain_node_deserialize(uint8_t *node_info_str, size_t DAP_DELETE(node_info); return NULL; } + assert((size / 2) == dap_chain_node_info_get_size(node_info)); return node_info; } diff --git a/dap_chain_node.h b/dap_chain_node.h index 69936ff9a95c6fa88171bfd9d37a94a134715492..9258b28a2eac0372b48693b803a49ce05a7d86f0 100644 --- a/dap_chain_node.h +++ b/dap_chain_node.h @@ -90,6 +90,10 @@ typedef struct dap_chain_node_publ{ dap_chain_node_info_t node_info; } DAP_ALIGN_PACKED dap_chain_node_publ_t; +/** + * Calculate size of struct dap_chain_node_info_t + */ +size_t dap_chain_node_info_get_size(dap_chain_node_info_t *node_info); /** * Serialize dap_chain_node_info_t diff --git a/dap_chain_node_cli_cmd.c b/dap_chain_node_cli_cmd.c index 0f65d87086c5e6f28a6aa0c4226ac9a798f5bef2..ff5b22d99dc99cffe213dd2f8b19853eb13a1cfe 100644 --- a/dap_chain_node_cli_cmd.c +++ b/dap_chain_node_cli_cmd.c @@ -101,7 +101,7 @@ static bool add_alias(const char *alias, dap_chain_node_addr_t *addr) char a_value[2 * sizeof(dap_chain_node_addr_t) + 1]; if(bin2hex(a_value, (const unsigned char *) addr, sizeof(dap_chain_node_addr_t)) == -1) return false; - a_value[2 * sizeof(dap_chain_node_addr_t) + 1] = '\0'; + a_value[2 * sizeof(dap_chain_node_addr_t)] = '\0'; bool res = dap_chain_global_db_gr_set(a_key, a_value, GROUP_ALIAS); return res; } @@ -109,7 +109,7 @@ static bool add_alias(const char *alias, dap_chain_node_addr_t *addr) /** * Delete alias from base */ -static bool del_alias(const char *alias, dap_chain_node_addr_t *addr) +static bool del_alias(const char *alias) { const char *a_key = alias; bool res = dap_chain_global_db_gr_del(a_key, GROUP_ALIAS); @@ -128,9 +128,8 @@ static dap_chain_node_addr_t* get_name_by_alias(const char *alias) return NULL; const char *a_key = alias; char *addr_str = dap_chain_global_db_gr_get(a_key, GROUP_ALIAS); - if(addr_str && strlen(addr_str) == sizeof(dap_chain_node_addr_t) * 2) - { - dap_chain_node_addr_t *addr = DAP_NEW_Z(dap_chain_node_addr_t); + if(addr_str && strlen(addr_str) == sizeof(dap_chain_node_addr_t) * 2) { + addr = DAP_NEW_Z(dap_chain_node_addr_t); if(hex2bin((char*) addr, (const unsigned char *) addr_str, sizeof(dap_chain_node_addr_t) * 2) == -1) { DAP_DELETE(addr); addr = NULL; @@ -140,6 +139,285 @@ static dap_chain_node_addr_t* get_name_by_alias(const char *alias) return addr; } +/** + * Find in base alias by addr + * + * return addr, NULL if not found + */ +static char* get_alias_by_name(dap_chain_node_addr_t *addr) +{ + if(!addr) + return NULL; + char *alias = NULL; + const char *a_key = alias; + size_t data_size = 0; + // read all aliases + dap_global_db_obj_t **aliases_list = dap_chain_global_db_gr_load(&data_size, GROUP_ALIAS); + if(!aliases_list || !data_size) + return NULL; + for(int i = 0; i < data_size; i++) { + dap_chain_node_addr_t addr_i; + dap_global_db_obj_t *obj = aliases_list[i]; + if(!obj) + break; + char *addr_str = obj->value; + if(addr_str && strlen(addr_str) == sizeof(dap_chain_node_addr_t) * 2) { + addr = DAP_NEW_Z(dap_chain_node_addr_t); + if(hex2bin((char*) &addr_i, (const unsigned char *) addr_str, sizeof(dap_chain_node_addr_t) * 2) == -1) { + continue; + } + } + if(addr->uint64 == addr_i.uint64) { + alias = strdup(obj->key); + break; + } + } + dap_chain_global_db_objs_delete(aliases_list); + return alias; +} + +static dap_chain_node_addr_t* com_global_db_get_addr(dap_chain_node_info_t *node_info, + const char *addr_str, const char *alias_str) +{ + dap_chain_node_addr_t *address = NULL; + if(alias_str && !addr_str) { + address = get_name_by_alias(alias_str); + } + if(addr_str) { + address = DAP_NEW(dap_chain_node_addr_t); + address->uint64 = node_info->hdr.address.uint64; + } + return address; +} + +static char* com_global_db_get_key_for_addr(dap_chain_node_addr_t *address) +{ + char *a_key = dap_chain_global_db_hash((const uint8_t*) address, sizeof(dap_chain_node_addr_t)); + return a_key; +} + +/** + * Handler of command 'global_db node add' + * + * str_reply[out] for reply + * return 0 Ok, -1 error + */ +static int com_global_db_add(dap_chain_node_info_t *node_info, const char *addr_str, const char *alias_str, + const char *shard_str, const char *ipv4_str, const char *ipv6_str, char **str_reply) +{ + + if(!addr_str) { + if(str_reply) + *str_reply = g_strdup("not found -addr parameter"); + return -1; + } + if(!shard_str) { + if(str_reply) + *str_reply = g_strdup("not found -shard parameter"); + return -1; + } + if(!ipv4_str && !ipv6_str) { + if(str_reply) + *str_reply = g_strdup("not found -ipv4 or -ipv6 parameter"); + return -1; + } + else { + if(ipv4_str) + inet_pton(AF_INET, ipv4_str, &(node_info->hdr.ext_addr_v4)); + if(ipv6_str) + inet_pton(AF_INET6, ipv6_str, &(node_info->hdr.ext_addr_v6)); + } + if(alias_str) { + if(addr_str) { + // add alias + if(!add_alias(alias_str, &node_info->hdr.address)) + log_it(L_WARNING, "can't save alias %s", alias_str); + } + else { + if(str_reply) + *str_reply = g_strdup("alias can't be mapped because -addr is not found"); + return -1; + } + } + // check match addr to shard or no + /*dap_chain_node_addr_t *addr = dap_chain_node_gen_addr(&node_info->hdr.shard_id); + if(!dap_chain_node_check_addr(&node_info->hdr.address, &node_info->hdr.shard_id)) { + if(str_reply) + *str_reply = g_strdup("shard does not match addr"); + return -1; + }*/ + + // write to base + char *a_key = dap_chain_global_db_hash((const uint8_t*) &(node_info->hdr.address), + sizeof(dap_chain_node_addr_t)); + char *a_value = dap_chain_node_serialize(node_info, NULL); + bool res = dap_chain_global_db_gr_set(a_key, a_value, GROUP_NODE); + if(res) { + if(str_reply) + *str_reply = g_strdup_printf("node is added"); + } + else if(str_reply) { + *str_reply = g_strdup_printf("node is not added"); + } + DAP_DELETE(a_key); + DAP_DELETE(a_value); + if(res) + return 0; + return -1; +} + +/** + * Handler of command 'global_db node add' + * + * str_reply[out] for reply + * return 0 Ok, -1 error + */ +static int com_global_db_del(dap_chain_node_info_t *node_info, const char *addr_str, + const char *alias_str, char **str_reply) +{ + char *a_key = NULL; + // find addr by alias + dap_chain_node_addr_t *address = NULL; + if(alias_str && !addr_str) { + address = get_name_by_alias(alias_str); + if(!address) { + *str_reply = g_strdup("alias not found"); + return -1; + } + a_key = dap_chain_global_db_hash((const uint8_t*) address, sizeof(dap_chain_node_addr_t)); + } + if(addr_str) + { + a_key = dap_chain_global_db_hash((const uint8_t*) &(node_info->hdr.address), sizeof(dap_chain_node_addr_t)); + if(a_key) { + address = DAP_NEW(dap_chain_node_addr_t); + address->uint64 = node_info->hdr.address.uint64; + } + } + if(a_key) + { + // delete node + bool res = dap_chain_global_db_gr_del(a_key, GROUP_NODE); + if(res) { + // delete all aliases for node address + { + char *alias = NULL; + do { + alias = get_alias_by_name(address); + del_alias(alias); + } + while(alias); + } + if(str_reply) + *str_reply = g_strdup_printf("node is deleted"); + } + else if(str_reply) { + *str_reply = g_strdup_printf("node is not deleted"); + } + DAP_DELETE(a_key); + if(res) + return 0; + } + if(str_reply) + *str_reply = g_strdup("addr to delete can't be defined"); + DAP_DELETE(address); + return -1; +} + +/** + * Handler of command 'global_db node link' + * + * str_reply[out] for reply + * return 0 Ok, -1 error + */ +static int com_global_db_link(dap_chain_node_info_t *node_info, const char *addr_str, + const char *alias_str, char **str_reply) +{ + char *a_key = NULL; + // find addr by alias + dap_chain_node_addr_t *address = NULL; + if(alias_str && !addr_str) { + address = get_name_by_alias(alias_str); + if(!address) { + *str_reply = g_strdup("alias not found"); + return -1; + } + a_key = dap_chain_global_db_hash((const uint8_t*) address, sizeof(dap_chain_node_addr_t)); + } + if(addr_str) + { + a_key = dap_chain_global_db_hash((const uint8_t*) &(node_info->hdr.address), sizeof(dap_chain_node_addr_t)); + if(a_key) { + address = DAP_NEW(dap_chain_node_addr_t); + address->uint64 = node_info->hdr.address.uint64; + } + } + if(a_key) + { + // add link + bool res = 0; //dap_chain_global_db_gr_read(a_key, GROUP_NODE); + if(res) { + + } + DAP_DELETE(a_key); + if(res) + return 0; + } + if(str_reply) + *str_reply = g_strdup("link addr can't be saved"); + DAP_DELETE(address); + return -1; +} + +/** + * Handler of command 'global_db node dump' + * + * str_reply[out] for reply + * return 0 Ok, -1 error + */ +static int com_global_db_dump(dap_chain_node_info_t *node_info, const char *addr_str, + const char *alias_str, char **str_reply) +{ + char *a_key = NULL; + if(!addr_str && !alias_str) { + *str_reply = g_strdup("addr not found"); + return -1; + } + // find addr by alias or addr_str + dap_chain_node_addr_t *address = com_global_db_get_addr(node_info, addr_str, alias_str); + if(!address) { + *str_reply = g_strdup("alias not found"); + return -1; + } + a_key = com_global_db_get_key_for_addr(address); + if(a_key) + { + // read node + char *str = dap_chain_global_db_gr_get(a_key, GROUP_NODE); + if(str) { + dap_chain_node_info_t *node_info = dap_chain_node_deserialize(str, strlen(str)); + if(str_reply) + { + // TODO dump insert here! + *str_reply = g_strdup_printf("node is read"); + } + } + else if(str_reply) { + *str_reply = g_strdup_printf("node is not found in base"); + } + DAP_DELETE(str); + DAP_DELETE(a_key); + DAP_DELETE(address); + if(str) + return 0; + return -1; + } + if(str_reply) + *str_reply = g_strdup("addr to dump can't be defined"); + DAP_DELETE(address); + return -1; +} + /** * global_db command * @@ -152,8 +430,7 @@ int com_global_db(int argc, const char ** argv, char **str_reply) }; printf("com_global_db\n"); int arg_index = 1; - const char *cmd_str = NULL; -// find 'node' parameter + // find 'node' parameter arg_index = find_option_val(argv, arg_index, argc, "node", NULL); if(!arg_index || argc < 4) { if(str_reply) @@ -161,7 +438,7 @@ int com_global_db(int argc, const char ** argv, char **str_reply) return -1; } arg_index++; -// find command (add, delete, etc) + // find command (add, delete, etc) int cmd_num = CMD_NONE; if(find_option_val(argv, arg_index, argc, "add", NULL)) { cmd_num = CMD_ADD; @@ -181,102 +458,57 @@ int com_global_db(int argc, const char ** argv, char **str_reply) return -1; } const char *addr_str = NULL, *alias_str = NULL, *shard_str = NULL, *ipv4_str = NULL, *ipv6_str = NULL; -// find addr, alias + // find addr, alias find_option_val(argv, arg_index, argc, "-addr", &addr_str); find_option_val(argv, arg_index, argc, "-alias", &alias_str); find_option_val(argv, arg_index, argc, "-shard", &shard_str); find_option_val(argv, arg_index, argc, "-ipv4", &ipv4_str); find_option_val(argv, arg_index, argc, "-ipv6", &ipv6_str); -// struct to write to the global db + // struct to write to the global db dap_chain_node_info_t node_info; memset(&node_info, 0, sizeof(dap_chain_node_info_t)); + if(addr_str) { + digit_from_string(addr_str, node_info.hdr.address.raw, sizeof(node_info.hdr.address.raw)); + } + if(shard_str) { + digit_from_string(shard_str, node_info.hdr.shard_id.raw, sizeof(node_info.hdr.shard_id.raw)); //DAP_CHAIN_SHARD_ID_SIZE); + } switch (cmd_num) { -// add new node to global_db + // add new node to global_db case CMD_ADD: - if(!arg_index || argc < 8) { if(str_reply) *str_reply = g_strdup("parameters are not valid"); return -1; } - if(!addr_str) { - if(str_reply) - *str_reply = g_strdup("not found -addr parameter"); - return -1; - } - else - digit_from_string(addr_str, node_info.hdr.address.raw, sizeof(node_info.hdr.address.raw)); - if(!shard_str) { - if(str_reply) - *str_reply = g_strdup("not found -shard parameter"); - return -1; - } - else - digit_from_string(shard_str, node_info.hdr.shard_id.raw, sizeof(node_info.hdr.shard_id.raw)); //DAP_CHAIN_SHARD_ID_SIZE); - if(!ipv4_str && !ipv6_str) { - if(str_reply) - *str_reply = g_strdup("not found -ipv4 or -ipv6 parameter"); - return -1; - } - else { - if(ipv4_str) - inet_pton(AF_INET, ipv4_str, &(node_info.hdr.ext_addr_v4)); - if(ipv6_str) - inet_pton(AF_INET6, ipv6_str, &(node_info.hdr.ext_addr_v6)); - } - if(alias_str) { - if(addr_str) { - // add alias - if(!add_alias(alias_str, &node_info.hdr.address)) - log_it(L_WARNING, "can't save alias %s", alias_str); - } - else { - if(str_reply) - *str_reply = g_strdup("alias can't be mapped because -addr is not found"); - return -1; - } - } - - // write to base - char *a_key = dap_chain_global_db_hash((const uint8_t*) &(node_info.hdr.address), - sizeof(dap_chain_node_addr_t)); - char *a_value = dap_chain_node_serialize(&node_info, NULL); - bool res = dap_chain_global_db_gr_set(a_key, a_value, GROUP_NODE); - if(res) { - if(str_reply) - *str_reply = g_strdup_printf("node is added"); - } - else if(str_reply) { - *str_reply = g_strdup_printf("node is not added"); - } - DAP_DELETE(a_value); - if(res) - return 0; - else - return -1; + // handler of command 'global_db node add' + return com_global_db_add(&node_info, addr_str, alias_str, shard_str, ipv4_str, ipv6_str, str_reply); break; case CMD_DEL: + // handler of command 'global_db node del' + return com_global_db_del(&node_info, addr_str, alias_str, str_reply); + break; + case CMD_LINK: + // handler of command 'global_db node link' + return com_global_db_link(&node_info, addr_str, alias_str, str_reply); + break; + case CMD_DUMP: + // handler of command 'global_db node dump' + return com_global_db_dump(&node_info, addr_str, alias_str, str_reply); break; default: if(str_reply) *str_reply = g_strdup_printf("command %s not recognized", argv[1]); return -1; } -// dap_chain_node_addr_t *addr = dap_chain_node_gen_addr(&node_info.hdr.shard_id); -// if(!dap_chain_node_check_addr(&node_info.hdr.address, &node_info.hdr.shard_id)) { -// if(str_reply) -// *str_reply = g_strdup("shard does not match addr"); -// return -1; -// } //inet_ntop(AF_INET, &(dap_addr.uint64), str, INET_ADDRSTRLEN); //uint64 - uint64_t - timestamp = time(NULL); +// timestamp = time(NULL); return -1; } @@ -286,10 +518,67 @@ int com_global_db(int argc, const char ** argv, char **str_reply) */ int com_node(int argc, const char ** argv, char **str_reply) { - for(int i = 0; i < argc; i++) - printf("com_node i=%d str=%s\n", i, argv[i]); - if(str_reply) - *str_reply = g_strdup("text"); + enum { + CMD_NONE, CMD_ALIAS, CMD_HANDSHAKE + }; + int arg_index = 1; + int cmd_num = CMD_NONE; + const char *cmd_str = NULL; + // find add parameter ('alias' or 'handshake') + if(find_option_val(argv, arg_index, min(argc, arg_index + 1), "handshake", NULL)) { + cmd_num = CMD_HANDSHAKE; + } + else if(find_option_val(argv, arg_index, min(argc, arg_index + 1), "alias", NULL)) { + cmd_num = CMD_ALIAS; + } + arg_index++; + if(cmd_num == CMD_NONE) { + if(str_reply) + *str_reply = g_strdup_printf("command %s not recognized", argv[1]); + return -1; + } + dap_chain_node_addr_t address; + const char *addr_str = NULL, *alias_str = NULL; + // find addr, alias + find_option_val(argv, arg_index, argc, "-addr", &addr_str); + find_option_val(argv, arg_index, argc, "-alias", &alias_str); + + digit_from_string(addr_str, address.raw, sizeof(address.raw)); + + switch (cmd_num) + { + // add alias + case CMD_ALIAS: + if(alias_str) { + if(addr_str) { + // add alias + if(!add_alias(alias_str, &address)) + log_it(L_WARNING, "can't save alias %s", alias_str); + else { + if(str_reply) + *str_reply = g_strdup("alias mapped successfully"); + } + } + else { + if(str_reply) + *str_reply = g_strdup("alias can't be mapped because -addr is not found"); + return -1; + } + } + else { + if(str_reply) + *str_reply = g_strdup("alias can't be mapped because -alias is not found"); + return -1; + } + + break; + + // make handshake + case CMD_HANDSHAKE: + if(str_reply) + *str_reply = g_strdup("handshake in progress..."); + break; + } return 0; }