From 187da8a59d96472d86bc0ad77b097dd75f2207b4 Mon Sep 17 00:00:00 2001 From: Constantin Papizh <p_const@bk.ru> Date: Wed, 18 Dec 2019 01:51:12 +0300 Subject: [PATCH] Reinterpreted vpn service concerned things --- dap_chain_net_srv_vpn.c | 129 +++++++++++++++--------------------- dap_chain_net_srv_vpn_cdb.c | 127 ++++++++++++++++++----------------- 2 files changed, 117 insertions(+), 139 deletions(-) diff --git a/dap_chain_net_srv_vpn.c b/dap_chain_net_srv_vpn.c index 993ceee..66e9cdc 100755 --- a/dap_chain_net_srv_vpn.c +++ b/dap_chain_net_srv_vpn.c @@ -147,7 +147,6 @@ static void s_ch_packet_out(dap_stream_ch_t* ch, void* arg); static char *s_srv_vpn_addr = NULL, *s_srv_vpn_mask = NULL; - static void s_update_limits(dap_stream_ch_t * a_ch , dap_chain_net_srv_stream_session_t * a_srv_session, dap_chain_net_srv_usage_t * a_usage, size_t a_bytes); @@ -184,101 +183,81 @@ int dap_chain_net_srv_vpn_init(dap_config_t * g_config) l_srv_vpn->parent = l_srv; uint16_t l_pricelist_count = 0; - char ** l_pricelist = dap_config_get_array_str(g_config,"srv_vpn","pricelist", &l_pricelist_count ); - for ( uint16_t i = 0; i < l_pricelist_count; i++ ){ - char * l_price_str = l_pricelist[i]; - size_t l_price_length = strlen(l_price_str); - size_t l_iter = 0; - char * l_pos_old = l_price_str; - dap_chain_net_srv_price_t *l_price = DAP_NEW_Z(dap_chain_net_srv_price_t); - for (char * l_pos = index(l_price_str,':'); ; l_pos = index(l_pos+1,':') ){ - if( l_iter == 0) - break; - - size_t l_parse_token_size = l_pos?(size_t) (l_pos - l_pos_old)-1: l_price_length- (size_t)(l_pos_old - l_pricelist[i]) ; - char * l_parse_token = strndup(l_pos_old, l_parse_token_size); - if( l_parse_token_size ==0 ){ - log_it(L_ERROR, "Wrong price element size nil"); - DAP_DELETE(l_parse_token); - break; - } - if ( l_iter == 0){ - l_price->net_name = strdup(l_parse_token); + l_srv->pricelist = NULL; - l_price->net = dap_chain_net_by_name( l_price->net_name); - if( ! l_price->net ){ - log_it(L_ERROR, "Error parse pricelist: can't find network \"%s\"", l_price->net_name); - DAP_DELETE( l_price->net); + /* ! IMPORTANT ! This fetch is single-action and cannot be further reused, since it modifies the stored config data + * ! it also must NOT be freed within this module ! + */ + char **l_pricelist = dap_config_get_array_str(g_config, "srv_vpn", "pricelist", &l_pricelist_count); // must not be freed! + for (uint16_t i = 0; i < l_pricelist_count; i++) { + dap_chain_net_srv_price_t *l_price = DAP_NEW_Z(dap_chain_net_srv_price_t); + short l_iter = 0; + char *l_ctx; + for (char *l_price_token = strtok_r(l_pricelist[i], ":", &l_ctx); l_price_token || l_iter == 6; l_price_token = strtok_r(NULL, ":", &l_ctx), ++l_iter) { + //log_it(L_DEBUG, "Tokenizer: %s", l_price_token); + switch (l_iter) { + case 0: + l_price->net_name = l_price_token; + if (!(l_price->net = dap_chain_net_by_name(l_price->net_name))) { + log_it(L_ERROR, "Error parsing pricelist: can't find network \"%s\"", l_price_token); DAP_DELETE(l_price); - DAP_DELETE(l_parse_token); break; } - }else if (l_iter == 1){ - l_price->value_coins = atof( l_parse_token); - l_price->value_datoshi =(uint64_t) dap_chain_coins_to_balance((long double)l_price->value_coins); - if ( ! l_price->value_datoshi ){ - log_it(L_ERROR, "Error parse pricelist: text on 2nd position \"%s\" is not floating number", l_parse_token); - DAP_DELETE( l_price->net); + continue; + case 1: + l_price->value_coins = atof(l_price_token); + if (!(l_price->value_datoshi = (uint64_t)dap_chain_coins_to_balance((long double)l_price->value_coins))) { + log_it(L_ERROR, "Error parsing pricelist: text on 2nd position \"%s\" is not floating number", l_price_token); + l_iter = 0; DAP_DELETE(l_price); - DAP_DELETE(l_parse_token); break; } - }else if (l_iter == 2){ - strncpy( l_price->token, l_parse_token, sizeof (l_price->token)-1); - - }else if (l_iter == 3){ - l_price->units = strtoul( l_parse_token,NULL,10); - if ( !l_price->units ){ - log_it(L_ERROR, "Error parse pricelist: text on 4th position \"%s\" is not unsigned integer", l_parse_token); - DAP_DELETE( l_price->net); + continue; + case 2: + dap_stpcpy(l_price->token, l_price_token); + continue; + case 3: + l_price->units = strtoul(l_price_token, NULL, 10); + if (!l_price->units) { + log_it(L_ERROR, "Error parsing pricelist: text on 4th position \"%s\" is not unsigned integer", l_price_token); + l_iter = 0; DAP_DELETE(l_price); - DAP_DELETE(l_parse_token); break; } - }else if (l_iter == 4){ - if ( strcmp(l_parse_token,"SEC") == 0 ){ + continue; + case 4: + if (!strcmp(l_price_token, "SEC")) l_price->units_uid.enm = SERV_UNIT_SEC; - }else if ( strcmp(l_parse_token,"DAY") == 0 ){ + else if (!strcmp(l_price_token, "DAY")) l_price->units_uid.enm = SERV_UNIT_DAY; - }else if ( strcmp(l_parse_token,"MB") == 0 ){ + else if (!strcmp(l_price_token, "MB")) l_price->units_uid.enm = SERV_UNIT_MB; - }else { - log_it(L_ERROR, "Error parse pricelist: wrong unit type \"%s\"", l_parse_token); - DAP_DELETE( l_price->net); + else { + log_it(L_ERROR, "Error parsing pricelist: wrong unit type \"%s\"", l_price_token); + l_iter = 0; DAP_DELETE(l_price); - DAP_DELETE(l_parse_token); break; } - }else if (l_iter == 5){ - l_price->wallet = dap_chain_wallet_open( l_parse_token, dap_config_get_item_str_default(g_config,"resources","wallets_path",NULL) ); - if (! l_price->wallet ){ - log_it(L_ERROR, "Error parse pricelist: can't open wallet \"%s\"", l_parse_token); - DAP_DELETE( l_price->net); + continue; + case 5: + if (!(l_price->wallet = dap_chain_wallet_open(l_price_token, dap_config_get_item_str_default(g_config, "resources", "wallets_path", NULL)))) { + log_it(L_ERROR, "Error parsing pricelist: can't open wallet \"%s\"", l_price_token); + l_iter = 0; DAP_DELETE(l_price); - DAP_DELETE(l_parse_token); break; } - }else{ - DAP_DELETE(l_parse_token); + continue; + case 6: + log_it(L_INFO, "Price item correct, added to service"); + DL_APPEND(l_srv->pricelist, l_price); break; - } - l_iter++; - l_pos_old = l_pos; - if (! l_pos ){ - DAP_DELETE(l_parse_token); + default: break; } + log_it(L_DEBUG, "Done with price item %d", i); + break; // double break exits tokenizer loop and steps to next price item } - if( l_iter == 6){ - log_it(L_NOTICE, "All price parsed well, added to service %s", l_price_str); - if (l_srv->pricelist) - l_srv->pricelist->prev = l_price; - l_price->next = l_srv->pricelist; - l_srv->pricelist = l_price; - } - } - return 0; } return -1; @@ -291,10 +270,10 @@ void dap_chain_net_srv_vpn_deinit(void) { pthread_mutex_destroy(&s_sf_socks_mutex); pthread_cond_destroy(&s_sf_socks_cond); - free((char*) s_srv_vpn_addr); - free((char*) s_srv_vpn_mask); + DAP_DELETE(s_srv_vpn_addr); + DAP_DELETE(s_srv_vpn_mask); if(s_raw_server) - free(s_raw_server); + DAP_DELETE(s_raw_server); } /** diff --git a/dap_chain_net_srv_vpn_cdb.c b/dap_chain_net_srv_vpn_cdb.c index 3179ed3..9485bde 100644 --- a/dap_chain_net_srv_vpn_cdb.c +++ b/dap_chain_net_srv_vpn_cdb.c @@ -71,7 +71,7 @@ typedef struct tx_cond_template{ long double value_coins; uint128_t value_datoshi; - char * token_ticker; + char token_ticker[DAP_CHAIN_TICKER_SIZE_MAX]; char * net_name; dap_chain_net_t * net; dap_ledger_t * ledger; @@ -129,11 +129,13 @@ int dap_chain_net_srv_vpn_cdb_init(dap_http_t * a_http) "cdb_auth", "tx_cond_create", false)) { - log_it (L_DEBUG, "2791: tx_cond_create is true"); // Parse tx cond templates size_t l_tx_cond_tpls_count = 0; + + /* ! IMPORTANT ! This fetch is single-action and cannot be further reused, since it modifies the stored config data + * ! it also must NOT be freed within this module ! + */ char **l_tx_cond_tpls = dap_config_get_array_str(g_config, "cdb_auth", "tx_cond_templates", &l_tx_cond_tpls_count); - log_it (L_DEBUG, "2791: tx_cond_templates: %d", l_tx_cond_tpls_count); if (l_tx_cond_tpls_count == 0) { log_it( L_ERROR, "No condition tpl, can't setup auth callback"); return -5; @@ -141,74 +143,71 @@ int dap_chain_net_srv_vpn_cdb_init(dap_http_t * a_http) db_auth_set_callbacks(s_auth_callback); for (size_t i = 0 ; i < l_tx_cond_tpls_count; i++) { - char *l_wallet_name = NULL; - long double l_value = 0.0L; - char *l_token_ticker = NULL; - char *l_net_name = NULL; - int l_step = 0; - time_t l_min_time = 0; - log_it (L_DEBUG, "2791: tx_cond: %s", l_tx_cond_tpls[i]); + tx_cond_template_t *l_tx_cond_template = DAP_NEW_Z(tx_cond_template_t); // Parse template entries + short l_step = 0; char *ctx; - for (char *l_tpl_token = strtok_r(l_tx_cond_tpls[i], ":", &ctx); l_tpl_token && l_step <= 4; l_tpl_token = strtok_r(NULL, ":", &ctx), ++l_step) { - log_it (L_DEBUG, "2791: tx_cond_token: %s", l_tpl_token); + for (char *l_tpl_token = strtok_r(l_tx_cond_tpls[i], ":", &ctx); l_tpl_token || l_step == 5; l_tpl_token = strtok_r(NULL, ":", &ctx), ++l_step) { switch (l_step) { - case 0: l_wallet_name = l_tpl_token; break; - case 1: l_value = strtold( l_tpl_token, NULL); break; - case 2: l_min_time =(time_t) atoll(l_tpl_token); break; - case 3: l_token_ticker = l_tpl_token; break; - case 4: l_net_name = l_tpl_token; break; - default: log_it(L_WARNING, "Too many ':' (%d) characters in condition template", l_step); break; - } - } - - // If all what we need is present - if (l_step <= 4) { - log_it(L_ERROR, "Not enough elements in condition template: 5 needed, %d present", l_step); - //assert(l_wallet_name && l_value > 0.0L && l_token_ticker && l_net_name && l_min_time); - if (!l_wallet_name || l_value <= 0.0L || !l_token_ticker || !l_net_name || !l_min_time) { - log_it(L_ERROR, "Condition template inconsistent"); + case 0: + if(!(l_tx_cond_template->wallet = dap_chain_wallet_open(l_tpl_token, c_wallets_path))) { + log_it(L_ERROR, "Can't open wallet \"%s\"", l_tpl_token); + DAP_DELETE(l_tx_cond_template); + break; + } + l_tx_cond_template->wallet_name = l_tpl_token; + continue; + case 1: + if (!(l_tx_cond_template->value_coins = strtold(l_tpl_token, NULL))) { + log_it(L_ERROR, "Error parsing tpl: text on 2nd position \"%s\" is not a number", l_tpl_token); + DAP_DELETE(l_tx_cond_template->wallet); + DAP_DELETE(l_tx_cond_template); + l_step = 0; + break; + } + l_tx_cond_template->value_datoshi = dap_chain_coins_to_balance(l_tx_cond_template->value_coins); + continue; + case 2: + if (!(l_tx_cond_template->min_time = (time_t)atoll(l_tpl_token))) { + log_it(L_ERROR, "Error parsing tpl: text on 3d position \"%s\" is not a number", l_tpl_token); + DAP_DELETE(l_tx_cond_template->wallet); + DAP_DELETE(l_tx_cond_template); + l_step = 0; + break; + } + continue; + case 3: + dap_stpcpy(l_tx_cond_template->token_ticker, l_tpl_token); + continue; + case 4: + if (!(l_tx_cond_template->net = dap_chain_net_by_name(l_tpl_token)) + || !(l_tx_cond_template->ledger = dap_chain_ledger_by_net_name(l_tpl_token))) + { + log_it(L_ERROR, "Can't open network \"%s\" or ledger in it", l_tpl_token); + DAP_DELETE(l_tx_cond_template->wallet); + DAP_DELETE(l_tx_cond_template); + l_step = 0; + break; + } + l_tx_cond_template->net_name = l_tpl_token; + continue; + case 5: + log_it(L_INFO, "Condition template correct, added to list"); + DL_APPEND(s_tx_cond_templates, l_tx_cond_template); + break; + default: + break; } - continue; + log_it(L_DEBUG, "Done with tpl item %d", i); + break; // double break exits tokenizer loop and steps to next tpl item } - - // we create condition template - tx_cond_template_t *l_tx_cond_template = DAP_NEW_Z(tx_cond_template_t); - - if(!(l_tx_cond_template->wallet = dap_chain_wallet_open(l_wallet_name, c_wallets_path))) { - log_it(L_ERROR, "Can't open wallet \"%s\" for condition transaction template \"%s\"", l_wallet_name, l_tx_cond_tpls[i]); - DAP_DELETE(l_tx_cond_template); - continue; - } - - if (!(l_tx_cond_template->net = dap_chain_net_by_name(l_net_name))) { - log_it(L_ERROR, "Can't open network \"%s\" for condition transaction template \"%s\"", l_net_name, l_tx_cond_tpls[i]); - DAP_DELETE(l_tx_cond_template->wallet); - DAP_DELETE(l_tx_cond_template); - continue; - } - - if (!(l_tx_cond_template->ledger = dap_chain_ledger_by_net_name(l_net_name))) { - log_it(L_ERROR, "Can't open ledger in network \"%s\" for condition transaction template \"%s\"", l_net_name, l_tx_cond_tpls[i]); - DAP_DELETE(l_tx_cond_template->wallet); - DAP_DELETE(l_tx_cond_template); - continue; - } - - l_tx_cond_template->wallet_name = l_wallet_name; - l_tx_cond_template->net_name = l_net_name; - l_tx_cond_template->min_time = l_min_time; - l_tx_cond_template->value_coins = l_value; - l_tx_cond_template->value_datoshi = dap_chain_coins_to_balance (l_value); - l_tx_cond_template->token_ticker = l_token_ticker; - DL_APPEND(s_tx_cond_templates, l_tx_cond_template); } + if (!s_tx_cond_templates) ret = -1; + } else { + log_it(L_INFO, "No conditional transactions, provide VPN service for free"); } } - - if (!s_tx_cond_templates) - ret = -1; return ret; } @@ -246,8 +245,8 @@ static void s_auth_callback(enc_http_delegate_t* a_delegate, void * a_arg) l_client_key = dap_enc_key_deserealize(l_pkey_raw, l_pkey_raw_size); } - tx_cond_template_t *l_tpl, *l_tmp; - DL_FOREACH_SAFE(s_tx_cond_templates, l_tpl, l_tmp) { + tx_cond_template_t *l_tpl; + DL_FOREACH(s_tx_cond_templates, l_tpl) { size_t l_gdb_group_size = 0; // Try to load from gdb -- GitLab