diff --git a/core/include/dap_common.h b/core/include/dap_common.h index ba771572db8448889b35da6b52efe4a6b1741542..d150a149b88376779f36a61c49c74b95150393b8 100755 --- a/core/include/dap_common.h +++ b/core/include/dap_common.h @@ -1142,14 +1142,8 @@ int exec_silent(const char *a_cmd); } #endif -DAP_STATIC_INLINE int dap_stream_node_addr_from_str(dap_stream_node_addr_t *a_addr, const char *a_addr_str) -{ - if (!a_addr || !a_addr_str) - return -2; - return sscanf(a_addr_str, NODE_ADDR_FP_STR, NODE_ADDR_FPS_ARGS(a_addr)) == 4 - || sscanf(a_addr_str, "0x%016" DAP_UINT64_FORMAT_x, (uint64_t*)a_addr) == 1 - ? 0 : -1; -} +int dap_stream_node_addr_from_str(dap_stream_node_addr_t *a_addr, const char *a_addr_str); + DAP_STATIC_INLINE bool dap_stream_node_addr_is_blank(dap_stream_node_addr_t *a_addr) { return !a_addr->uint64; } diff --git a/core/src/dap_common.c b/core/src/dap_common.c index b1cd1d83c354b9fd7c79fa0c9fd8c5822d183aee..aa96fa41a75d15a4c44926b7d2a0e11a760b4eec 100755 --- a/core/src/dap_common.c +++ b/core/src/dap_common.c @@ -1555,6 +1555,22 @@ dap_node_addr_str_t dap_stream_node_addr_to_str_static_(dap_stream_node_addr_t a snprintf((char*)&l_ret, sizeof(l_ret), NODE_ADDR_FP_STR, NODE_ADDR_FP_ARGS_S(a_address)); return l_ret; } + +int dap_stream_node_addr_from_str(dap_stream_node_addr_t *a_addr, const char *a_addr_str) +{ + if (!a_addr || !a_addr_str) + return -2; + bool l_res = true; + size_t l_len = 0; + for (; l_res && *(a_addr_str + l_len) && l_len < 23; l_len++) { + l_res &= *(a_addr_str + l_len) == ':' || isxdigit(*(a_addr_str + l_len)); + } + l_res &= l_len == 18 || l_len == 22; + return l_res ? (sscanf(a_addr_str, NODE_ADDR_FP_STR, NODE_ADDR_FPS_ARGS(a_addr)) == 4 + || sscanf(a_addr_str, "0x%016" DAP_UINT64_FORMAT_x, (uint64_t*)a_addr) == 1 + ? 0 : -1) : -4; +} + #ifdef __cplusplus } #endif diff --git a/net/server/cli_server/dap_cli_server.c b/net/server/cli_server/dap_cli_server.c index fa0cc797df85bb276c6c289ac84683733de9847c..6d61a47d8bf88233dc5ecaafd78b2b88c74ba925 100644 --- a/net/server/cli_server/dap_cli_server.c +++ b/net/server/cli_server/dap_cli_server.c @@ -54,11 +54,14 @@ static dap_server_t *s_cli_server = NULL; static bool s_debug_cli = false; +static atomic_int_fast32_t s_cmd_thread_count = 0; +static bool s_allowed_cmd_control = false; +static const char **s_allowed_cmd_array = NULL; static dap_cli_cmd_t *cli_commands = NULL; static dap_cli_cmd_aliases_t *s_command_alias = NULL; -static inline dap_cli_cmd_t *s_cmd_add_ex(const char *a_name, dap_cli_server_cmd_callback_ex_t a_func, void *a_arg_func, const char *a_doc, const char *a_doc_ex); +static dap_cli_server_cmd_stat_callback_t s_stat_callback = NULL; typedef struct cli_cmd_arg { dap_worker_t *worker; @@ -69,7 +72,9 @@ typedef struct cli_cmd_arg { static void* s_cli_cmd_exec(void *a_arg); -static bool s_allowed_cmd_check(char *a_buf) { +static bool s_allowed_cmd_check(const char *a_buf) { + if (!s_allowed_cmd_array) + return false; enum json_tokener_error jterr; const char *l_method; json_object *jobj = json_tokener_parse_verbose(a_buf, &jterr), @@ -84,7 +89,7 @@ static bool s_allowed_cmd_check(char *a_buf) { return false; } - bool l_allowed = !!dap_str_find( dap_config_get_array_str(g_config, "cli-server", "allowed_cmd", NULL), l_method ); + bool l_allowed = !!dap_str_find( s_allowed_cmd_array, l_method ); return debug_if(!l_allowed, L_ERROR, "Command %s is restricted", l_method), json_object_put(jobj), l_allowed; } @@ -119,11 +124,14 @@ DAP_STATIC_INLINE void s_cli_cmd_schedule(dap_events_socket_t *a_es, void *a_arg if ( a_es->buf_in_size < l_arg->buf_size + l_hdr_len ) return; - if ( ((struct sockaddr_in*)&a_es->addr_storage)->sin_addr.s_addr != htonl(INADDR_LOOPBACK) + if (!( #ifdef DAP_OS_UNIX - && a_es->addr_storage.ss_family != AF_UNIX + a_es->addr_storage.ss_family == AF_UNIX || #endif - && !s_allowed_cmd_check(l_arg->buf) ) { + ( ((struct sockaddr_in*)&a_es->addr_storage)->sin_addr.s_addr == htonl(INADDR_LOOPBACK) && !s_allowed_cmd_control) || + + (((struct sockaddr_in*)&a_es->addr_storage)->sin_addr.s_addr && s_allowed_cmd_control && s_allowed_cmd_check(l_arg->buf))) + ) { dap_events_socket_write_f_unsafe(a_es, "HTTP/1.1 403 Forbidden\r\n"); a_es->flags |= DAP_SOCK_SIGNAL_CLOSE; return; @@ -184,18 +192,6 @@ void dap_cli_server_deinit() dap_server_delete(s_cli_server); } -/** - * @brief dap_cli_server_cmd_add - * @param a_name - * @param a_func - * @param a_doc - * @param a_doc_ex - */ -dap_cli_cmd_t *dap_cli_server_cmd_add(const char * a_name, dap_cli_server_cmd_callback_t a_func, const char *a_doc, const char *a_doc_ex) -{ - return s_cmd_add_ex(a_name, (dap_cli_server_cmd_callback_ex_t)(void *)a_func, NULL, a_doc, a_doc_ex); -} - /** * @brief s_cmd_add_ex * @param a_name @@ -204,7 +200,7 @@ dap_cli_cmd_t *dap_cli_server_cmd_add(const char * a_name, dap_cli_server_cmd_ca * @param a_doc * @param a_doc_ex */ -static inline dap_cli_cmd_t *s_cmd_add_ex(const char * a_name, dap_cli_server_cmd_callback_ex_t a_func, void *a_arg_func, const char *a_doc, const char *a_doc_ex) +DAP_STATIC_INLINE dap_cli_cmd_t *s_cmd_add_ex(const char * a_name, dap_cli_server_cmd_callback_ex_t a_func, void *a_arg_func, const char *a_doc, const char *a_doc_ex, int16_t a_id) { dap_cli_cmd_t *l_cmd_item = DAP_NEW_Z(dap_cli_cmd_t); if (!l_cmd_item) { @@ -220,11 +216,24 @@ static inline dap_cli_cmd_t *s_cmd_add_ex(const char * a_name, dap_cli_server_cm } else { l_cmd_item->func = (dap_cli_server_cmd_callback_t )(void *)a_func; } + l_cmd_item->id = a_id; HASH_ADD_STR(cli_commands,name,l_cmd_item); log_it(L_DEBUG,"Added command %s",l_cmd_item->name); return l_cmd_item; } +/** + * @brief dap_cli_server_cmd_add + * @param a_name + * @param a_func + * @param a_doc + * @param a_doc_ex + */ +dap_cli_cmd_t *dap_cli_server_cmd_add(const char * a_name, dap_cli_server_cmd_callback_t a_func, const char *a_doc, int16_t a_id, const char *a_doc_ex) +{ + return s_cmd_add_ex(a_name, (dap_cli_server_cmd_callback_ex_t)(void *)a_func, NULL, a_doc, a_doc_ex, a_id); +} + int json_commands(const char * a_name) { static const char* long_cmd[] = { "tx_history", @@ -240,7 +249,6 @@ int json_commands(const char * a_name) { "chain_ca_copy", "dag", "block", - "dag", "token", "esbocs", "global_db", @@ -429,6 +437,7 @@ dap_cli_cmd_t *dap_cli_server_cmd_find_by_alias(const char *a_alias, char **a_ap } static void *s_cli_cmd_exec(void *a_arg) { + atomic_fetch_add(&s_cmd_thread_count, 1); cli_cmd_arg_t *l_arg = (cli_cmd_arg_t*)a_arg; char *l_ret = dap_cli_cmd_exec(l_arg->buf), *l_full_ret = dap_strdup_printf("HTTP/1.1 200 OK\r\n" @@ -438,6 +447,7 @@ static void *s_cli_cmd_exec(void *a_arg) { dap_events_socket_write_mt(l_arg->worker, l_arg->es_uid, l_full_ret, dap_strlen(l_full_ret)); // TODO: pagination DAP_DEL_MULTY(l_arg->buf, /* l_full_ret, */ l_arg); + atomic_fetch_sub(&s_cmd_thread_count, 1); return NULL; } @@ -505,6 +515,10 @@ char *dap_cli_cmd_exec(char *a_req_str) { } // Call the command function if(l_cmd && l_argv && l_cmd->func) { + dap_time_t l_call_time = 0; + if (s_stat_callback) { + l_call_time = dap_nanotime_now(); + } if (json_commands(cmd_name)) { res = l_cmd->func(l_argc, l_argv, (void *)&l_json_arr_reply); } else if (l_cmd->arg_func) { @@ -512,6 +526,9 @@ char *dap_cli_cmd_exec(char *a_req_str) { } else { res = l_cmd->func(l_argc, l_argv, (void *)&str_reply); } + if (s_stat_callback) { + s_stat_callback(l_cmd->id, (dap_nanotime_now() - l_call_time) / 1000000); + } } else if (l_cmd) { log_it(L_WARNING,"NULL arguments for input for command \"%s\"", str_cmd); dap_json_rpc_error_add(l_json_arr_reply, -1, "NULL arguments for input for command \"%s\"", str_cmd); @@ -550,3 +567,27 @@ char *dap_cli_cmd_exec(char *a_req_str) { dap_json_rpc_request_free(request); return response_string; } + +DAP_INLINE int32_t dap_cli_get_cmd_thread_count() +{ + return atomic_load(&s_cmd_thread_count); +} + +/** + * @brief dap_cli_server_cmd_add + * @param a_callback callback to statistic collect + */ +void dap_cli_server_statistic_callback_add(dap_cli_server_cmd_stat_callback_t a_callback) +{ + if (a_callback && s_stat_callback) + log_it(L_ERROR, "Dap cli server statistic callback already added"); + else + s_stat_callback = a_callback; +} + +DAP_INLINE void dap_cli_server_set_allowed_cmd_check(const char **a_cmd_array) +{ + dap_return_if_pass_err(s_allowed_cmd_array, "Allowed cmd array already exist"); + s_allowed_cmd_array = a_cmd_array; + s_allowed_cmd_control = true; +} \ No newline at end of file diff --git a/net/server/cli_server/include/dap_cli_server.h b/net/server/cli_server/include/dap_cli_server.h index aecdd2d8196fbe0f100244390faf56205643fb5f..e9e689ead9230025a594041db47f7aec413742ff 100644 --- a/net/server/cli_server/include/dap_cli_server.h +++ b/net/server/cli_server/include/dap_cli_server.h @@ -32,6 +32,7 @@ typedef int (*dap_cli_server_cmd_callback_ex_t)(int argc, char ** argv, void *arg_func, void **a_str_reply); typedef int (*dap_cli_server_cmd_callback_t)(int argc, char ** argv, void **a_str_reply); +typedef void (*dap_cli_server_cmd_stat_callback_t)(int16_t a_cmd_num, int64_t a_call_time); // use to statistic collect typedef void (*dap_cli_server_override_log_cmd_callback_t)(const char*); @@ -50,6 +51,7 @@ typedef struct dap_cli_cmd{ char *doc; /* Documentation for this function. */ char *doc_ex; /* Full documentation for this function. */ dap_cli_server_cmd_override_t overrides; /* Used to change default behaviour */ + int16_t id; UT_hash_handle hh; } dap_cli_cmd_t; @@ -64,7 +66,7 @@ typedef struct dap_cli_cmd_aliases{ int dap_cli_server_init(bool a_debug_more, const char *a_cfg_section); void dap_cli_server_deinit(); -dap_cli_cmd_t *dap_cli_server_cmd_add(const char * a_name, dap_cli_server_cmd_callback_t a_func, const char *a_doc, const char *a_doc_ex); +dap_cli_cmd_t *dap_cli_server_cmd_add(const char * a_name, dap_cli_server_cmd_callback_t a_func, const char *a_doc, int16_t a_id, const char *a_doc_ex); DAP_PRINTF_ATTR(2, 3) void dap_cli_server_cmd_set_reply_text(void **a_str_reply, const char *str, ...); int dap_cli_server_cmd_find_option_val( char** argv, int arg_start, int arg_end, const char *opt_name, const char **opt_value); int dap_cli_server_cmd_check_option( char** argv, int arg_start, int arg_end, const char *opt_name); @@ -75,7 +77,10 @@ dap_cli_cmd_t* dap_cli_server_cmd_find(const char *a_name); dap_cli_cmd_aliases_t *dap_cli_server_alias_add(dap_cli_cmd_t *a_cmd, const char *a_pre_cmd, const char *a_alias); dap_cli_cmd_t *dap_cli_server_cmd_find_by_alias(const char *a_cli, char **a_append, char **a_ncmd); +int32_t dap_cli_get_cmd_thread_count(); //for json int json_commands(const char * a_name); char *dap_cli_cmd_exec(char *a_req_str); +void dap_cli_server_statistic_callback_add(dap_cli_server_cmd_stat_callback_t a_callback); +void dap_cli_server_set_allowed_cmd_check(const char **a_cmd_array); \ No newline at end of file diff --git a/net/server/json_rpc/rpc_core/src/dap_json_rpc_response.c b/net/server/json_rpc/rpc_core/src/dap_json_rpc_response.c index d5ea2f6b3269e7003d9426c660a2a99ccb15b088..ab111fdacccace0188fa1f53112e01dbc3bde7a4 100644 --- a/net/server/json_rpc/rpc_core/src/dap_json_rpc_response.c +++ b/net/server/json_rpc/rpc_core/src/dap_json_rpc_response.c @@ -212,7 +212,7 @@ void json_print_value(json_object *obj, const char *key, int indent_level, bool printf(print_separator ? "%s, " : "%s", json_object_get_string(obj)); break; case json_type_int: - printf("%lld", json_object_get_int64(obj)); + printf("%ld", json_object_get_int64(obj)); break; case json_type_double: printf("%lf", json_object_get_double(obj)); diff --git a/net/stream/stream/dap_stream.c b/net/stream/stream/dap_stream.c index 23f7ab17615ca89a27bad94bd8708e7759f3060c..2098daf9f554e423d5d312e9b348a95bdbaccd63 100644 --- a/net/stream/stream/dap_stream.c +++ b/net/stream/stream/dap_stream.c @@ -77,6 +77,7 @@ static dap_cluster_t *s_global_links_cluster = NULL; static pthread_rwlock_t s_streams_lock = PTHREAD_RWLOCK_INITIALIZER; // Lock for all tables and list under static dap_stream_t *s_authorized_streams = NULL; // Authorized streams hashtable by addr static dap_stream_t *s_streams = NULL; // Double-linked list +static int32_t s_streams_count = 0; // Stream count static dap_enc_key_type_t s_stream_get_preferred_encryption_type = DAP_ENC_KEY_TYPE_IAES; static int s_add_stream_info(authorized_stream_t **a_hash_table, authorized_stream_t *a_item, dap_stream_t *a_stream); @@ -966,8 +967,10 @@ void s_stream_delete_from_list(dap_stream_t *a_stream) return log_it(L_CRITICAL, "! Attempt to aquire streams lock recursively !"); dap_stream_t *l_stream = NULL; - if (a_stream->prev) + if (a_stream->prev) { DL_DELETE(s_streams, a_stream); + --s_streams_count; + } if (a_stream->authorized) { // It's an authorized stream, try to replace it in hastable if (a_stream->primary) @@ -995,6 +998,7 @@ int dap_stream_add_to_list(dap_stream_t *a_stream) if ( lock == EDEADLK ) return log_it(L_CRITICAL, "! Attempt to aquire streams lock recursively !"), -666; DL_APPEND(s_streams, a_stream); + ++s_streams_count; if (a_stream->authorized) l_ret = s_stream_add_to_hashtable(a_stream); pthread_rwlock_unlock(&s_streams_lock); @@ -1158,6 +1162,12 @@ dap_stream_info_t *dap_stream_get_links_info(dap_cluster_t *a_cluster, size_t *a return l_ret; } + +DAP_INLINE int32_t dap_stream_get_links_count() +{ + return s_streams_count; +} + void dap_stream_delete_links_info(dap_stream_info_t *a_info, size_t a_count) { dap_return_if_fail(a_info && a_count); diff --git a/net/stream/stream/include/dap_stream.h b/net/stream/stream/include/dap_stream.h index 416e0e5f39bfdd8ba09516e038080501a1bb7cf9..cb84c0750a14b017427c7fc03669399439c0c0f3 100644 --- a/net/stream/stream/include/dap_stream.h +++ b/net/stream/stream/include/dap_stream.h @@ -160,3 +160,4 @@ dap_stream_node_addr_t dap_stream_node_addr_from_cert(dap_cert_t *a_cert); dap_stream_node_addr_t dap_stream_node_addr_from_pkey(dap_pkey_t *a_pkey); dap_stream_info_t *dap_stream_get_links_info(dap_cluster_t *a_cluster, size_t *a_count); void dap_stream_delete_links_info(dap_stream_info_t *a_info, size_t a_count); +int32_t dap_stream_get_links_count(); diff --git a/plugin/src/dap_plugin_command.c b/plugin/src/dap_plugin_command.c index c7d036612f54b225ee2f14a128082aa90a61a4d2..cf0fec07f3ee091b313a9dc5b1ded3741ec186d8 100644 --- a/plugin/src/dap_plugin_command.c +++ b/plugin/src/dap_plugin_command.c @@ -22,7 +22,7 @@ void dap_plugin_command_init(void) { if (!s_l_restart_plugins){ dap_cli_server_cmd_add("plugin", s_command_handler, - "Commands for working with plugins:\n", + "Commands for working with plugins:\n", -1, "plugin list\n" "\tShow plugins list\n" "plugin show <plugin name>\n"