Skip to content
Snippets Groups Projects
Commit a7487912 authored by dmitriy.gerasimov's avatar dmitriy.gerasimov
Browse files

Merge branch 'support-4218' into 'master'

[-] removed unused code

See merge request !133
parents cf03cd20 1db6777c
No related branches found
No related tags found
1 merge request!133[-] removed unused code
Pipeline #4049 passed with stage
in 12 seconds
/*
* Authors:
* Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
* DeM Labs Inc. https://demlabs.net
* CellFrame https://cellframe.net
* Sources https://gitlab.demlabs.net/cellframe
* Copyright (c) 2017-2019
* All rights reserved.
This file is part of CellFrame SDK the open source project
CellFrame SDK is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CellFrame SDK is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with any CellFrame SDK based project. If not, see <http://www.gnu.org/licenses/>.
*/
#include "utlist.h"
#include "dap_common.h"
#include "dap_config.h"
#include "dap_enc_http.h"
#include "dap_enc_base64.h"
#include "dap_http.h"
#include "dap_chain.h"
#include "dap_chain_net.h"
#include "dap_chain_ledger.h"
#include "dap_chain_wallet.h"
#include "dap_chain_datum_tx.h"
#include "dap_chain_datum_tx_in.h"
#include "dap_chain_datum_tx_in_cond.h"
#include "dap_chain_datum_tx_out_cond.h"
#include "dap_chain_datum_tx_out.h"
#include "dap_chain_datum_tx_pkey.h"
#include "dap_chain_datum_tx_receipt.h"
#include "dap_chain_datum_tx_sig.h"
#include "dap_chain_global_db.h"
#include "dap_chain_node_cli.h"
#include "dap_chain_mempool.h"
#include "dap_pkey.h"
#include "dap_chain_net_srv_vpn.h"
#include "dap_chain_net_srv_vpn_cdb.h"
#include "dap_chain_net_srv_vpn_cdb_auth.h"
#include "dap_chain_net_srv_vpn_cdb_server_list.h"
#define LOG_TAG "dap_chain_net_srv_vpn_cdb"
#define DB_URL "/db"
#define NODELIST_URL "/nodelist"
typedef struct tx_cond_template{
char * wallet_name;
dap_chain_wallet_t * wallet;
long double value_coins;
uint128_t value_datoshi;
char token_ticker[DAP_CHAIN_TICKER_SIZE_MAX];
char * net_name;
dap_chain_net_t * net;
dap_ledger_t * ledger;
time_t min_time; // Minimum time between transactions
struct tx_cond_template *prev, *next;
} tx_cond_template_t;
static tx_cond_template_t *s_tx_cond_templates = NULL;
const char *c_wallets_path = NULL;
static int s_cli_vpn_cdb(int a_argc, char ** a_argv, void *arg_func, char **a_str_reply);
/**
* @brief dap_chain_net_srv_vpn_cdb_init
* @return
*/
int dap_chain_net_srv_vpn_cdb_init(dap_http_t * a_http)
{
int ret=0;
c_wallets_path = dap_chain_wallet_get_path(g_config);
if (dap_config_get_item_bool_default( g_config,
"cdb",
"servers_list_enabled",
false)) {
if (dap_chain_net_srv_vpn_cdb_server_list_init() != 0) {
log_it(L_CRITICAL,"Can't init vpn servers list");
return -10;
}
}
dap_chain_node_cli_cmd_item_create ("vpn_cdb", s_cli_vpn_cdb, NULL, "VPN Central DataBase (CDB) commands",
"vpn_cdb user create --login <Login> --password <Password> [--first_name <First Name] [--last_name <Last Name>] [--email <Email>]"
"[--acive_days <Setup active day thats left for user >]\n"
"\tCreate user with login, password and some more optional fields\n\n"
"vpn_cdb user update --login <Login> [--password <Password>] [--first_name <First Name] [--last_name <Last Name>] [--email <Email>]"
"[--active_days <Setup active days that left for user >]\n"
"\tUpdate existent user\n"
"vpn_cdb user delete --login <Login>\n"
"\tDelete user by login\n"
"vpn_cdb user show --login <Login>\n"
"\tShow user fields by login\n"
"vpn_cdb user check --login <Login> --password <Password>\n"
"\tCompare <Password> with stored in GDB for <Login>\n"
"vpn_cdb user list\n"
"\tShow all users\n"
"vpn_cdb serial generate -n <number of serial keys>] [-acive_days <active days that left for serial>]\n"
"\tGenerate new serial keys\n"
"vpn_cdb serial list [-n <How many show serial keys>] [-shift <How many skip serial keys>] [-activated_only|-inactive_only] [-nototal|-total_only]\n"
"\tShow serial keys\n"
"vpn_cdb serial update -serial <serial keys> -acive_days <active days that left for serial>\n"
"\tEdit serial key\n"
"vpn_cdb serial info -serial <serial keys>\n"
"\tInformation about serial key\n"
"vpn_cdb serial delete -serial <serial keys>\n"
"\tDelete serial key\n"
"vpn_cdb serial deactivate -serial <serial keys>\n"
"\tDeactivate serial key\n"
);
// Load all chain networks
if (dap_config_get_item_bool_default( g_config,
"cdb",
"servers_list_enabled",
false)) {
dap_chain_net_srv_vpn_cdb_server_list_add_proc ( a_http, NODELIST_URL);
}
if (dap_config_get_item_bool_default( g_config,"cdb_auth","enabled",false) ){
ret = dap_chain_net_srv_vpn_cdb_auth_init( dap_config_get_item_str_default(g_config,"cdb_auth","domain","cdb"),
dap_config_get_item_str_default(g_config,"cdb_auth","mode","passwd"),
dap_config_get_item_bool_default(g_config,"cdb_auth","registration_open",false));
if(ret<0)
return ret;
dap_chain_net_srv_vpn_cdb_auth_add_proc( a_http , DB_URL );
// Produce transaction for authorized users
if (dap_config_get_item_bool_default( g_config,
"cdb_auth",
"tx_cond_create",
false)) {
// Parse tx cond templates
uint16_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);
if (l_tx_cond_tpls_count == 0) {
log_it( L_ERROR, "No condition tpl, can't setup auth callback");
return -5;
}
for (size_t i = 0 ; i < l_tx_cond_tpls_count; 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 == 5; l_tpl_token = strtok_r(NULL, ":", &ctx), ++l_step) {
switch (l_step) {
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;
}
log_it(L_DEBUG, "Done with tpl item %d", i);
break; // double break exits tokenizer loop and steps to next tpl item
}
}
if (!s_tx_cond_templates) ret = -1;
} else {
log_it(L_INFO, "No conditional transactions, provide VPN service for free");
}
}
return ret;
}
static int s_cli_vpn_cdb(int a_argc, char ** a_argv, void *arg_func, char **a_str_reply)
{
const char *l_user_str = NULL;
const char *l_serial_add_param_str = NULL;
int l_arg_index = 1;
int l_ret = -1;
int l_user_pos = dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "user", &l_user_str);
int l_serial_pos = dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "serial", &l_serial_add_param_str);
// Selected 'user' subcommand
if ( l_user_str ){
l_ret = 0;
return dap_chain_net_srv_vpn_cdb_auth_cli_cmd_user(l_user_str,l_arg_index, a_argc, a_argv,a_str_reply);
}
// Selected 'serial' subcoummand
else if(l_serial_add_param_str) {
l_ret = 0;
return dap_chain_net_srv_vpn_cdb_auth_cli_cmd_serial(l_serial_add_param_str, l_arg_index, a_argc, a_argv, a_str_reply);
}
else {
if(l_user_pos || l_user_pos)
dap_chain_node_cli_set_reply_text(a_str_reply, "require additional subcommand, see 'help vpn_cdb'");
else
dap_chain_node_cli_set_reply_text(a_str_reply, "unknown subcommand, use 'user' or 'serial'", l_user_str);
}
return l_ret;
}
/**
* @brief dap_chain_net_srv_vpn_cdb_deinit
*/
void dap_chain_net_srv_vpn_cdb_deinit()
{
}
/**
* @brief dap_chain_net_srv_vpn_cdb_auth_after
* @param a_delegate
* @param a_login
* @param a_pkey_b64
*/
void dap_chain_net_srv_vpn_cdb_auth_after(enc_http_delegate_t* a_delegate, const char * a_login, const char * a_pkey_b64 )
{
#ifndef __ANDROID__
dap_enc_key_t *l_client_key = NULL;
byte_t *l_pkey_raw = NULL;
size_t l_pkey_raw_size = 0;
log_it( L_DEBUG, "Authorized, now need to create conditioned transaction if not present key_len=%d", dap_strlen( a_pkey_b64));
{
size_t l_pkey_b64_length = dap_strlen( a_pkey_b64);
l_pkey_raw = DAP_NEW_Z_SIZE(byte_t,l_pkey_b64_length);
memset(l_pkey_raw, 0, l_pkey_b64_length);
l_pkey_raw_size = dap_enc_base64_decode(a_pkey_b64, l_pkey_b64_length, l_pkey_raw, DAP_ENC_DATA_TYPE_B64_URLSAFE);
char *l_pkey_gdb_group = dap_strdup_printf( "cdb.%s.pkey", DAP_CHAIN_NET_SRV_VPN_CDB_GDB_PREFIX);
log_it(L_DEBUG, "Pkey group '%s'", l_pkey_gdb_group);
dap_chain_global_db_gr_set( dap_strdup(a_login), l_pkey_raw, l_pkey_raw_size, l_pkey_gdb_group);
l_client_key = dap_enc_key_new(DAP_ENC_KEY_TYPE_SIG_TESLA);
int l_res = dap_enc_key_deserealize_pub_key(l_client_key, l_pkey_raw, l_pkey_raw_size);
// bad pkey
if(l_res){
log_it(L_WARNING, "dap_enc_key_deserealize_priv_key='%d'", l_res);
DAP_DELETE(l_pkey_raw);
l_pkey_raw_size = 0;
l_pkey_raw = NULL;
}
DAP_DELETE(l_pkey_gdb_group);
}
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
//char *l_tx_cond_gdb_group = dap_strdup_printf( "%s.%s.tx_cond", l_tpl->net->pub.name, DAP_CHAIN_NET_SRV_VPN_CDB_GDB_PREFIX);
char *l_tx_cond_gdb_group = dap_strdup_printf( "cdb.%s.tx_cond", DAP_CHAIN_NET_SRV_VPN_CDB_GDB_PREFIX);
log_it(L_DEBUG, "Checkout group %s", l_tx_cond_gdb_group);
// get key for tx_cond
char *l_user_key;
{
dap_chain_hash_fast_t l_hash = { 0 };
char *l_key_hash_str = NULL;
if(dap_hash_fast(a_pkey_b64, dap_strlen(a_pkey_b64), &l_hash))
l_key_hash_str = dap_chain_hash_fast_to_str_new(&l_hash);
l_user_key = dap_strdup_printf("%s/%s", a_login, l_key_hash_str);
DAP_DELETE(l_key_hash_str);
}
log_it(L_DEBUG, "\ndbg l_user_key=%s\n", l_user_key);
dap_chain_hash_fast_t *l_tx_cond_hash = (dap_chain_hash_fast_t*) dap_chain_global_db_gr_get(l_user_key, &l_gdb_group_size, l_tx_cond_gdb_group);
// Check for entry size
if (l_gdb_group_size && l_gdb_group_size != sizeof(dap_chain_hash_fast_t)) {
log_it(L_ERROR, "Wrong size of tx condition on database (%zd but expected %zd), may be old entry",
l_gdb_group_size, sizeof(dap_chain_hash_fast_t));
}
time_t l_tx_cond_ts = 0;
// If loaded lets check is it spent or not
if ( l_tx_cond_hash ){
log_it(L_DEBUG, "2791: Search for unspent tx, net %s", l_tpl->net_name);
dap_chain_datum_tx_t *l_tx = dap_chain_net_get_tx_by_hash(l_tpl->net, l_tx_cond_hash, TX_SEARCH_TYPE_NET_UNSPENT);
if ( !l_tx ){ // If not found - all outs are used. Create new one
// pass all chains
l_tx = dap_chain_net_get_tx_by_hash(l_tpl->net, l_tx_cond_hash, TX_SEARCH_TYPE_NET);
DAP_DELETE(l_tx_cond_hash);
l_tx_cond_hash = NULL;
if ( l_tx ){
l_tx_cond_ts =(time_t) l_tx->header.ts_created;
log_it(L_DEBUG, "2791: got some tx, created %d", l_tx->header.ts_created);
}
}
}
// Try to create condition
if (! l_tx_cond_hash ) {
dap_chain_wallet_t *l_wallet_from = l_tpl->wallet;
log_it(L_DEBUG, "Create tx from wallet %s", l_wallet_from->name);
dap_enc_key_t *l_key_from = dap_chain_wallet_get_key(l_wallet_from, 0);
//dap_chain_cell_id_t *xccell = dap_chain_net_get_cur_cell(l_tpl->net);
//uint64_t uint64 =dap_chain_net_get_cur_cell(l_tpl->net)->uint64;
// where to take coins for service
dap_chain_addr_t *l_addr_from = dap_chain_wallet_get_addr(l_wallet_from, l_tpl->net->pub.id);
dap_chain_net_srv_price_unit_uid_t l_price_unit = { .enm = SERV_UNIT_SEC };
dap_chain_net_srv_uid_t l_srv_uid = { .uint64 = DAP_CHAIN_NET_SRV_VPN_ID };
l_tx_cond_hash = dap_chain_proc_tx_create_cond(l_tpl->net, l_key_from, l_client_key, l_addr_from, l_tpl->token_ticker,
(uint64_t) l_tpl->value_datoshi, 0, l_price_unit, l_srv_uid, 0, l_pkey_raw, l_pkey_raw_size);
char *l_addr_from_str = dap_chain_addr_to_str( l_addr_from );
DAP_DELETE( l_addr_from);
if (!l_tx_cond_hash) {
log_it(L_ERROR, "Can't create condition for user");
} else {
// save transaction for login
dap_chain_global_db_gr_set(l_user_key, l_tx_cond_hash, sizeof(dap_chain_hash_fast_t), l_tx_cond_gdb_group);
log_it(L_NOTICE, "User \"%s\": created conditioned transaction from %s(%s) on "
, a_login, l_tpl->wallet_name, l_addr_from_str);
}
DAP_DELETE( l_addr_from_str );
}
DAP_DELETE(l_user_key);
// dbg
//dap_ledger_t * l_ledger = dap_chain_ledger_by_net_name( l_tpl->net->pub.name);
//dap_chain_datum_tx_t *l_tx = dap_chain_ledger_tx_find_by_hash( l_ledger, l_tx_cond_hash);
// If we loaded or created hash
if( l_tx_cond_hash ){
char * l_tx_cond_hash_str = dap_chain_hash_fast_to_str_new(l_tx_cond_hash);
enc_http_reply_f(a_delegate,"\t<tx_cond_tpl>\n");
//enc_http_reply_f(a_delegate,"\t\t<net>%s</net>\n",l_tpl->net_name);
enc_http_reply_f(a_delegate,"\t\t<net>0x%x</net>\n",l_tpl->net->pub.id.uint64);
enc_http_reply_f(a_delegate,"\t\t<token>%s</token>\n",l_tpl->token_ticker);
enc_http_reply_f(a_delegate,"\t\t<tx_cond>%s</tx_cond>\n",l_tx_cond_hash_str);
enc_http_reply_f(a_delegate,"\t</tx_cond_tpl>\n");
DAP_DELETE(l_tx_cond_hash);
DAP_DELETE(l_tx_cond_hash_str);
}
DAP_DELETE(l_tx_cond_gdb_group);
}
if (l_client_key)
dap_enc_key_delete(l_client_key);
#endif
}
This diff is collapsed.
/*
* Authors:
* Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
* Alexander Lysikov <alexander.lysikov@demlabs.net>
* DeM Labs Inc. https://demlabs.net
* CellFrame https://cellframe.net
* Sources https://gitlab.demlabs.net/cellframe
* Copyright (c) 2017-2019
* All rights reserved.
This file is part of DAP (Deus Applications Prototypes) the open source project
DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DAP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with any DAP based project. If not, see <http://www.gnu.org/licenses/>.
*/
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "dap_common.h"
#include "dap_config.h"
#include "dap_chain.h"
#include "dap_chain_net.h"
#include "dap_chain_net_srv.h"
#include "dap_chain_net_srv_vpn.h"
#include "dap_chain_net_srv_order.h"
#include "dap_chain_net_srv_geoip.h"
#include "dap_http.h"
#include "dap_http_simple.h"
#include "http_status_code.h"
#include "dap_chain_net_srv_vpn_cdb_server_list.h"
#define LOG_TAG "dap_chain_net_srv_vpn_cdb_server_list"
static size_t s_cdb_net_count = 0;
static dap_chain_net_t ** s_cdb_net = NULL;
static void s_http_simple_proc(dap_http_simple_t *a_http_simple, void *a_arg);
int dap_chain_net_srv_vpn_cdb_server_list_init()
{
char **l_cdb_networks;
uint16_t l_cdb_networks_count = 0;
log_it(L_NOTICE,"Initialized Server List Module");
l_cdb_networks = dap_config_get_array_str( g_config, "cdb", "servers_list_networks", &l_cdb_networks_count );
if ( l_cdb_networks_count ){
s_cdb_net = DAP_NEW_Z_SIZE(dap_chain_net_t*, sizeof (dap_chain_net_t*)* l_cdb_networks_count );
s_cdb_net_count = l_cdb_networks_count;
for ( size_t i = 0; i < l_cdb_networks_count ; i++) {
s_cdb_net[i] = dap_chain_net_by_name( l_cdb_networks[i] );
if ( s_cdb_net[i] )
log_it( L_INFO, "Added \"%s\" network for server list fetchs", l_cdb_networks[i]);
else
log_it( L_WARNING, "Can't find \"%s\" network to add to server list fetchs", l_cdb_networks[i]);
}
} else
log_it( L_WARNING, "No chain networks listed in config");
return 0;
}
void dap_chain_net_srv_vpn_cdb_server_list_deinit(void)
{
}
/**
* @brief order_info_print
* @param a_server_location for server name, NULL not used
* @param a_node_number for server name, <0 not use
*/
static int order_info_print(dap_string_t *a_reply_str, dap_chain_net_t * a_net, dap_chain_net_srv_order_t * a_order, const char *a_server_name, int a_node_number)
{
dap_chain_node_info_t * l_node_info = dap_chain_node_info_read(a_net, &a_order->node_addr);
if(l_node_info) {
char l_node_ext_ipv4_str[INET_ADDRSTRLEN] = { 0 };
char l_node_ext_ipv6_str[INET6_ADDRSTRLEN] = { 0 };
if(l_node_info->hdr.ext_addr_v4.s_addr)
inet_ntop(AF_INET, &l_node_info->hdr.ext_addr_v4, l_node_ext_ipv4_str, sizeof(l_node_ext_ipv4_str));
if(*((uint128_t *) l_node_info->hdr.ext_addr_v6.s6_addr))
inet_ntop(AF_INET6, &l_node_info->hdr.ext_addr_v6, l_node_ext_ipv6_str, sizeof(l_node_ext_ipv6_str));
uint8_t l_continent_num = 0;
char *l_region = NULL;
dap_chain_net_srv_order_get_continent_region(a_order, &l_continent_num, &l_region);
const char *l_continent_str = dap_chain_net_srv_order_continent_to_str(l_continent_num);
// ext_out in hex view
char *l_ext_out = a_order->ext_size ? DAP_NEW_Z_SIZE(char, a_order->ext_size * 2 + 1) : NULL;
dap_bin2hex(l_ext_out, a_order->ext, a_order->ext_size);
dap_string_append_printf(a_reply_str, " {\n");
dap_string_append_printf(a_reply_str, " \"Location\":\"%s\",\n", l_region ? l_region : "None"); //NETHERLANDS
//l_continent_str ? l_continent_str : "None", l_region ? l_region : "None");
dap_string_append_printf(a_reply_str, " \"ChainNet\":\"%s\",\n", a_net->pub.name);
//dap_string_append_printf(a_reply_str, " \"Name\":\"%s.Cell-%lu.%zd\",\n", a_net->pub.name, l_node_info->hdr.cell_id.uint64, 0);
if(a_server_name)
dap_string_append_printf(a_reply_str, " \"Name\":\"%s\",\n", a_server_name);
else
dap_string_append_printf(a_reply_str, " \"Name\":\"%s.%s.%zd\",\n", l_continent_str ? l_continent_str : "", l_region ? l_region : "", a_node_number + 1);
//dap_string_append_printf(a_reply_str, " \"Name\":\"%s.%s.Cell-%lu.%zd\",\n", l_continent_str ? l_continent_str : "", l_region ? l_region : "", l_node_info->hdr.cell_id.uint64, a_node_number + 1);
if(l_node_ext_ipv4_str[0])
dap_string_append_printf(a_reply_str, " \"Address\":\"%s\",\n", l_node_ext_ipv4_str);
if(l_node_ext_ipv6_str[0])
dap_string_append_printf(a_reply_str, " \"Address6\":\"%s\",\n", l_node_ext_ipv6_str);
dap_string_append_printf(a_reply_str, " \"Port\":%hu,\n", l_node_info->hdr.ext_port ? l_node_info->hdr.ext_port : 80);
//dap_string_append_printf(a_reply_str, " \"Ext\":\"%s-%s\",\n", l_continent_str ? l_continent_str : "", l_region ? l_region : "");
if(l_ext_out)
dap_string_append_printf(a_reply_str, " \"Ext\":\"0x%s\",\n", l_ext_out);
else
dap_string_append_printf(a_reply_str, " \"Ext\":\"0x0\",\n");
dap_string_append_printf(a_reply_str, " \"Price\":%lu,\n", a_order->price);
dap_string_append_printf(a_reply_str, " \"PriceUnits\":%u,\n", a_order->price_unit.uint32);
dap_string_append_printf(a_reply_str, " \"PriceToken\":\"%s\"\n", a_order->price_ticker);
dap_string_append_printf(a_reply_str, " }");
DAP_DELETE(l_region);
DAP_DELETE(l_ext_out);
} else{
log_it(L_WARNING, "Order in \"%s\" network issued by node without ext_ipv4 field", a_net->pub.name);
return -1;
}
return 0;
}
static void s_http_simple_proc(dap_http_simple_t *a_http_simple, void *a_arg)
{
http_status_code_t * l_ret_code = (http_status_code_t*)a_arg;
dap_string_t *l_reply_str = dap_string_new("[\n");
char *l_client_ip = a_http_simple->http->client->s_ip;//"64.225.61.216"
geoip_info_t *l_geoip_info = chain_net_geoip_get_ip_info(l_client_ip);
log_it(L_DEBUG, "Have %zd chain networks for cdb lists", s_cdb_net_count );
for ( size_t i = 0; i < s_cdb_net_count ; i++ ) {
dap_chain_net_t * l_net = s_cdb_net[i];
if ( l_net ) {
dap_chain_net_srv_order_t * l_orders = NULL;
size_t l_orders_num = 0;
dap_chain_net_srv_price_unit_uid_t l_unit_uid = {{0}};
dap_chain_net_srv_uid_t l_srv_uid = { .uint64 =DAP_CHAIN_NET_SRV_VPN_ID };
dap_chain_net_srv_order_find_all_by( l_net, SERV_DIR_SELL, l_srv_uid, l_unit_uid ,
NULL,0,0, &l_orders, &l_orders_num );
log_it(L_DEBUG, "Found %zd orders in \"%s\" network", l_orders_num, l_net->pub.name );
// find the shift for each node
dap_chain_net_srv_order_t *l_orders_pos[l_orders_num];
size_t l_orders_size = 0;
for(size_t j = 0; j < l_orders_num; j++) {
l_orders_pos[j] = (dap_chain_net_srv_order_t*) ((char*) l_orders + l_orders_size);
l_orders_size += dap_chain_net_srv_order_get_size(l_orders_pos[j]);
}
// list of node numbers
size_t l_continents_count = dap_chain_net_srv_order_continents_count(); //int *l_node_numbering = DAP_NEW_Z_SIZE(int, l_orders_num * sizeof(int));
// list of the number of nodes in each continent
int l_continents_numbers[l_continents_count]; //int *l_continents_numbers = DAP_NEW_Z_SIZE(int, l_continents_count * sizeof(int));
int l_node_numbering[l_continents_count][l_orders_num];
// init arrays
for(size_t m1 = 0; m1 < l_continents_count; m1++) {
l_continents_numbers[m1] = 0;
for(size_t m2 = 0; m2 < l_orders_num; m2++)
l_node_numbering[m1][m2] = -1;
}
// node numbering
size_t l_orders_used_num = 0;
{
// filling l_continents_numbers and l_node_numbering
for(size_t j = 0; j < l_orders_num; j++) {
dap_chain_net_srv_order_t *l_order = l_orders_pos[j];
uint8_t l_continent_num;
if(!dap_chain_net_srv_order_get_continent_region(l_order, &l_continent_num, NULL))
continue;
l_node_numbering[l_continent_num][j] = l_continents_numbers[l_continent_num]++;
l_orders_used_num++;
}
// shuffle nodes for each continent
for(size_t m1 = 0; m1 < l_continents_count; m1++) {
int l_cont_num = l_continents_numbers[m1];
if(l_cont_num <= 1)
continue;
// number of shuffles
int l_shuffle_num = rand() % (l_cont_num + 1);
for(size_t l_sh = 0; l_sh <= l_shuffle_num; l_sh++) {
size_t l_pos1 = 0;
size_t l_pos2 = 0;
while(l_pos1 == l_pos2) {
l_pos1 = rand() % l_cont_num;
l_pos2 = rand() % l_cont_num;
}
for(size_t m2 = 0; m2 < l_orders_num; m2++) {
if(l_node_numbering[m1][m2] == l_pos1)
l_node_numbering[m1][m2] = l_pos2;
else if(l_node_numbering[m1][m2] == l_pos2)
l_node_numbering[m1][m2] = l_pos1;
}
}
}
}
int8_t l_client_continent = l_geoip_info ? dap_chain_net_srv_order_continent_to_num(l_geoip_info->continent) : 0;
// random node on client's continent
if(l_client_continent > 0 && l_continents_numbers[l_client_continent] > 1) {
int l_count = 0;
while(l_orders_num > 0) {
size_t k = rand() % l_continents_numbers[l_client_continent];
size_t l_node_pos = -1;
for(size_t j2 = 0; j2 <= l_orders_num; j2++) {
if(k == l_node_numbering[l_client_continent][j2]) {
l_node_pos = j2;
break;
}
}
if(l_node_pos == -1) {
// random node for the whole world
l_node_pos = rand() % l_orders_num;
}
dap_chain_net_srv_order_t *l_order = l_orders_pos[l_node_pos];
const char *country_code = dap_chain_net_srv_order_get_country_code(l_order);
if(country_code) {
// only for other countries
if(dap_strcmp(l_geoip_info->country_code, country_code)) {
if(!order_info_print(l_reply_str, l_net, l_order, "Auto", -1)) {
dap_string_append_printf(l_reply_str, ",\n");
break;
}
}
}
if(l_count > 20)
break;
l_count++;
}
}
// random node for the whole world
else {
int l_count = 0;
while(l_orders_num > 0) {
// first random node
size_t k = rand() % l_orders_num;
dap_chain_net_srv_order_t *l_order = l_orders_pos[k];
if(!order_info_print(l_reply_str, l_net, l_order, "Auto", -1)){
dap_string_append_printf(l_reply_str, ",\n");
break;
}
if (l_count>20)
break;
l_count++;
}
}
// random nodes for continents
int l_count = 0;
for(size_t l_c = 0; l_c < l_continents_count; l_c++) {
while(l_continents_numbers[l_c] > 0) {
// random node for continent
size_t k = rand() % l_continents_numbers[l_c];
size_t l_node_pos = -1;
for(size_t j2 = 0; j2 <= l_orders_num; j2++) {
if(k == l_node_numbering[l_c][j2]) {
l_node_pos = j2;
break;
}
}
if(l_node_pos == -1)
break;
dap_chain_net_srv_order_t *l_order = l_orders_pos[l_node_pos];
char *l_server_name = dap_strdup_printf("%s", dap_chain_net_srv_order_continent_to_str(l_c));
if(!order_info_print(l_reply_str, l_net, l_order, l_server_name, -1)) {
dap_string_append_printf(l_reply_str, ",\n");
DAP_DELETE(l_server_name);
break;
}
else
DAP_DELETE(l_server_name);
if(l_count > 20)
break;
l_count++;
}
}
for(size_t l_c = 0; l_c < l_continents_count; l_c++) {
// print all nodes for continent
for(size_t l_n = 0; l_n < l_continents_numbers[l_c]; l_n++) {
// since the nodes are shuffled, look for the desired node index
for(size_t l_o = 0; l_o < l_orders_num; l_o++) {
if(l_node_numbering[l_c][l_o] != l_n)
continue;
dap_chain_net_srv_order_t *l_order = l_orders_pos[l_o];
if(!order_info_print(l_reply_str, l_net, l_order, NULL, l_n)) {
dap_string_append_printf(l_reply_str, ",\n");
}
break;
}
}
}
}
}
DAP_DELETE(l_geoip_info);
//delete trailing comma if exists
if(l_reply_str->str[l_reply_str->len - 2] == ','){
dap_string_truncate(l_reply_str, l_reply_str->len - 2);
dap_string_append_printf(l_reply_str, "\n");
}
dap_string_append_printf( l_reply_str, "]\n\n");
dap_http_simple_reply( a_http_simple, l_reply_str->str, l_reply_str->len );
dap_string_free(l_reply_str, true);
//log_it(L_DEBUG,"Reply in buffer: %s", a_http_simple->reply_str );
*l_ret_code = Http_Status_OK;
}
/**
* @brief dap_chain_net_srv_vpn_cdb_server_list_add_proc
* @param sh
* @param url
*/
void dap_chain_net_srv_vpn_cdb_server_list_add_proc(dap_http_t *a_http, const char *a_url)
{
dap_http_simple_proc_add(a_http,a_url,100000,s_http_simple_proc);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment