From 77fd968a06a994df671867b8a8b92efb85a92f11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Al=D0=B5x=D0=B0nder=20Lysik=D0=BEv?= <alexander.lysikov@demlabs.net> Date: Thu, 18 Jun 2020 21:27:33 +0500 Subject: [PATCH] added vpn client inside node --- dap-sdk/core/src/dap_common.c | 5 +- dap-sdk/crypto/include/dap_enc_SEED.h | 2 +- dap-sdk/net/client/dap_client_pvt.c | 13 +- dap-sdk/net/client/include/dap_client_pvt.h | 2 +- dap-sdk/net/core/dap_events_socket.c | 5 +- .../dap_stream_ch_chain_net_srv.c | 52 ++- .../include/dap_stream_ch_chain_net_srv.h | 3 + modules/net/dap_chain_node_cli.c | 2 +- modules/net/dap_chain_node_cli_cmd.c | 87 +++- modules/net/dap_chain_node_client.c | 28 +- modules/net/srv/dap_chain_net_srv.c | 1 + modules/net/srv/dap_chain_net_srv_client.c | 29 ++ modules/net/srv/dap_chain_net_srv_common.c | 4 + modules/net/srv/include/dap_chain_net_srv.h | 14 + .../srv/include/dap_chain_net_srv_client.h | 5 + .../srv/include/dap_chain_net_srv_common.h | 3 + modules/service/vpn/CMakeLists.txt | 2 +- modules/service/vpn/dap_chain_net_srv_vpn.c | 398 +++++++++++----- .../service/vpn/dap_chain_net_srv_vpn_cdb.c | 4 +- .../vpn/dap_chain_net_srv_vpn_cdb_auth.c | 8 +- .../dap_chain_net_srv_vpn_cdb_server_list.c | 17 +- .../service/vpn/dap_chain_net_vpn_client.c | 436 ++++++++++++------ .../vpn/dap_chain_net_vpn_client_tun.c | 137 +++++- .../vpn/include/dap_chain_net_srv_vpn.h | 4 + .../include/dap_chain_net_srv_vpn_cdb_auth.h | 4 +- .../vpn/include/dap_chain_net_vpn_client.h | 13 +- 26 files changed, 962 insertions(+), 316 deletions(-) diff --git a/dap-sdk/core/src/dap_common.c b/dap-sdk/core/src/dap_common.c index 78b63ee843..39d6bec006 100755 --- a/dap-sdk/core/src/dap_common.c +++ b/dap-sdk/core/src/dap_common.c @@ -166,8 +166,9 @@ static char* s_appname = NULL; DAP_STATIC_INLINE void s_update_log_time(char *a_datetime_str) { time_t t = time(NULL); - struct tm *tmptime = localtime(&t); - strftime(a_datetime_str, 32, "[%x-%X]", tmptime); + struct tm tmptime; + if(localtime_r(&t, &tmptime)) + strftime(a_datetime_str, 32, "[%x-%X]", &tmptime); } /** diff --git a/dap-sdk/crypto/include/dap_enc_SEED.h b/dap-sdk/crypto/include/dap_enc_SEED.h index 8ff83d6c8f..8b9a31acea 100644 --- a/dap-sdk/crypto/include/dap_enc_SEED.h +++ b/dap-sdk/crypto/include/dap_enc_SEED.h @@ -3,7 +3,7 @@ #include <stddef.h> #include "dap_enc_key.h" -#include "seed.h" +#include "seed/seed.h" #ifdef __cplusplus extern "C" { diff --git a/dap-sdk/net/client/dap_client_pvt.c b/dap-sdk/net/client/dap_client_pvt.c index 04e2fb58d3..fd15bb670d 100644 --- a/dap-sdk/net/client/dap_client_pvt.c +++ b/dap-sdk/net/client/dap_client_pvt.c @@ -408,8 +408,12 @@ static void s_stage_status_after(dap_client_pvt_t * a_client_pvt) l_key_str, DAP_ENC_DATA_TYPE_B64); log_it(L_DEBUG, "ENC request size %u", l_key_str_enc_size); - dap_client_pvt_request(a_client_pvt, DAP_UPLINK_PATH_ENC_INIT "/gd4y5yh78w42aaagh", + int l_res = dap_client_pvt_request(a_client_pvt, DAP_UPLINK_PATH_ENC_INIT "/gd4y5yh78w42aaagh", l_key_str, l_key_str_enc_size, m_enc_init_response, m_enc_init_error); + // bad request + if(l_res<0){ + a_client_pvt->stage_status = STAGE_STATUS_ERROR; + } DAP_DELETE(l_key_str); } break; @@ -668,7 +672,7 @@ void dap_client_pvt_stage_transaction_begin(dap_client_pvt_t * a_client_internal * @param a_request_size * @param a_response_proc */ -void dap_client_pvt_request(dap_client_pvt_t * a_client_internal, const char * a_path, void * a_request, +int dap_client_pvt_request(dap_client_pvt_t * a_client_internal, const char * a_path, void * a_request, size_t a_request_size, dap_client_callback_data_size_t a_response_proc, dap_client_callback_int_t a_response_error) { @@ -689,11 +693,14 @@ void dap_client_pvt_request(dap_client_pvt_t * a_client_internal, const char * a // l_url = DAP_NEW_Z_SIZE(char, l_url_size_max); // snprintf(l_url, l_url_size_max, "http://%s:%u", a_client_internal->uplink_addr, a_client_internal->uplink_port); // } - dap_client_http_request(a_client_internal->uplink_addr,a_client_internal->uplink_port, a_request ? "POST" : "GET", "text/text", a_path, a_request, + void *l_ret = dap_client_http_request(a_client_internal->uplink_addr,a_client_internal->uplink_port, a_request ? "POST" : "GET", "text/text", a_path, a_request, a_request_size, NULL, m_request_response, m_request_error, a_client_internal, NULL); // a_client_internal->curl = dap_http_client_simple_request(l_url, a_request ? "POST" : "GET", "text/text", a_request, // a_request_size, NULL, m_request_response, m_request_error, &a_client_internal->curl_sockfd, a_client_internal, NULL); // DAP_DELETE(l_url); + if(l_ret) + return 0; + return -1; } /** diff --git a/dap-sdk/net/client/include/dap_client_pvt.h b/dap-sdk/net/client/include/dap_client_pvt.h index 3c27387fbe..9c93e03ad6 100644 --- a/dap-sdk/net/client/include/dap_client_pvt.h +++ b/dap-sdk/net/client/include/dap_client_pvt.h @@ -89,7 +89,7 @@ void dap_client_pvt_deinit(); void dap_client_pvt_stage_transaction_begin(dap_client_pvt_t * dap_client_pvt_t, dap_client_stage_t a_stage_next, dap_client_callback_t a_done_callback); -void dap_client_pvt_request(dap_client_pvt_t * a_client_internal, const char * a_path, void * a_request, +int dap_client_pvt_request(dap_client_pvt_t * a_client_internal, const char * a_path, void * a_request, size_t a_request_size, dap_client_callback_data_size_t a_response_proc, dap_client_callback_int_t a_response_error); void dap_client_pvt_request_enc(dap_client_pvt_t * a_client_internal, const char * a_path, const char * a_sub_url, diff --git a/dap-sdk/net/core/dap_events_socket.c b/dap-sdk/net/core/dap_events_socket.c index 6060e27a3f..22693a4597 100644 --- a/dap-sdk/net/core/dap_events_socket.c +++ b/dap-sdk/net/core/dap_events_socket.c @@ -264,9 +264,12 @@ int dap_events_socket_kill_socket( dap_events_socket_t *a_es ) return -1; } + dap_worker_t *w = a_es->dap_worker; + // worker not initialized yet + if(!w) + return -2; uint32_t tn = a_es->dap_worker->number_thread; - dap_worker_t *w = a_es->dap_worker; //dap_events_t *d_ev = w->events; pthread_mutex_lock( &w->locker_on_count ); diff --git a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c index c15223614f..2a1422804c 100644 --- a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c +++ b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c @@ -33,6 +33,7 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic #include "dap_chain_mempool.h" #include "dap_chain_net_srv.h" +#include "dap_chain_net_srv_common.h" #include "dap_chain_net_srv_stream_session.h" @@ -48,6 +49,7 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic typedef struct dap_stream_ch_chain_net_srv { pthread_mutex_t mutex; + dap_chain_net_srv_uid_t srv_uid; } dap_stream_ch_chain_net_srv_t; #define DAP_STREAM_CH_CHAIN_NET_SRV(a) ((dap_stream_ch_chain_net_srv_t *) ((a)->internal) ) @@ -57,7 +59,6 @@ static void s_stream_ch_delete(dap_stream_ch_t* ch , void* arg); static void s_stream_ch_packet_in(dap_stream_ch_t* ch , void* arg); static void s_stream_ch_packet_out(dap_stream_ch_t* ch , void* arg); - /** * @brief dap_stream_ch_chain_net_init * @return @@ -65,7 +66,7 @@ static void s_stream_ch_packet_out(dap_stream_ch_t* ch , void* arg); int dap_stream_ch_chain_net_srv_init(void) { log_it(L_NOTICE,"Chain network services channel initialized"); - dap_stream_ch_proc_add('R',s_stream_ch_new,s_stream_ch_delete,s_stream_ch_packet_in,s_stream_ch_packet_out); + dap_stream_ch_proc_add(dap_stream_ch_chain_net_srv_get_id(),s_stream_ch_new,s_stream_ch_delete,s_stream_ch_packet_in,s_stream_ch_packet_out); return 0; } @@ -78,6 +79,16 @@ void dap_stream_ch_chain_net_srv_deinit(void) } +/** + * @brief Set srv uid - for client + */ +void dap_stream_ch_chain_net_srv_set_srv_uid(dap_stream_ch_t* a_ch, dap_chain_net_srv_uid_t a_srv_uid) +{ + // save srv id + dap_stream_ch_chain_net_srv_t * l_ch_chain_net_srv = DAP_STREAM_CH_CHAIN_NET_SRV(a_ch); + l_ch_chain_net_srv->srv_uid.uint64 = a_srv_uid.uint64; +} + /** * @brief s_stream_ch_new * @param a_ch @@ -135,6 +146,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg) if(l_ch_pkt ) { switch (l_ch_pkt->hdr.type) { + // only for server case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_REQUEST:{ if (l_ch_pkt->hdr.size < sizeof(dap_stream_ch_chain_net_srv_pkt_request_hdr_t) ){ log_it( L_WARNING, "Wrong request size, less than minimum"); @@ -312,10 +324,35 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg) //if(l_receipt) // DAP_DELETE(l_receipt); } break; + // only for client case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_REQUEST:{ log_it( L_NOTICE, "Requested smth to sign"); + dap_chain_datum_tx_receipt_t * l_receipt = (dap_chain_datum_tx_receipt_t *) l_ch_pkt->data; + size_t l_receipt_size = l_ch_pkt->hdr.size; + // create receipt copy, because l_receipt may be reallocated inside dap_chain_datum_tx_receipt_create()! + dap_chain_datum_tx_receipt_t *l_receipt_new = dap_chain_datum_tx_receipt_create(l_receipt->receipt_info.srv_uid, + l_receipt->receipt_info.units_type, + l_receipt->receipt_info.units, + l_receipt->receipt_info.value_datoshi, + l_receipt->exts_n_signs, l_receipt->exts_size); + + + //l_srv_session->usages + ///l_usage->service->uid.uint64; + //dap_chain_net_srv_usage_t * l_usage = dap_chain_net_srv_usage_find( l_srv_session, l_pkt->hdr.usage_id ); + dap_chain_net_srv_t * l_srv = dap_chain_net_srv_get(l_ch_chain_net_srv->srv_uid); + if(l_srv && l_srv->callback_client_sign_request) { + // Sign receipt + l_srv->callback_client_sign_request(l_srv, 0, NULL, &l_receipt_new, l_receipt_size); + if(dap_stream_ch_pkt_write(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_RESPONSE, + l_receipt_new, l_receipt_new->size)) { + dap_stream_ch_set_ready_to_write(a_ch, true); + } + } + DAP_DELETE(l_receipt_new); // TODO sign smth } break; + // only for server case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_RESPONSE:{ if ( l_ch_pkt->hdr.size > sizeof(dap_chain_receipt_info_t)+1 ){ dap_chain_datum_tx_receipt_t * l_receipt = (dap_chain_datum_tx_receipt_t *) l_ch_pkt->data; @@ -485,6 +522,17 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg) case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_SUCCESS:{ log_it( L_NOTICE, "Responsed with success"); // TODO code for service client mode + dap_stream_ch_chain_net_srv_pkt_success_t * l_success = (dap_stream_ch_chain_net_srv_pkt_success_t*)l_ch_pkt->data; + size_t l_success_size = l_ch_pkt->hdr.size; + dap_chain_net_srv_t * l_srv = dap_chain_net_srv_get(l_success->hdr.srv_uid); + if ( l_srv && l_srv->callback_client_success){ + // Create client for client) + dap_chain_net_srv_client_t *l_clients = DAP_NEW_Z( dap_chain_net_srv_client_t); + l_clients->ch = a_ch; + l_clients->ts_created = time(NULL); + l_srv->callback_client_success(l_srv, l_success->hdr.usage_id, l_clients, l_success, l_success_size ); + //l_success->hdr.net_id, l_success->hdr.srv_uid, l_success->hdr.usage_id + } } break; case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_DATA:{ if (l_ch_pkt->hdr.size < sizeof(dap_stream_ch_chain_net_srv_pkt_data_hdr_t) ){ diff --git a/modules/channel/chain-net-srv/include/dap_stream_ch_chain_net_srv.h b/modules/channel/chain-net-srv/include/dap_stream_ch_chain_net_srv.h index e323beced4..d614b20b0c 100644 --- a/modules/channel/chain-net-srv/include/dap_stream_ch_chain_net_srv.h +++ b/modules/channel/chain-net-srv/include/dap_stream_ch_chain_net_srv.h @@ -25,6 +25,9 @@ #pragma once +#include "dap_chain_common.h" + int dap_stream_ch_chain_net_srv_init(void); void dap_stream_ch_chain_net_srv_deinit(void); +void dap_stream_ch_chain_net_srv_set_srv_uid(dap_stream_ch_t* a_ch, dap_chain_net_srv_uid_t a_srv_uid); diff --git a/modules/net/dap_chain_node_cli.c b/modules/net/dap_chain_node_cli.c index d3ebd6e8bc..f5efed9dc6 100644 --- a/modules/net/dap_chain_node_cli.c +++ b/modules/net/dap_chain_node_cli.c @@ -996,7 +996,7 @@ int dap_chain_node_cli_init(dap_config_t * g_config) // vpn client dap_chain_node_cli_cmd_item_create ("vpn_client", com_vpn_client, NULL, "VPN client control", - "vpn_client [start -addr <server address> -port <server port>| stop | status]\n"); + "vpn_client [start -addr <server address> -port <server port>| stop | status] -net <net name>\n"); // Log diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index ad07d981cb..94ee286ba0 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -3795,7 +3795,7 @@ int com_vpn_client(int a_argc, char ** a_argv, void *arg_func, char **a_str_repl { #ifndef _WIN32 enum { - CMD_NONE, CMD_START, CMD_STOP, CMD_STATUS + CMD_NONE, CMD_INIT, CMD_START, CMD_STOP, CMD_STATUS }; int l_arg_index = 1; // find net @@ -3804,9 +3804,12 @@ int com_vpn_client(int a_argc, char ** a_argv, void *arg_func, char **a_str_repl return -2; int cmd_num = CMD_NONE; - if(dap_chain_node_cli_find_option_val(a_argv, l_arg_index, min(a_argc, l_arg_index + 1), "start", NULL)) { - cmd_num = CMD_START; + if(dap_chain_node_cli_find_option_val(a_argv, l_arg_index, min(a_argc, l_arg_index + 1), "init", NULL)) { + cmd_num = CMD_INIT; } + if(dap_chain_node_cli_find_option_val(a_argv, l_arg_index, min(a_argc, l_arg_index + 1), "start", NULL)) { + cmd_num = CMD_START; + } else if(dap_chain_node_cli_find_option_val(a_argv, l_arg_index, min(a_argc, l_arg_index + 1), "stop", NULL)) { cmd_num = CMD_STOP; } @@ -3823,6 +3826,48 @@ int com_vpn_client(int a_argc, char ** a_argv, void *arg_func, char **a_str_repl switch (cmd_num) { + case CMD_INIT: { + const char * l_str_token = NULL; // token name + const char * l_str_value_datoshi = NULL; + const char * l_str_wallet = NULL; // wallet name + dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-wallet", &l_str_wallet); + if(!l_str_wallet) + dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-w", &l_str_wallet); + + dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-token", &l_str_token); + dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-value", &l_str_value_datoshi); + + if(!l_str_wallet) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Wallet not defined, use -w <wallet_name> or -wallet <wallet_name> parameter"); + break; + } + if(!l_str_token) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Token not defined, use -token <token_name> parameter"); + break; + } + if(!l_str_value_datoshi) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Value of datoshi not defined, use -value <value of datoshi> parameter"); + break; + } + uint64_t l_a_value_datoshi = strtoull(l_str_value_datoshi, NULL, 10); + if(!l_a_value_datoshi) + l_a_value_datoshi = strtoull(l_str_value_datoshi, NULL, 16); + if(!l_a_value_datoshi) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Value of datoshi have to be more then 0"); + break; + } + int l_res = dap_chain_net_vpn_client_update(l_net, l_str_wallet, l_str_token, l_a_value_datoshi); + if(!l_res) + dap_chain_node_cli_set_reply_text(a_str_reply, "VPN client init successfully"); + else{ + if(l_res==-3) + dap_chain_node_cli_set_reply_text(a_str_reply, "VPN client init successfully, but probably not enough founds in the wallet"); + else + dap_chain_node_cli_set_reply_text(a_str_reply, "VPN client not init"); + } + return l_res; + } + break; case CMD_START: { const char * l_str_addr = NULL; // for example, "192.168.100.93" const char * l_str_port = NULL; // for example, "8079" @@ -3866,22 +3911,36 @@ int com_vpn_client(int a_argc, char ** a_argv, void *arg_func, char **a_str_repl dap_chain_node_cli_set_reply_text(a_str_reply, "VPN client not stopped"); return res; } - //break; + break; case CMD_STATUS: + { + char *l_wallet_name = NULL, *l_str_token = NULL; + uint64_t l_value_datoshi = 0; + dap_chain_net_vpn_client_get_wallet_info(l_net, &l_wallet_name, &l_str_token, &l_value_datoshi); + + const char *l_status_txt = ""; switch (dap_chain_net_vpn_client_status()) { -// switch (0){ - case 0: - dap_chain_node_cli_set_reply_text(a_str_reply, "VPN client stopped"); - return 0; - case 1: - dap_chain_node_cli_set_reply_text(a_str_reply, "VPN client started"); - return 0; - case -1: - dap_chain_node_cli_set_reply_text(a_str_reply, "Can't get VPN state"); - return -1; + case VPN_CLIENT_STATUS_NOT_STARTED: + l_status_txt = "VPN client not started"; + break; + case VPN_CLIENT_STATUS_STARTED: + l_status_txt = "VPN client started"; + break; + case VPN_CLIENT_STATUS_STOPPED: + l_status_txt = "VPN client stopped"; + break; + case VPN_CLIENT_STATUS_CONN_LOST: + l_status_txt = "VPN client lost connection"; + break; + default: + l_status_txt = "VPN client status unknown"; + break; } + dap_chain_node_cli_set_reply_text(a_str_reply, "%s\nused:\nwallet:%s\nreceipt:%u*1e-9 %s", l_status_txt, + l_wallet_name, l_value_datoshi, l_str_token); break; } + } #endif return 0; } diff --git a/modules/net/dap_chain_node_client.c b/modules/net/dap_chain_node_client.c index b8d1c88a33..84d03e43b6 100644 --- a/modules/net/dap_chain_node_client.c +++ b/modules/net/dap_chain_node_client.c @@ -160,22 +160,31 @@ static void s_stage_connected_callback(dap_client_t *a_client, void *a_arg) NODE_ADDR_FP_ARGS_S( l_node_client->remote_node_addr)); pthread_mutex_lock(&l_node_client->wait_mutex); l_node_client->state = NODE_CLIENT_STATE_CONNECTED; - // find current channel code + pthread_mutex_unlock(&l_node_client->wait_mutex); + // set callbacks for C and N channels; for R and S it is not needed dap_client_pvt_t * l_client_internal = DAP_CLIENT_PVT(a_client); - dap_stream_ch_t * l_ch = NULL; - if(l_client_internal && l_client_internal->active_channels) - l_ch = dap_client_get_stream_ch(a_client, l_client_internal->active_channels[0]); + if(l_client_internal && l_client_internal->active_channels) { + size_t l_channels_count = dap_strlen(l_client_internal->active_channels); + for(size_t i = 0; i < l_channels_count; i++) { + if(dap_chain_node_client_set_callbacks(a_client, l_client_internal->active_channels[i]) == -1) { + log_it(L_WARNING, "No ch_chain channel, can't init notify callback for pkt type CH_CHAIN"); + } + } + } + /* + // find current channel code + dap_stream_ch_t * l_ch = NULL; + l_ch = dap_client_get_stream_ch(a_client, l_client_internal->active_channels[0]); //dap_stream_ch_t * l_ch = dap_client_get_stream_ch(a_client, dap_stream_ch_chain_get_id()); if(l_ch) { + dap_chain_node_client_set_callbacks(dap_client_t *a_client, uint8_t a_ch_id) dap_stream_ch_chain_t * l_ch_chain = DAP_STREAM_CH_CHAIN(l_ch); l_ch_chain->callback_notify_packet_out = s_ch_chain_callback_notify_packet_out; l_ch_chain->callback_notify_packet_in = s_ch_chain_callback_notify_packet_in; l_ch_chain->callback_notify_arg = l_node_client; } else { log_it(L_WARNING, "No ch_chain channel, can't init notify callback for pkt type CH_CHAIN"); - } - - pthread_mutex_unlock(&l_node_client->wait_mutex); + }*/ if(l_node_client->callback_connected) l_node_client->callback_connected(l_node_client, a_arg); l_node_client->keep_connection = true; @@ -494,6 +503,11 @@ dap_chain_node_client_t* dap_chain_client_connect(dap_chain_node_info_t *a_node_ //dap_client_pvt_ref(DAP_CLIENT_PVT(l_node_client->client)); // Handshake & connect dap_client_go_stage(l_node_client->client, a_stage_target, s_stage_connected_callback); + dap_client_pvt_t *l_client_internal = DAP_CLIENT_PVT(l_node_client->client); + if(!l_client_internal || l_client_internal->stage_status == STAGE_STATUS_ERROR){ + dap_chain_node_client_close(l_node_client); + return NULL; + } return l_node_client; } diff --git a/modules/net/srv/dap_chain_net_srv.c b/modules/net/srv/dap_chain_net_srv.c index 15b1167389..1fda5aca22 100644 --- a/modules/net/srv/dap_chain_net_srv.c +++ b/modules/net/srv/dap_chain_net_srv.c @@ -509,6 +509,7 @@ dap_chain_net_srv_t* dap_chain_net_srv_add(dap_chain_net_srv_uid_t a_uid,dap_cha HASH_ADD(hh, s_srv_list, uid, sizeof(l_srv->uid), l_sdata); }else{ log_it(L_ERROR, "Already present service with 0x%016llX ", a_uid.uint64); + //l_srv = l_sdata->srv; } pthread_mutex_unlock(&s_srv_list_mutex); return l_srv; diff --git a/modules/net/srv/dap_chain_net_srv_client.c b/modules/net/srv/dap_chain_net_srv_client.c index 35c69cbf8d..c9f43454f3 100644 --- a/modules/net/srv/dap_chain_net_srv_client.c +++ b/modules/net/srv/dap_chain_net_srv_client.c @@ -24,7 +24,36 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic #include "dap_common.h" +#include "dap_chain_net_srv.h" #include "dap_chain_net_srv_client.h" #define LOG_TAG "dap_chain_net_srv_client" + +/* + * Init service client + * l_uid service id + * a_callback_client_success callback to start client service + */ +// +int dap_chain_net_srv_client_init(dap_chain_net_srv_uid_t a_uid, + dap_chain_net_srv_callback_data_t a_callback_request, + dap_chain_net_srv_callback_data_t a_callback_response_success, + dap_chain_net_srv_callback_data_t a_callback_response_error, + dap_chain_net_srv_callback_data_t a_callback_receipt_next_success, + dap_chain_net_srv_callback_data_t a_callback_client_success, + dap_chain_net_srv_callback_data_t a_callback_client_sign_request, + void *a_inhertor) { + + dap_chain_net_srv_t *l_srv_custom = dap_chain_net_srv_get(a_uid); + if(!l_srv_custom) { + l_srv_custom = dap_chain_net_srv_add(a_uid, a_callback_request, + a_callback_response_success, a_callback_response_error, + a_callback_receipt_next_success); + } + l_srv_custom->callback_client_success = a_callback_client_success; + l_srv_custom->callback_client_sign_request = a_callback_client_sign_request; + if(a_inhertor) + l_srv_custom->_inhertor = a_inhertor; + return 0; +} diff --git a/modules/net/srv/dap_chain_net_srv_common.c b/modules/net/srv/dap_chain_net_srv_common.c index 494923184e..23618345a6 100644 --- a/modules/net/srv/dap_chain_net_srv_common.c +++ b/modules/net/srv/dap_chain_net_srv_common.c @@ -46,3 +46,7 @@ #include "dap_stream.h" #include "dap_chain_net_srv_common.h" +uint8_t dap_stream_ch_chain_net_srv_get_id() +{ + return 'R'; +} diff --git a/modules/net/srv/include/dap_chain_net_srv.h b/modules/net/srv/include/dap_chain_net_srv.h index f12364a226..4673bff67e 100755 --- a/modules/net/srv/include/dap_chain_net_srv.h +++ b/modules/net/srv/include/dap_chain_net_srv.h @@ -60,6 +60,11 @@ typedef struct dap_chain_net_srv dap_chain_net_srv_callback_ch_t callback_stream_ch_write; dap_chain_net_srv_callback_ch_t callback_stream_ch_closed; + // Client have to start service + dap_chain_net_srv_callback_data_t callback_client_success; + // Client have to sign receipt + dap_chain_net_srv_callback_data_t callback_client_sign_request; + // Pointer to inheritor object void * _inhertor; } dap_chain_net_srv_t; @@ -96,3 +101,12 @@ dap_chain_datum_tx_receipt_t * dap_chain_net_srv_issue_receipt(dap_chain_net_srv dap_chain_net_srv_price_t * a_price, const void * a_ext, size_t a_ext_size ); + +int dap_chain_net_srv_client_init(dap_chain_net_srv_uid_t a_uid, + dap_chain_net_srv_callback_data_t a_callback_request, + dap_chain_net_srv_callback_data_t a_callback_response_success, + dap_chain_net_srv_callback_data_t a_callback_response_error, + dap_chain_net_srv_callback_data_t a_callback_receipt_next_success, + dap_chain_net_srv_callback_data_t a_callback_client_success, + dap_chain_net_srv_callback_data_t a_callback_client_sign_request, + void *a_inhertor); diff --git a/modules/net/srv/include/dap_chain_net_srv_client.h b/modules/net/srv/include/dap_chain_net_srv_client.h index d385f29c3d..d25801c9cf 100644 --- a/modules/net/srv/include/dap_chain_net_srv_client.h +++ b/modules/net/srv/include/dap_chain_net_srv_client.h @@ -23,9 +23,14 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic */ #pragma once +#include <stdint.h> +#include <time.h> + + #include "dap_chain_net_srv_common.h" #include "dap_chain_net_remote.h" + typedef struct dap_chain_net_srv_client { time_t ts_created; diff --git a/modules/net/srv/include/dap_chain_net_srv_common.h b/modules/net/srv/include/dap_chain_net_srv_common.h index 94886a340c..5fd998bc36 100755 --- a/modules/net/srv/include/dap_chain_net_srv_common.h +++ b/modules/net/srv/include/dap_chain_net_srv_common.h @@ -176,3 +176,6 @@ DAP_STATIC_INLINE const char * dap_chain_net_srv_price_unit_uid_to_str( dap_chai default: return "UNKNOWN"; } } + +uint8_t dap_stream_ch_chain_net_srv_get_id(); + diff --git a/modules/service/vpn/CMakeLists.txt b/modules/service/vpn/CMakeLists.txt index b5aff03684..e897e26558 100644 --- a/modules/service/vpn/CMakeLists.txt +++ b/modules/service/vpn/CMakeLists.txt @@ -15,7 +15,7 @@ endif() add_library(${PROJECT_NAME} STATIC ${DAP_CHAIN_NET_SRV_VPN_SRCS} ${DAP_CHAIN_NET_SRV_VPN_HEADERS}) -target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_stream dap_chain dap_chain_crypto dap_chain_net dap_chain_net_srv) +target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_stream dap_stream_ch_chain_net_srv dap_chain dap_chain_crypto dap_chain_net dap_chain_net_srv) target_include_directories(${PROJECT_NAME} INTERFACE .) target_include_directories(${PROJECT_NAME} PUBLIC include) diff --git a/modules/service/vpn/dap_chain_net_srv_vpn.c b/modules/service/vpn/dap_chain_net_srv_vpn.c index 4a8f310518..b95b5479d4 100644 --- a/modules/service/vpn/dap_chain_net_srv_vpn.c +++ b/modules/service/vpn/dap_chain_net_srv_vpn.c @@ -63,14 +63,19 @@ #include "dap_chain_net.h" #include "dap_chain_net_srv.h" +#include "dap_chain_net_srv_client.h" #include "dap_chain_net_srv_vpn.h" +#include "dap_chain_net_srv_vpn_cdb.h" #include "dap_chain_net_srv_stream_session.h" #include "dap_chain_net_vpn_client.h" +#include "dap_chain_net_vpn_client_tun.h" #include "dap_chain_ledger.h" #include "dap_events.h" #define LOG_TAG "dap_chain_net_srv_vpn" +#define DAP_TUN_IN_WORKER + #define SF_MAX_EVENTS 256 typedef struct usage_client { @@ -143,7 +148,7 @@ static void s_tun_destroy(void); // Stream callbacks static void s_new(dap_stream_ch_t* ch, void* arg); static void srv_ch_vpn_delete(dap_stream_ch_t* ch, void* arg); -static void s_ch_packet_in(dap_stream_ch_t* ch, void* arg); +static void s_ch_packet_in(dap_stream_ch_t* ch, void* a_arg); static void s_ch_packet_out(dap_stream_ch_t* ch, void* arg); //static int srv_ch_sf_raw_write(uint8_t op_code, const void * data, size_t data_size); @@ -160,12 +165,21 @@ static void m_es_tun_delete(dap_events_socket_t * a_es, void * arg); static void m_es_tun_read(dap_events_socket_t * a_es, void * arg); static void m_es_tun_error(dap_events_socket_t * a_es, void * arg); +bool is_dap_tun_in_worker(void) +{ +#ifdef DAP_TUN_IN_WORKER + return true; +#else + return false; +#endif +} + //TODO: create .new_callback for event sockets int s_tun_event_stream_create() { static dap_events_socket_callbacks_t l_s_callbacks = { - .read_callback = m_es_tun_read, - .write_callback = NULL, + .read_callback = m_es_tun_read,// for server + .write_callback = NULL,// for client .error_callback = m_es_tun_error, .delete_callback = m_es_tun_delete }; @@ -180,6 +194,137 @@ int s_tun_event_stream_create() } #endif +static int s_callback_client_success(dap_chain_net_srv_t * a_srv, uint32_t a_usage_id, dap_chain_net_srv_client_t * a_srv_client, + const void * a_success, size_t a_success_size) +{ + if(!a_srv || !a_srv_client || !a_srv_client->ch || !a_success || a_success_size < sizeof(dap_stream_ch_chain_net_srv_pkt_success_t)) + return -1; + dap_stream_ch_chain_net_srv_pkt_success_t * l_success = (dap_stream_ch_chain_net_srv_pkt_success_t*) a_success; + + dap_chain_net_srv_stream_session_t * l_srv_session = + (dap_chain_net_srv_stream_session_t *) a_srv_client->ch->stream->session->_inheritor; + dap_chain_net_srv_vpn_t* l_srv_vpn = (dap_chain_net_srv_vpn_t*) a_srv->_inhertor; + //a_srv_client->ch-> + dap_chain_net_t * l_net = dap_chain_net_by_id(l_success->hdr.net_id); + dap_chain_net_srv_usage_t *l_usage = dap_chain_net_srv_usage_add(l_srv_session, l_net, a_srv); + if(!l_usage) + return -2; + + dap_chain_net_srv_ch_vpn_t * l_srv_ch_vpn = + (dap_chain_net_srv_ch_vpn_t*) a_srv_client->ch->stream->channel[DAP_CHAIN_NET_SRV_VPN_ID] ? + a_srv_client->ch->stream->channel[DAP_CHAIN_NET_SRV_VPN_ID]->internal : NULL; + if ( ! l_srv_ch_vpn ){ + log_it(L_ERROR, "No VPN service stream channel, its closed?"); + return -3; + } + l_srv_ch_vpn->usage_id = l_usage->id; + l_usage->is_active = true; + l_usage->is_free = true; + + dap_stream_ch_t *l_ch = dap_chain_net_vpn_client_get_stream_ch(); + + int remote_sock_id = 0;//l_vpn_pkt->header.sock_id; + ch_vpn_socket_proxy_t * sf_sock = NULL; + sf_sock = DAP_NEW_Z(ch_vpn_socket_proxy_t); + sf_sock->id = remote_sock_id; + sf_sock->sock = l_ch->stream->events_socket->socket; + sf_sock->ch = l_ch; + pthread_mutex_init(&sf_sock->mutex, NULL); + dap_chain_net_srv_ch_vpn_t *f = CH_VPN(a_srv_client->ch); + //pthread_mutex_lock(&s_sf_socks_mutex); + pthread_mutex_lock(&l_srv_ch_vpn->mutex); + HASH_ADD_INT(l_srv_ch_vpn->socks, id, sf_sock); + pthread_mutex_unlock(&l_srv_ch_vpn->mutex); + //HASH_ADD_INT(CH_VPN(a_srv_client->ch)->socks, id, sf_sock); + log_it(L_DEBUG, "Added %d sock_id with sock %d to the hash table", sf_sock->id, sf_sock->sock); + + //!!!//l_usage->receipt = ; + + /* + dap_chain_net_srv_stream_session_t * l_srv_session = DAP_CHAIN_NET_SRV_STREAM_SESSION( a_ch->stream->session ); + dap_chain_net_srv_ch_vpn_t *l_ch_vpn = CH_VPN(a_ch); + dap_chain_net_srv_usage_t * l_usage = dap_chain_net_srv_usage_find(l_srv_session, l_ch_vpn->usage_id); + if ( ! l_usage->is_active + */ + + if(l_ch) { // Is present in hash table such destination address + size_t l_ipv4_str_len = 0; //dap_strlen(a_ipv4_str); + ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1, sizeof(pkt_out->header) + l_ipv4_str_len); + + pkt_out->header.op_code = VPN_PACKET_OP_CODE_VPN_ADDR_REQUEST; + //pkt_out->header.sock_id = l_stream->stream->events_socket->socket; + //pkt_out->header.op_connect.addr_size = l_ipv4_str_len; //remoteAddrBA.length(); + //pkt_out->header.op_connect.port = a_port; + //memcpy(pkt_out->data, a_ipv4_str, l_ipv4_str_len); + sf_sock->pkt_out[sf_sock->pkt_out_size] = pkt_out; + sf_sock->pkt_out_size++; + + dap_stream_ch_pkt_write(l_ch, DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_DATA, pkt_out, + pkt_out->header.op_data.data_size + sizeof(pkt_out->header)); + dap_stream_ch_set_ready_to_write(l_ch, true); + //DAP_DELETE(pkt_out); + } + + + + + // usage is present, we've accepted packets + dap_stream_ch_set_ready_to_read( l_srv_ch_vpn->ch , true ); + return 0; +} + +static int callback_client_sign_request(dap_chain_net_srv_t * a_srv, uint32_t a_usage_id, dap_chain_net_srv_client_t * a_srv_client, + const void **a_receipt, size_t a_receipt_size) +{ + dap_chain_datum_tx_receipt_t *l_receipt = (dap_chain_datum_tx_receipt_t*)*a_receipt; + char *l_gdb_group = dap_strdup_printf("local.%s", DAP_CHAIN_NET_SRV_VPN_CDB_GDB_PREFIX); + char *l_wallet_name = dap_chain_global_db_gr_get(dap_strdup("wallet_name"), NULL, l_gdb_group); + + dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_name, dap_chain_wallet_get_path(g_config)); + if(l_wallet) { + dap_enc_key_t *l_enc_key = dap_chain_wallet_get_key(l_wallet, 0); + dap_chain_datum_tx_receipt_sign_add(&l_receipt, dap_chain_datum_tx_receipt_get_size(l_receipt), l_enc_key); + dap_chain_wallet_close(l_wallet); + *a_receipt = l_receipt; + } + DAP_DELETE(l_gdb_group); + DAP_DELETE(l_wallet_name); + return 0; +} + + +/* + * Client VPN init (after dap_chain_net_srv_vpn_init!) + */ +int dap_chain_net_srv_client_vpn_init(dap_config_t * g_config) { + dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_VPN_ID }; + dap_chain_net_srv_t *l_srv = dap_chain_net_srv_get(l_uid); + dap_chain_net_srv_vpn_t* l_srv_vpn = l_srv ? (dap_chain_net_srv_vpn_t*) l_srv->_inhertor : NULL; + // if vpn server disabled + if(!l_srv_vpn) { + l_srv_vpn = DAP_NEW_Z(dap_chain_net_srv_vpn_t); + if(l_srv) + l_srv->_inhertor = l_srv_vpn; + dap_stream_ch_proc_add(DAP_STREAM_CH_ID_NET_SRV_VPN, s_new, srv_ch_vpn_delete, s_ch_packet_in, s_ch_packet_out); + pthread_mutex_init(&s_sf_socks_mutex, NULL); + pthread_cond_init(&s_sf_socks_cond, NULL); + } + if(!dap_chain_net_srv_client_init(l_uid, s_callback_requested, + s_callback_response_success, s_callback_response_error, + s_callback_receipt_next_success, + s_callback_client_success, + callback_client_sign_request, + l_srv_vpn)) { + l_srv = dap_chain_net_srv_get(l_uid); + //l_srv_vpn = l_srv ? (dap_chain_net_srv_vpn_t*)l_srv->_inhertor : NULL; + //l_srv_vpn->parent = l_srv; + l_srv->_inhertor = l_srv_vpn; + } + l_srv_vpn->parent = (dap_chain_net_srv_t*) l_srv; + + return 0; +} + /** * @brief dap_stream_ch_vpn_init Init actions for VPN stream channel * @param vpn_addr Zero if only client mode. Address if the node shares its local VPN @@ -631,101 +776,6 @@ static ch_vpn_pkt_t* srv_ch_sf_raw_read() return ret; } -/** - * @brief stream_sf_packet_out Packet Out Ch callback - * @param ch - * @param arg - */ -static void s_ch_packet_out(dap_stream_ch_t* a_ch, void* a_arg) -{ - (void) a_arg; - ch_vpn_socket_proxy_t * cur, *tmp; - dap_chain_net_srv_stream_session_t * l_srv_session = DAP_CHAIN_NET_SRV_STREAM_SESSION( a_ch->stream->session ); - dap_chain_net_srv_ch_vpn_t *l_ch_vpn = CH_VPN(a_ch); - - dap_chain_net_srv_usage_t * l_usage = dap_chain_net_srv_usage_find(l_srv_session, l_ch_vpn->usage_id); - if ( ! l_usage){ - log_it(L_NOTICE, "No active usage in list, possible disconnected. Send nothin on this channel"); - dap_stream_ch_set_ready_to_write(a_ch,false); - dap_stream_ch_set_ready_to_read(a_ch,false); - return; - } - - if ( ! l_usage->is_active ){ - log_it(L_INFO, "Usage inactivation: switch off packet output channel"); - dap_stream_ch_set_ready_to_write(a_ch,false); - dap_stream_ch_set_ready_to_read(a_ch,false); - if (l_usage->clients) - dap_stream_ch_pkt_write( l_usage->clients->ch , DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_NOTIFY_STOPPED , NULL, 0 ); - return; - } - if ( (! l_usage->is_free) && (! l_usage->receipt) ){ - log_it(L_WARNING, "No active receipt, switching off"); - dap_stream_ch_set_ready_to_write(a_ch,false); - dap_stream_ch_set_ready_to_read(a_ch,false); - if (l_usage->clients) - dap_stream_ch_pkt_write( l_usage->clients->ch , DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_NOTIFY_STOPPED , NULL, 0 ); - return; - } - - bool l_is_smth_out = false; -// log_it(L_DEBUG,"Socket forwarding packet out callback: %u sockets in hashtable", HASH_COUNT(CH_SF(ch)->socks) ); - HASH_ITER(hh, l_ch_vpn->socks , cur, tmp) - { - bool l_signal_to_break = false; - pthread_mutex_lock(&(cur->mutex)); - size_t i; - //log_it(L_DEBUG, "Socket with id %d has %u packets in output buffer", cur->id, cur->pkt_out_size); - if(cur->pkt_out_size) { - for(i = 0; i < cur->pkt_out_size; i++) { - ch_vpn_pkt_t * pout = cur->pkt_out[i]; - if(pout) { - size_t l_wrote_size; - if((l_wrote_size = dap_stream_ch_pkt_write(a_ch, DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_DATA, pout, - pout->header.op_data.data_size + sizeof(pout->header)))>0 ) { - l_is_smth_out = true; - DAP_DELETE(pout); - cur->pkt_out[i] = NULL; - } else { - //log_it(L_WARNING, - // "Buffer is overflowed, breaking cycle to let the upper level cycle drop data to the output socket"); - l_is_smth_out = true; - l_signal_to_break = true; - break; - } - s_update_limits (a_ch, l_srv_session, l_usage,l_wrote_size ); - } - } - } - - if(l_signal_to_break) { - pthread_mutex_unlock(&(cur->mutex)); - break; - } - cur->pkt_out_size = 0; - if(cur->signal_to_delete) { - log_it(L_NOTICE, "Socket id %d got signal to be deleted", cur->id); - pthread_mutex_lock(&( CH_VPN(a_ch)->mutex)); - HASH_DEL(l_ch_vpn->socks, cur); - pthread_mutex_unlock(&( CH_VPN(a_ch)->mutex)); - - pthread_mutex_lock(&(s_sf_socks_mutex)); - HASH_DELETE(hh2, sf_socks, cur); - HASH_DELETE(hh_sock, sf_socks_client, cur); - pthread_mutex_unlock(&(s_sf_socks_mutex)); - - pthread_mutex_unlock(&(cur->mutex)); - s_ch_proxy_delete(cur); - } else - pthread_mutex_unlock(&(cur->mutex)); - } - if(l_is_smth_out) { - a_ch->stream->conn_http->state_write = DAP_HTTP_CLIENT_STATE_DATA; - } - - dap_stream_ch_set_ready_to_write(a_ch, l_is_smth_out); -} - /** * @brief s_check_limits * @param a_ch @@ -831,14 +881,27 @@ static void s_update_limits(dap_stream_ch_t * a_ch , } + +static void send_pong_pkt(dap_stream_ch_t* a_ch) +{ +// log_it(L_DEBUG,"---------------------------------- PONG!"); + ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1, sizeof(pkt_out->header)); + pkt_out->header.op_code = VPN_PACKET_OP_CODE_PONG; + + dap_stream_ch_pkt_write(a_ch, 'd', pkt_out, + pkt_out->header.op_data.data_size + sizeof(pkt_out->header)); + dap_stream_ch_set_ready_to_write(a_ch, true); + free(pkt_out); +} + /** * @brief stream_sf_packet_in * @param ch * @param arg */ -void s_ch_packet_in(dap_stream_ch_t* a_ch, void* arg) +void s_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) { - dap_stream_ch_pkt_t * pkt = (dap_stream_ch_pkt_t *) arg; + dap_stream_ch_pkt_t * l_pkt = (dap_stream_ch_pkt_t *) a_arg; dap_chain_net_srv_stream_session_t * l_srv_session = DAP_CHAIN_NET_SRV_STREAM_SESSION (a_ch->stream->session ); dap_chain_net_srv_ch_vpn_t *l_ch_vpn = CH_VPN(a_ch); dap_chain_net_srv_usage_t * l_usage = dap_chain_net_srv_usage_find(l_srv_session, l_ch_vpn->usage_id); @@ -860,18 +923,33 @@ void s_ch_packet_in(dap_stream_ch_t* a_ch, void* arg) // TODO move address leasing to this structure dap_chain_net_srv_vpn_t * l_srv_vpn =(dap_chain_net_srv_vpn_t *) l_usage->service->_inhertor; - if ( pkt->hdr.type == DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_CLIENT ) - dap_chain_net_vpn_client_pkt_in( a_ch, pkt); - else { + //if ( pkt->hdr.type == DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_CLIENT ) + // dap_chain_net_vpn_client_pkt_in( a_ch, l_pkt); + if(l_pkt->hdr.type == DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_DATA) { static bool client_connected = false; - ch_vpn_pkt_t * l_vpn_pkt = (ch_vpn_pkt_t *) pkt->data; - size_t l_vpn_pkt_size = pkt->hdr.size - sizeof (l_vpn_pkt->header); + ch_vpn_pkt_t * l_vpn_pkt = (ch_vpn_pkt_t *) l_pkt->data; + size_t l_vpn_pkt_size = l_pkt->hdr.size - sizeof (l_vpn_pkt->header); int remote_sock_id = l_vpn_pkt->header.sock_id; //log_it(L_DEBUG, "Got SF packet with id %d op_code 0x%02x", remote_sock_id, sf_pkt->header.op_code); if(l_vpn_pkt->header.op_code >= 0xb0) { // Raw packets switch (l_vpn_pkt->header.op_code) { + case VPN_PACKET_OP_CODE_PING: + a_ch->stream->events_socket->last_ping_request = time(NULL); + send_pong_pkt(a_ch); + break; + case VPN_PACKET_OP_CODE_PONG: + a_ch->stream->events_socket->last_ping_request = time(NULL); + break; + // for client + case VPN_PACKET_OP_CODE_VPN_ADDR_REPLY: { // Assigned address for peer + if(ch_sf_tun_addr_leased(CH_VPN(a_ch), l_vpn_pkt, l_vpn_pkt_size) < 0) { + log_it(L_ERROR, "Can't create tun"); + } + } + break; + // for server case VPN_PACKET_OP_CODE_VPN_ADDR_REQUEST: { // Client request after L3 connection the new IP address log_it(L_INFO, "Received address request "); if ( l_ch_vpn->addr_ipv4.s_addr ){ @@ -978,6 +1056,14 @@ void s_ch_packet_in(dap_stream_ch_t* a_ch, void* arg) } } break; + // for client only + case VPN_PACKET_OP_CODE_VPN_RECV:{ + a_ch->stream->events_socket->last_ping_request = time(NULL); // not ping, but better ;-) + ch_sf_tun_send(CH_VPN(a_ch), l_vpn_pkt->data, l_vpn_pkt->header.op_data.data_size); + } + break; + + // for servier only case VPN_PACKET_OP_CODE_VPN_SEND: { struct in_addr in_saddr, in_daddr; in_saddr.s_addr = ((struct iphdr*) l_vpn_pkt->data)->saddr; @@ -1070,7 +1156,7 @@ void s_ch_packet_in(dap_stream_ch_t* a_ch, void* arg) pthread_mutex_unlock(&sf_sock->mutex); } //log_it(L_INFO, "Send action from %d sock_id (sf_packet size %lu, ch packet size %lu, have sent %d)" - // , sf_sock->id, sf_pkt->header.op_data.data_size, pkt->hdr.size, ret); + // , sf_sock->id, sf_pkt->header.op_data.data_size, l_pkt->hdr.size, ret); } break; case VPN_PACKET_OP_CODE_DISCONNECT: { @@ -1192,6 +1278,101 @@ void s_ch_packet_in(dap_stream_ch_t* a_ch, void* arg) } } +/** + * @brief stream_sf_packet_out Packet Out Ch callback + * @param ch + * @param arg + */ +static void s_ch_packet_out(dap_stream_ch_t* a_ch, void* a_arg) +{ + (void) a_arg; + ch_vpn_socket_proxy_t * cur, *tmp; + dap_chain_net_srv_stream_session_t * l_srv_session = DAP_CHAIN_NET_SRV_STREAM_SESSION( a_ch->stream->session ); + dap_chain_net_srv_ch_vpn_t *l_ch_vpn = CH_VPN(a_ch); + + dap_chain_net_srv_usage_t * l_usage = dap_chain_net_srv_usage_find(l_srv_session, l_ch_vpn->usage_id); + if ( ! l_usage){ + log_it(L_NOTICE, "No active usage in list, possible disconnected. Send nothin on this channel"); + dap_stream_ch_set_ready_to_write(a_ch,false); + dap_stream_ch_set_ready_to_read(a_ch,false); + return; + } + + if ( ! l_usage->is_active ){ + log_it(L_INFO, "Usage inactivation: switch off packet output channel"); + dap_stream_ch_set_ready_to_write(a_ch,false); + dap_stream_ch_set_ready_to_read(a_ch,false); + if (l_usage->clients) + dap_stream_ch_pkt_write( l_usage->clients->ch , DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_NOTIFY_STOPPED , NULL, 0 ); + return; + } + if ( (! l_usage->is_free) && (! l_usage->receipt) ){ + log_it(L_WARNING, "No active receipt, switching off"); + dap_stream_ch_set_ready_to_write(a_ch,false); + dap_stream_ch_set_ready_to_read(a_ch,false); + if (l_usage->clients) + dap_stream_ch_pkt_write( l_usage->clients->ch , DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_NOTIFY_STOPPED , NULL, 0 ); + return; + } + + bool l_is_smth_out = false; +// log_it(L_DEBUG,"Socket forwarding packet out callback: %u sockets in hashtable", HASH_COUNT(CH_SF(ch)->socks) ); + HASH_ITER(hh, l_ch_vpn->socks , cur, tmp) + { + bool l_signal_to_break = false; + pthread_mutex_lock(&(cur->mutex)); + size_t i; + //log_it(L_DEBUG, "Socket with id %d has %u packets in output buffer", cur->id, cur->pkt_out_size); + if(cur->pkt_out_size) { + for(i = 0; i < cur->pkt_out_size; i++) { + ch_vpn_pkt_t * pout = cur->pkt_out[i]; + if(pout) { + size_t l_wrote_size; + if((l_wrote_size = dap_stream_ch_pkt_write(a_ch, DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_DATA, pout, + pout->header.op_data.data_size + sizeof(pout->header)))>0 ) { + l_is_smth_out = true; + DAP_DELETE(pout); + cur->pkt_out[i] = NULL; + } else { + log_it(L_WARNING, "Buffer is overflowed, breaking cycle to let the upper level cycle drop data to the output socket"); + l_is_smth_out = true; + l_signal_to_break = true; + break; + } + s_update_limits (a_ch, l_srv_session, l_usage,l_wrote_size ); + } + } + } + + if(l_signal_to_break) { + pthread_mutex_unlock(&(cur->mutex)); + break; + } + cur->pkt_out_size = 0; + if(cur->signal_to_delete) { + log_it(L_NOTICE, "Socket id %d got signal to be deleted", cur->id); + pthread_mutex_lock(&( CH_VPN(a_ch)->mutex)); + HASH_DEL(l_ch_vpn->socks, cur); + pthread_mutex_unlock(&( CH_VPN(a_ch)->mutex)); + + pthread_mutex_lock(&(s_sf_socks_mutex)); + HASH_DELETE(hh2, sf_socks, cur); + HASH_DELETE(hh_sock, sf_socks_client, cur); + pthread_mutex_unlock(&(s_sf_socks_mutex)); + + pthread_mutex_unlock(&(cur->mutex)); + s_ch_proxy_delete(cur); + } else + pthread_mutex_unlock(&(cur->mutex)); + } + if(l_is_smth_out) { + if(a_ch->stream->conn_http) + a_ch->stream->conn_http->state_write = DAP_HTTP_CLIENT_STATE_DATA; + } + + dap_stream_ch_set_ready_to_write(a_ch, l_is_smth_out); +} + /** * @brief stream_sf_disconnect * @param sf @@ -1452,6 +1633,11 @@ void m_es_tun_delete(dap_events_socket_t * a_es, void * arg) s_tun_destroy(); } +void m_es_tun_write(dap_events_socket_t * a_es, void * arg) +{ + +} + void m_es_tun_read(dap_events_socket_t * a_es, void * arg) { const static int tun_MTU = 100000; /// TODO Replace with detection of MTU size diff --git a/modules/service/vpn/dap_chain_net_srv_vpn_cdb.c b/modules/service/vpn/dap_chain_net_srv_vpn_cdb.c index 236f73f401..5fe3f20061 100644 --- a/modules/service/vpn/dap_chain_net_srv_vpn_cdb.c +++ b/modules/service/vpn/dap_chain_net_srv_vpn_cdb.c @@ -226,9 +226,9 @@ static int s_cli_vpn_cdb(int a_argc, char ** a_argv, void *arg_func, char **a_st dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "user", &l_user_str); - // Selected 'user' subcoummand + // Selected 'user' subcommand if ( l_user_str ){ - return dap_chain_net_srv_vpn_cdb_auth_cli_cmd(l_user_str,l_arg_index, a_argc, a_argv,a_str_reply); + return dap_chain_net_srv_vpn_cdb_auth_cli_cmd_user(l_user_str,l_arg_index, a_argc, a_argv,a_str_reply); } return l_ret; } diff --git a/modules/service/vpn/dap_chain_net_srv_vpn_cdb_auth.c b/modules/service/vpn/dap_chain_net_srv_vpn_cdb_auth.c index 06aef6a66f..9e1fa7b4a0 100644 --- a/modules/service/vpn/dap_chain_net_srv_vpn_cdb_auth.c +++ b/modules/service/vpn/dap_chain_net_srv_vpn_cdb_auth.c @@ -139,7 +139,7 @@ void dap_chain_net_srv_vpn_cdb_auth_set_callback(dap_enc_http_callback_t a_callb * @param a_password * @return */ -int dap_chain_net_srv_vpn_cdb_auth_check(const char * a_login, const char * a_password) +int dap_chain_net_srv_vpn_cdb_auth_check_login(const char * a_login, const char * a_password) { int l_ret; @@ -204,7 +204,7 @@ static int s_input_validation(const char * str) * @param a_str_reply * @return */ -int dap_chain_net_srv_vpn_cdb_auth_cli_cmd ( const char *a_user_str,int a_arg_index, int a_argc, char ** a_argv, char **a_str_reply) +int dap_chain_net_srv_vpn_cdb_auth_cli_cmd_user ( const char *a_user_str,int a_arg_index, int a_argc, char ** a_argv, char **a_str_reply) { int l_ret = 0; dap_string_t * l_ret_str = dap_string_new(""); @@ -319,7 +319,7 @@ int dap_chain_net_srv_vpn_cdb_auth_cli_cmd ( const char *a_user_str,int a_arg const char * l_password_str = NULL; dap_chain_node_cli_find_option_val(a_argv, a_arg_index, a_argc, "--password", &l_password_str); if ( l_login_str && l_password_str) { - int l_check = dap_chain_net_srv_vpn_cdb_auth_check (l_login_str, l_password_str); + int l_check = dap_chain_net_srv_vpn_cdb_auth_check_login (l_login_str, l_password_str); if ( l_check == 0){ dap_string_append_printf(l_ret_str,"OK: Passed password check for '%s'\n",l_login_str ); l_ret = 0; @@ -521,7 +521,7 @@ static void s_http_enc_proc(enc_http_delegate_t *a_delegate, void * a_arg) return; } - int l_login_result = dap_chain_net_srv_vpn_cdb_auth_check( l_login, l_password ); + int l_login_result = dap_chain_net_srv_vpn_cdb_auth_check_login( l_login, l_password ); switch (l_login_result) { case 0:{ size_t l_tmp_size; diff --git a/modules/service/vpn/dap_chain_net_srv_vpn_cdb_server_list.c b/modules/service/vpn/dap_chain_net_srv_vpn_cdb_server_list.c index e3c807118e..67f7e54c9b 100644 --- a/modules/service/vpn/dap_chain_net_srv_vpn_cdb_server_list.c +++ b/modules/service/vpn/dap_chain_net_srv_vpn_cdb_server_list.c @@ -156,7 +156,7 @@ static void s_http_simple_proc(dap_http_simple_t *a_http_simple, void *a_arg) dap_string_t *l_reply_str = dap_string_new("[\n"); - char *l_client_ip = a_http_simple->http->client->s_ip;//"77.222.110.44" + char *l_client_ip = a_http_simple->http->client->s_ip;//"134.209.97.195" 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 ); @@ -232,11 +232,22 @@ static void s_http_simple_proc(dap_http_simple_t *a_http_simple, void *a_arg) 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) { + 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]; - dap_chain_net_srv_order_t *l_order = l_orders_pos[k]; + 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 diff --git a/modules/service/vpn/dap_chain_net_vpn_client.c b/modules/service/vpn/dap_chain_net_vpn_client.c index 6ffa1cf15a..7a673697cd 100644 --- a/modules/service/vpn/dap_chain_net_vpn_client.c +++ b/modules/service/vpn/dap_chain_net_vpn_client.c @@ -26,6 +26,7 @@ #include <stdbool.h> #include <stdint.h> #include <stdio.h> +#include <time.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> @@ -42,19 +43,30 @@ #include "dap_chain_node_client.h" #include "dap_stream_ch_proc.h" +//#include "dap_stream_ch_chain_net_srv.h" +#include "dap_chain_common.h" +#include "dap_chain_mempool.h" #include "dap_chain_net_srv_vpn.h" +#include "dap_chain_net_srv_vpn_cdb.h" // for DAP_CHAIN_NET_SRV_VPN_CDB_GDB_PREFIX #include "dap_chain_net_vpn_client.h" #include "dap_stream_ch_pkt.h" +#include "dap_stream_ch_chain_net_srv.h" +//#include "dap_stream_ch_chain_net_srv.h" #include "dap_chain_net_vpn_client_tun.h" +//#include "dap_chain_net_vpn_client_data.h" -typedef enum dap_http_client_state { - DAP_HTTP_CLIENT_STATE_NONE = 0, - DAP_HTTP_CLIENT_STATE_START = 1, - DAP_HTTP_CLIENT_STATE_HEADERS = 2, - DAP_HTTP_CLIENT_STATE_DATA = 3 -} dap_http_client_state_t; +/* + #if !defined( dap_http_client_state_t ) + typedef enum dap_http_client_state { + DAP_HTTP_CLIENT_STATE_NONE = 0, + DAP_HTTP_CLIENT_STATE_START = 1, + DAP_HTTP_CLIENT_STATE_HEADERS = 2, + DAP_HTTP_CLIENT_STATE_DATA = 3 + } dap_http_client_state_t; + #endif + */ #define LOG_TAG "vpn_client" @@ -72,44 +84,223 @@ dap_stream_ch_t* dap_chain_net_vpn_client_get_stream_ch(void) { if(!s_vpn_client) return NULL; - dap_stream_ch_t *l_stream = dap_client_get_stream_ch(s_vpn_client->client, DAP_STREAM_CH_ID_NET_SRV_VPN ); + dap_stream_ch_t *l_stream = dap_client_get_stream_ch(s_vpn_client->client, DAP_STREAM_CH_ID_NET_SRV_VPN); return l_stream; } - - /// TODO convert below callback to processor of stage /* -void s_stage_callback() + void s_stage_callback() + { + char* l_full_path = NULL; + const char * l_path = "stream"; + const char *l_suburl = "globaldb"; + int l_full_path_size = snprintf(l_full_path, 0, "%s/%s?session_id=%s", DAP_UPLINK_PATH_STREAM, l_suburl, + dap_client_get_stream_id(a_client_pvt->client)); + l_full_path = DAP_NEW_Z_SIZE(char, l_full_path_size + 1); + snprintf(l_full_path, l_full_path_size + 1, "%s/%s?session_id=%s", DAP_UPLINK_PATH_STREAM, l_suburl, + dap_client_get_stream_id(a_client_pvt->client)); + + //dap_client_request(a_client_pvt->client, l_full_path, "12345", 0, m_stream_response, m_stream_error); + + const char *l_add_str = ""; + // if connect to vpn server + const char l_active_vpn_channels[] = { VPN_CLIENT_ID, 0 }; + if(!dap_strcmp(a_client_pvt->active_channels, l_active_vpn_channels)) + l_add_str = "\r\nService-Key: test"; + + { + char *l_message = dap_strdup_printf("GET /%s HTTP/1.1\r\nHost: %s:%d%s\r\n\r\n", + l_full_path, a_client_pvt->uplink_addr, a_client_pvt->uplink_port, l_add_str); + size_t l_message_size = dap_strlen(l_message); + int count = send(a_client_pvt->stream_socket, l_message, l_message_size, 0); + DAP_DELETE(l_message); + } + DAP_DELETE(l_full_path); + + }*/ + +/** + * Get tx_cond_hash + * + * return: 0 Ok, 1 Already started, <0 Error + */ +static dap_chain_hash_fast_t* dap_chain_net_vpn_client_tx_cond_hash(dap_chain_net_t *a_net, + dap_chain_wallet_t *a_wallet, const char *a_token_ticker, uint64_t a_value_datoshi) { - char* l_full_path = NULL; - const char * l_path = "stream"; - const char *l_suburl = "globaldb"; - int l_full_path_size = snprintf(l_full_path, 0, "%s/%s?session_id=%s", DAP_UPLINK_PATH_STREAM, l_suburl, - dap_client_get_stream_id(a_client_pvt->client)); - l_full_path = DAP_NEW_Z_SIZE(char, l_full_path_size + 1); - snprintf(l_full_path, l_full_path_size + 1, "%s/%s?session_id=%s", DAP_UPLINK_PATH_STREAM, l_suburl, - dap_client_get_stream_id(a_client_pvt->client)); - - //dap_client_request(a_client_pvt->client, l_full_path, "12345", 0, m_stream_response, m_stream_error); - - const char *l_add_str = ""; - // if connect to vpn server - const char l_active_vpn_channels[] = { VPN_CLIENT_ID, 0 }; - if(!dap_strcmp(a_client_pvt->active_channels, l_active_vpn_channels)) - l_add_str = "\r\nService-Key: test"; + uint8_t *l_pkey_b64 = NULL; + size_t l_pkey_b64_size = 0; + + // Try to load from gdb + size_t l_gdb_group_size = 0; + char *l_gdb_group = dap_strdup_printf("local.%s", DAP_CHAIN_NET_SRV_VPN_CDB_GDB_PREFIX); + dap_chain_hash_fast_t *l_tx_cond_hash = (dap_chain_hash_fast_t*) dap_chain_global_db_gr_get( + dap_strdup("client_tx_cond_hash"), &l_gdb_group_size, l_gdb_group); + + time_t l_tx_cond_ts = 0; + // Check for entry size + if(l_tx_cond_hash && 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)); + l_tx_cond_hash = NULL; + } + // 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", a_net); + dap_chain_datum_tx_t *l_tx = dap_chain_net_get_tx_by_hash(a_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(a_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); + } + } + } + if(l_tx_cond_hash) + return l_tx_cond_hash; + + //l_pkey_b64 = (char*) dap_chain_global_db_gr_get(dap_strdup("client_pkey"), &l_gdb_group_size, l_gdb_group); + dap_enc_key_t *l_enc_key = NULL; + if(a_wallet) { + l_enc_key = dap_chain_wallet_get_key(a_wallet, 0); + } + // use default pkey + else { - { - char *l_message = dap_strdup_printf("GET /%s HTTP/1.1\r\nHost: %s:%d%s\r\n\r\n", - l_full_path, a_client_pvt->uplink_addr, a_client_pvt->uplink_port, l_add_str); - size_t l_message_size = dap_strlen(l_message); - int count = send(a_client_pvt->stream_socket, l_message, l_message_size, 0); - DAP_DELETE(l_message); } - DAP_DELETE(l_full_path); + /* + // generate new pub key + if(!l_pkey_b64){ + //if(!l_pub_key_data || !l_pub_key_data_size){ + char *l_certs_name_str = dap_strdup_printf("client.%s", DAP_CHAIN_NET_SRV_VPN_CDB_GDB_PREFIX); + dap_cert_t ** l_certs = NULL; + size_t l_certs_size = 0; + dap_cert_t * l_cert = NULL; + // Load certs or create if not found + if(!dap_cert_parse_str_list(l_certs_name_str, &l_certs, &l_certs_size)) { // Load certs + const char *l_cert_folder = dap_cert_get_folder(0); + // create new cert + if(l_cert_folder) { + char *l_cert_path = dap_strdup_printf("%s/%s.dcert", l_cert_folder, l_certs_name_str); + l_cert = dap_cert_generate(l_certs_name_str, l_cert_path, DAP_ENC_KEY_TYPE_SIG_DILITHIUM); + DAP_DELETE(l_cert_path); + } + } + if(l_certs_size > 0) + l_cert = l_certs[0]; + if(l_cert) { + size_t l_pub_key_data_size = 0; + uint8_t *l_pub_key_data = dap_enc_key_serealize_pub_key(l_cert->enc_key, &l_pub_key_data_size); + // save pub key + if(l_pub_key_data && l_pub_key_data_size > 0){ + if(dap_chain_global_db_gr_set(dap_strdup("client_pkey"), l_pub_key_data, l_pub_key_data_size, + l_gdb_group)){ + l_pkey_b64 = l_pub_key_data; + l_pkey_b64_size = l_pub_key_data_size; + } + else + DAP_DELETE(l_pub_key_data); + } + } + DAP_DELETE(l_certs_name_str); + }*/ + + if(!l_enc_key) + return NULL; + + // Try to create condition + if(!l_tx_cond_hash) { + dap_chain_wallet_t *l_wallet_from = a_wallet; + log_it(L_DEBUG, "Create tx from wallet %s", l_wallet_from->name); + dap_enc_key_t *l_key_from = l_enc_key; //dap_chain_wallet_get_key(l_wallet_from, 0); + dap_enc_key_t *l_client_key = l_enc_key; + //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; + + size_t l_pub_key_data_size = 0; + uint8_t *l_pub_key_data = dap_enc_key_serealize_pub_key(l_enc_key, &l_pub_key_data_size); + // where to take coins for service + dap_chain_addr_t *l_addr_from = dap_chain_wallet_get_addr(l_wallet_from, a_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(a_net, l_key_from, l_client_key, l_addr_from, + a_token_ticker, a_value_datoshi, 0, l_price_unit, l_srv_uid, 0, l_pub_key_data, l_pub_key_data_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("client_tx_cond_hash", l_tx_cond_hash, sizeof(dap_chain_hash_fast_t), + l_gdb_group); + } + //DAP_DELETE(l_addr_from_str); + DAP_DELETE(l_pub_key_data); + } + DAP_DELETE(l_tx_cond_hash); + dap_enc_key_delete(l_enc_key); + DAP_DELETE(l_gdb_group); + return l_tx_cond_hash; +} + +/** + * Init VPN client + * + * return: 0 Ok, 1 Ok, <0 Error + */ + +int dap_chain_net_vpn_client_update(dap_chain_net_t *a_net, const char *a_wallet_name, const char *a_str_token, + uint64_t a_value_datoshi) +{ + dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(a_wallet_name, dap_chain_wallet_get_path(g_config)); + if(!l_wallet) { + return -1; + } + size_t l_gdb_group_size = 0; + char *l_gdb_group = dap_strdup_printf("local.%s", DAP_CHAIN_NET_SRV_VPN_CDB_GDB_PREFIX); + if(!dap_chain_global_db_gr_set(dap_strdup("wallet_name"), (void*) a_wallet_name, dap_strlen(a_wallet_name) + 1, + l_gdb_group)) + return -2; + if(!dap_chain_global_db_gr_set(dap_strdup("token_name"), (void*) a_str_token, dap_strlen(a_str_token) + 1, + l_gdb_group)) + return -2; + if(!dap_chain_global_db_gr_set(dap_strdup("value_datoshi"), &a_value_datoshi, sizeof(a_value_datoshi), l_gdb_group)) + return -2; + DAP_DELETE(l_gdb_group); + dap_chain_hash_fast_t *l_hash = dap_chain_net_vpn_client_tx_cond_hash(a_net, l_wallet, a_str_token, + a_value_datoshi); + dap_chain_wallet_close(l_wallet); + if(!l_hash) + return -3; + DAP_DELETE(l_hash); + return 0; +} -}*/ +/** + * Init VPN client + * + * return: 0 Ok, 1 Ok, <0 Error + */ +int dap_chain_net_vpn_client_get_wallet_info(dap_chain_net_t *a_net, char **a_wallet_name, char **a_str_token, + uint64_t *a_value_datoshi) +{ + size_t l_gdb_group_size = 0; + char *l_gdb_group = dap_strdup_printf("local.%s", DAP_CHAIN_NET_SRV_VPN_CDB_GDB_PREFIX); + if(a_wallet_name) + *a_wallet_name = (char*) dap_chain_global_db_gr_get("wallet_name", NULL, l_gdb_group); + if(a_str_token) + *a_str_token = (char*) dap_chain_global_db_gr_get("token_name", NULL, l_gdb_group); + if(a_value_datoshi) { + uint64_t *l_value_datoshi = (uint64_t*) dap_chain_global_db_gr_get("value_datoshi", NULL, l_gdb_group); + *a_value_datoshi = l_value_datoshi ? *l_value_datoshi : 0; + DAP_DELETE(l_value_datoshi); + } + return 0; +} /** * Start VPN client @@ -121,29 +312,17 @@ int dap_chain_net_vpn_client_start(dap_chain_net_t *a_net, const char *a_ipv4_st int l_ret = 0; if(!a_ipv4_str) // && !a_ipv6_str) return -1; - /* - dap_client_t *l_client = DAP_NEW_Z(dap_client_t); - dap_events_t *l_events = NULL; //dap_events_new(); - l_client = dap_client_new(l_events, s_stage_status_callback, s_stage_status_error_callback); - char l_channels[2] = { VPN_CLIENT_ID, 0 }; - dap_client_set_active_channels(l_client, l_channels); - dap_client_set_uplink(l_client, strdup(a_ip_v4), a_port); - dap_client_go_stage(l_client, STAGE_STREAM_STREAMING, s_stage_connected_callback); - */ - if(!s_node_info) s_node_info = DAP_NEW_Z(dap_chain_node_info_t); s_node_info->hdr.ext_port = a_port; dap_client_stage_t l_stage_target = STAGE_STREAM_STREAMING; //DAP_CLIENT_STAGE_STREAM_CTL;//STAGE_STREAM_STREAMING; - const char l_active_channels[] = { DAP_STREAM_CH_ID_NET_SRV_VPN , 0 }; + const char l_active_channels[] = { dap_stream_ch_chain_net_srv_get_id(), DAP_STREAM_CH_ID_NET_SRV_VPN, 0 }; //R, S if(a_ipv4_str) inet_pton(AF_INET, a_ipv4_str, &(s_node_info->hdr.ext_addr_v4)); if(a_ipv6_str) inet_pton(AF_INET6, a_ipv6_str, &(s_node_info->hdr.ext_addr_v6)); - - s_vpn_client = dap_chain_client_connect(s_node_info, l_stage_target, l_active_channels); if(!s_vpn_client) { log_it(L_ERROR, "Can't connect to VPN server=%s:%d", a_ipv4_str, a_port); @@ -154,7 +333,7 @@ int dap_chain_net_vpn_client_start(dap_chain_net_t *a_net, const char *a_ipv4_st return -2; } // wait connected - int timeout_ms = 500000; //5 sec = 5000 ms + int timeout_ms = 5000; //5 sec = 5000 ms int res = dap_chain_node_client_wait(s_vpn_client, NODE_CLIENT_STATE_CONNECTED, timeout_ms); if(res) { log_it(L_ERROR, "No response from VPN server=%s:%d", a_ipv4_str, a_port); @@ -168,77 +347,36 @@ int dap_chain_net_vpn_client_start(dap_chain_net_t *a_net, const char *a_ipv4_st l_ret = dap_chain_net_vpn_client_tun_init(a_ipv4_str); // send first packet to server -// if(0) { - dap_stream_ch_t *l_ch = dap_chain_net_vpn_client_get_stream_ch(); - if(l_ch) { // Is present in hash table such destination address - size_t l_ipv4_str_len = 0; //dap_strlen(a_ipv4_str); - ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1, sizeof(pkt_out->header) + l_ipv4_str_len); - - pkt_out->header.op_code = VPN_PACKET_OP_CODE_VPN_ADDR_REQUEST; - //pkt_out->header.sock_id = l_stream->stream->events_socket->socket; - //pkt_out->header.op_connect.addr_size = l_ipv4_str_len; //remoteAddrBA.length(); - //pkt_out->header.op_connect.port = a_port; - //memcpy(pkt_out->data, a_ipv4_str, l_ipv4_str_len); - dap_stream_ch_pkt_write(l_ch, DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_DATA, pkt_out, - pkt_out->header.op_data.data_size + sizeof(pkt_out->header)); + uint8_t l_ch_id = dap_stream_ch_chain_net_srv_get_id(); // Channel id for chain net request = 'R' + dap_stream_ch_t *l_ch = dap_client_get_stream_ch(s_vpn_client->client, l_ch_id); + if(l_ch) { + dap_stream_ch_chain_net_srv_pkt_request_t l_request; + memset(&l_request, 0, sizeof(dap_stream_ch_chain_net_srv_pkt_request_t)); + l_request.hdr.net_id.uint64 = a_net->pub.id.uint64; + l_request.hdr.srv_uid.uint64 = DAP_CHAIN_NET_SRV_VPN_ID; + dap_chain_hash_fast_t *l_tx_cond = dap_chain_net_vpn_client_tx_cond_hash(a_net, NULL, NULL, 0); + if(l_tx_cond) { + memcpy(&l_request.hdr.tx_cond, l_tx_cond, sizeof(dap_chain_hash_fast_t)); + DAP_DELETE(l_tx_cond); + } + // set srv id + dap_stream_ch_chain_net_srv_set_srv_uid(l_ch, l_request.hdr.srv_uid); + //dap_chain_hash_fast_t l_request + //.hdr.tx_cond = a_txCond.value(); +// strncpy(l_request->hdr.token, a_token.toLatin1().constData(),sizeof (l_request->hdr.token)-1); + dap_stream_ch_pkt_write(l_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_REQUEST, &l_request, sizeof(l_request)); dap_stream_ch_set_ready_to_write(l_ch, true); - DAP_DELETE(pkt_out); } } - /* dap_stream_ch_t *l_stream = dap_client_get_stream_ch(s_vpn_client->client, VPN_CLIENT_ID);//dap_stream_ch_chain_get_id()); - size_t l_res = dap_stream_ch_chain_pkt_write(l_stream, - VPN_PACKET_OP_CODE_CONNECT, a_net->pub.id, (dap_chain_id_t ) { { 0 } }, - a_net->pub.cell_id, NULL, 0);*/ - - //return l_ret; - // send connect packet to server - /* { - dap_stream_ch_t *l_stream = dap_chain_net_vpn_client_get_stream(); - if(l_stream) { // Is present in hash table such destination address - size_t l_ipv4_str_len = dap_strlen(a_ipv4_str); - ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1, sizeof(pkt_out->header) + l_ipv4_str_len); - - pkt_out->header.op_code = VPN_PACKET_OP_CODE_CONNECT; - pkt_out->header.sock_id = l_stream->stream->events_socket->socket; - pkt_out->header.op_connect.addr_size = l_ipv4_str_len; //remoteAddrBA.length(); - pkt_out->header.op_connect.port = a_port; - memcpy(pkt_out->data, a_ipv4_str, l_ipv4_str_len); - - // pkt_out->header.op_code = VPN_PACKET_OP_CODE_VPN_RECV; - // pkt_out->header.sock_id = 123; - // pkt_out->header.op_data.data_size = 0; - //memcpy(pkt_out->data, 0, 0); - dap_stream_ch_pkt_write(l_stream, DATA_CHANNEL_ID, pkt_out, - pkt_out->header.op_data.data_size + sizeof(pkt_out->header)); - dap_stream_ch_set_ready_to_write(l_stream, true); - DAP_DELETE(pkt_out); - } - }*/ - - //l_ret = dap_chain_net_vpn_client_tun_init(a_ipv4_str); - /* { - dap_stream_ch_t *l_stream = dap_chain_net_vpn_client_get_stream(); - if(l_stream) { // Is present in hash table such destination address - ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1, sizeof(pkt_out->header) + 0); - pkt_out->header.op_code = VPN_PACKET_OP_CODE_VPN_RECV; - pkt_out->header.sock_id = 123; - pkt_out->header.op_data.data_size = 0; - //memcpy(pkt_out->data, 0, 0); - dap_stream_ch_pkt_write(l_stream, DATA_CHANNEL_ID, pkt_out, - pkt_out->header.op_data.data_size + sizeof(pkt_out->header)); - dap_stream_ch_set_ready_to_write(l_stream, true); - } - }*/ - return l_ret; } int dap_chain_net_vpn_client_stop(void) { // delete connection with VPN server - if(!s_vpn_client) { + if(s_vpn_client) { dap_chain_node_client_close(s_vpn_client); s_vpn_client = NULL; } @@ -249,12 +387,20 @@ int dap_chain_net_vpn_client_stop(void) return l_ret; } -int dap_chain_net_vpn_client_status(void) +dap_chain_net_vpn_client_status_t dap_chain_net_vpn_client_status(void) { + if(s_vpn_client) { + uint8_t l_ch_id = dap_stream_ch_chain_net_srv_get_id(); // Channel id for chain net request = 'R' + dap_stream_ch_t *l_ch = dap_client_get_stream_ch(s_vpn_client->client, l_ch_id); + if(!l_ch) + return VPN_CLIENT_STATUS_CONN_LOST; + } + else + return VPN_CLIENT_STATUS_NOT_STARTED; if(!dap_chain_net_vpn_client_tun_status()) // VPN client started - return 1; - return 0; + return VPN_CLIENT_STATUS_STARTED; + return VPN_CLIENT_STATUS_STOPPED; } static void vpn_socket_delete(ch_vpn_socket_proxy_t * sf) @@ -265,18 +411,6 @@ static void vpn_socket_delete(ch_vpn_socket_proxy_t * sf) free(sf); } -static void send_pong_pkt(dap_stream_ch_t* a_ch) -{ -// log_it(L_DEBUG,"---------------------------------- PONG!"); - ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1, sizeof(pkt_out->header)); - pkt_out->header.op_code = VPN_PACKET_OP_CODE_PONG; - - dap_stream_ch_pkt_write(a_ch, 'd', pkt_out, - pkt_out->header.op_data.data_size + sizeof(pkt_out->header)); - dap_stream_ch_set_ready_to_write(a_ch, true); - free(pkt_out); -} - /** * @brief dap_chain_net_vpn_client_pkt_in * @param a_ch @@ -301,30 +435,32 @@ void dap_chain_net_vpn_client_pkt_in(dap_stream_ch_t* a_ch, dap_stream_ch_pkt_t* // ,remote_sock_id, l_sf_pkt->header.op_code, l_sf_pkt_data_size ); if(l_sf_pkt->header.op_code >= 0xb0) { // Raw packets switch (l_sf_pkt->header.op_code) { - case VPN_PACKET_OP_CODE_VPN_ADDR_REPLY: { // Assigned address for peer - if(ch_sf_tun_addr_leased(CH_VPN(a_ch), l_sf_pkt, l_sf_pkt_data_size) < 0) { - log_it(L_WARNING, "Can't create tun"); - } - } - break; - case VPN_PACKET_OP_CODE_VPN_ADDR_REQUEST: // Client request after L3 connection the new IP address - log_it(L_WARNING, "Got VPN_PACKET_OP_CODE_VPN_ADDR_REQUEST packet with id %d, it's very strange' ", - remote_sock_id); - break; - case VPN_PACKET_OP_CODE_VPN_SEND: - log_it(L_WARNING, "Got VPN_PACKET_OP_CODE_VPN_SEND packet with id %d, it's very strange' ", remote_sock_id); - - case VPN_PACKET_OP_CODE_VPN_RECV: - a_ch->stream->events_socket->last_ping_request = time(NULL); // not ping, but better ;-) - ch_sf_tun_send(CH_VPN(a_ch), l_sf_pkt->data, l_sf_pkt->header.op_data.data_size); - break; - case VPN_PACKET_OP_CODE_PING: - a_ch->stream->events_socket->last_ping_request = time(NULL); - send_pong_pkt(a_ch); - break; - case VPN_PACKET_OP_CODE_PONG: - a_ch->stream->events_socket->last_ping_request = time(NULL); - break; + /* case VPN_PACKET_OP_CODE_VPN_ADDR_REPLY: { // Assigned address for peer + if(ch_sf_tun_addr_leased(CH_VPN(a_ch), l_sf_pkt, l_sf_pkt_data_size) < 0) { + log_it(L_WARNING, "Can't create tun"); + } + } + break; + case VPN_PACKET_OP_CODE_VPN_ADDR_REQUEST: // Client request after L3 connection the new IP address + log_it(L_WARNING, "Got VPN_PACKET_OP_CODE_VPN_ADDR_REQUEST packet with id %d, it's very strange' ", + remote_sock_id); + break; + case VPN_PACKET_OP_CODE_VPN_SEND: + log_it(L_WARNING, "Got VPN_PACKET_OP_CODE_VPN_SEND packet with id %d, it's very strange' ", remote_sock_id); + + case VPN_PACKET_OP_CODE_VPN_RECV: + a_ch->stream->events_socket->last_ping_request = time(NULL); // not ping, but better ;-) + ch_sf_tun_send(CH_VPN(a_ch), l_sf_pkt->data, l_sf_pkt->header.op_data.data_size); + break;*/ + /* + case VPN_PACKET_OP_CODE_PING: + a_ch->stream->events_socket->last_ping_request = time(NULL); + send_pong_pkt(a_ch); + break; + case VPN_PACKET_OP_CODE_PONG: + a_ch->stream->events_socket->last_ping_request = time(NULL); + break; + */ default: log_it(L_WARNING, "Can't process SF type 0x%02x", l_sf_pkt->header.op_code); } @@ -540,7 +676,8 @@ void dap_chain_net_vpn_client_pkt_out(dap_stream_ch_t* a_ch) for(i = 0; i < l_cur->pkt_out_size; i++) { ch_vpn_pkt_t * pout = l_cur->pkt_out[i]; if(pout) { - if(dap_stream_ch_pkt_write(a_ch, DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_DATA, pout, pout->header.op_data.data_size + sizeof(pout->header))) { + if(dap_stream_ch_pkt_write(a_ch, DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_DATA, pout, + pout->header.op_data.data_size + sizeof(pout->header))) { l_is_smth_out = true; if(pout) free(pout); @@ -587,8 +724,7 @@ void dap_chain_net_vpn_client_pkt_out(dap_stream_ch_t* a_ch) int dap_chain_net_vpn_client_init(dap_config_t * g_config) { pthread_mutex_init(&sf_socks_mutex, NULL); - - return 0; + return dap_chain_net_srv_client_vpn_init(g_config); } void dap_chain_net_vpn_client_deinit() diff --git a/modules/service/vpn/dap_chain_net_vpn_client_tun.c b/modules/service/vpn/dap_chain_net_vpn_client_tun.c index ef786d30f0..cde51a3266 100644 --- a/modules/service/vpn/dap_chain_net_vpn_client_tun.c +++ b/modules/service/vpn/dap_chain_net_vpn_client_tun.c @@ -73,6 +73,7 @@ static char *s_last_used_connection_name = NULL, *s_last_used_connection_device static pthread_t s_thread_read_tun_id; static pthread_mutex_t s_clients_mutex; +static dap_events_socket_t * s_tun_events_socket = NULL; //list_addr_element * list_addr_head = NULL; //ch_sf_tun_server_t * m_tun_server = NULL; @@ -146,13 +147,20 @@ static char* get_def_gateway(void) * * return: connection name or NULL */ -static char* get_connection(const char *a_conn_name) +static char* get_connection(const char *a_conn_name, char **a_connection_dev) { if(!a_conn_name) return NULL; + // NAME UUID TYPE DEVICE + //nodeVPNClient a2b4cbc4-b8d2-4dd9-ac7f-81d9bf6fa276 tun -- char *l_cmd = dap_strdup_printf("nmcli connection show | grep %s | awk '{print $1}'", a_conn_name); char* l_connection_name = run_bash_cmd(l_cmd); DAP_DELETE(l_cmd); + if(a_connection_dev) { + l_cmd = dap_strdup_printf("nmcli connection show | grep %s | awk '{print $4}'", a_conn_name); + *a_connection_dev = run_bash_cmd(l_cmd); + DAP_DELETE(l_cmd); + } return l_connection_name; } @@ -363,6 +371,71 @@ int dap_chain_net_vpn_client_tun_init(const char *a_ipv4_server_str) return 0; } + +static void m_client_tun_delete(dap_events_socket_t * a_es, void * arg) +{ + log_it(L_DEBUG, __PRETTY_FUNCTION__); + //dap_chain_net_vpn_client_tun_delete(); + log_it(L_NOTICE, "Raw sockets listen thread is stopped"); +} + +static void m_client_tun_write(dap_events_socket_t * a_es, void * arg) +{ +// log_it(L_WARNING, __PRETTY_FUNCTION__); +} + +static void m_client_tun_read(dap_events_socket_t * a_es, void * arg) +{ + const static int tun_MTU = 100000; /// TODO Replace with detection of MTU size + uint8_t l_tmp_buf[tun_MTU]; + + size_t l_read_ret; + log_it(L_WARNING, __PRETTY_FUNCTION__); + + do{ + l_read_ret = dap_events_socket_read(a_es, l_tmp_buf, sizeof(l_tmp_buf)); + + if(l_read_ret > 0) { + struct iphdr *iph = (struct iphdr*) l_tmp_buf; + struct in_addr in_daddr, in_saddr; + in_daddr.s_addr = iph->daddr; + in_saddr.s_addr = iph->saddr; + char str_daddr[42], str_saddr[42]; + dap_snprintf(str_saddr, sizeof(str_saddr), "%s",inet_ntoa(in_saddr) ); + dap_snprintf(str_daddr, sizeof(str_daddr), "%s",inet_ntoa(in_daddr) ); + + dap_stream_ch_t *l_stream = dap_chain_net_vpn_client_get_stream_ch(); + if(l_stream) { + // form packet to vpn-server + ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1, sizeof(pkt_out->header) + l_read_ret); + pkt_out->header.op_code = VPN_PACKET_OP_CODE_VPN_SEND; //VPN_PACKET_OP_CODE_VPN_RECV + pkt_out->header.sock_id = s_fd_tun; + pkt_out->header.op_data.data_size = l_read_ret; + memcpy(pkt_out->data, l_tmp_buf, l_read_ret); + + pthread_mutex_lock(&s_clients_mutex); + // sent packet to vpn server + dap_stream_ch_pkt_write(l_stream, DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_DATA, pkt_out, + pkt_out->header.op_data.data_size + sizeof(pkt_out->header)); + dap_stream_ch_set_ready_to_write(l_stream, true); + pthread_mutex_unlock(&s_clients_mutex); + + DAP_DELETE(pkt_out); + } + else { + log_it(L_DEBUG, "No remote client for income IP packet with addr %s", inet_ntoa(in_daddr)); + } + } + }while(l_read_ret > 0); + + dap_events_socket_set_readable(a_es, true); +} + +static void m_client_tun_error(dap_events_socket_t * a_es, void * arg) +{ + log_it(L_DEBUG, __PRETTY_FUNCTION__); +} + int dap_chain_net_vpn_client_tun_create(const char *a_ipv4_addr_str, const char *a_ipv4_gw_str) { // char dev[IFNAMSIZ] = { 0 }; @@ -382,9 +455,11 @@ int dap_chain_net_vpn_client_tun_create(const char *a_ipv4_addr_str, const char char *l_cmd_del_gw = dap_strdup_printf("ip route del default via %s", s_cur_gw); char *l_cmd_ret = run_bash_cmd(l_cmd_del_gw); DAP_DELETE(l_cmd_del_gw); - if(!l_cmd_del_gw) { - log_it(L_ERROR, "Can't delete dafault gateway %s)", s_cur_gw); - DAP_DELETE(s_cur_gw); + // check gateway + char *s_cur_gw_tmp = get_def_gateway(); + if(s_cur_gw_tmp) { + log_it(L_ERROR, "Can't delete default gateway %s)", s_cur_gw); + DAP_DELETE(s_cur_gw_tmp); return -3; } DAP_DELETE(l_cmd_ret); @@ -397,8 +472,7 @@ int dap_chain_net_vpn_client_tun_create(const char *a_ipv4_addr_str, const char disableIPV6(s_last_used_connection_device); // add new default gateway for vpn-server address - if(!is_local_address(s_cur_ipv4_server)) - { + if(!is_local_address(s_cur_ipv4_server)) { // This route don't need if address is local char *l_str_cmd = dap_strdup_printf("route add -host %s gw %s metric 10", s_cur_ipv4_server, s_cur_gw); char *l_cmd_ret = run_bash_cmd(l_str_cmd); @@ -407,7 +481,7 @@ int dap_chain_net_vpn_client_tun_create(const char *a_ipv4_addr_str, const char } // check and delete present connection - char *l_conn_present = get_connection(s_conn_name); + char *l_conn_present = get_connection(s_conn_name, NULL); if(!dap_strcmp(l_conn_present, s_conn_name)) { char *l_str_cmd = dap_strdup_printf("nmcli c delete %s", s_conn_name); exe_bash_cmd(l_str_cmd); @@ -422,7 +496,7 @@ int dap_chain_net_vpn_client_tun_create(const char *a_ipv4_addr_str, const char "nmcli connection add type tun con-name %s autoconnect false ifname %s mode tun ip4 %s gw4 %s", s_conn_name, s_dev, a_ipv4_addr_str, a_ipv4_gw_str); char *l_cmd_ret = run_bash_cmd(l_cmd_add_con); - l_conn_present = get_connection(s_conn_name); + l_conn_present = get_connection(s_conn_name, NULL); if(dap_strcmp(l_conn_present, s_conn_name)) l_ret = -1; DAP_DELETE(l_cmd_ret); @@ -468,7 +542,28 @@ int dap_chain_net_vpn_client_tun_create(const char *a_ipv4_addr_str, const char } pthread_mutex_init(&s_clients_mutex, NULL); - pthread_create(&s_thread_read_tun_id, NULL, thread_read_tun, NULL); + + if(is_dap_tun_in_worker()) { + + static dap_events_socket_callbacks_t l_s_callbacks = { + .read_callback = m_client_tun_read,// for server + .write_callback = m_client_tun_write,// for client + .error_callback = m_client_tun_error, + .delete_callback = m_client_tun_delete + }; + + s_tun_events_socket = dap_events_socket_wrap_no_add(NULL, s_fd_tun, &l_s_callbacks); + s_tun_events_socket->type = DESCRIPTOR_TYPE_FILE; + dap_events_socket_create_after(s_tun_events_socket); + s_tun_events_socket->_inheritor = NULL; + + return 0; + } + else { + pthread_create(&s_thread_read_tun_id, NULL, thread_read_tun, NULL); + } + + //m_tunDeviceName = dev; //m_tunSocket = fd; return l_ret; @@ -476,6 +571,14 @@ int dap_chain_net_vpn_client_tun_create(const char *a_ipv4_addr_str, const char int dap_chain_net_vpn_client_tun_delete(void) { + if(is_dap_tun_in_worker()) + { + pthread_mutex_lock(&s_clients_mutex); + dap_events_socket_kill_socket(s_tun_events_socket); + s_tun_events_socket = NULL; + pthread_mutex_unlock(&s_clients_mutex); + } + // restore previous routing if(!s_conn_name || !s_last_used_connection_name) return -1; @@ -518,27 +621,31 @@ int dap_chain_net_vpn_client_tun_delete(void) int dap_chain_net_vpn_client_tun_status(void) { - char *l_str_cmd = get_connection(s_conn_name); + char *l_conn_dev = NULL; + char *l_str_cmd = get_connection(s_conn_name, &l_conn_dev); if(!l_str_cmd) - return 0; + return -1; // connection must be present - if(dap_strcmp(l_str_cmd, s_conn_name)) { + if(dap_strcmp(l_str_cmd, s_conn_name) || dap_strcmp(l_conn_dev, s_dev)) { DAP_DELETE(l_str_cmd); - return 0; + DAP_DELETE(l_conn_dev); + return -2; } DAP_DELETE(l_str_cmd); + DAP_DELETE(l_conn_dev); + /* alternative method char *l_used_connection_name = NULL; char *l_used_connection_device = NULL; save_current_connection_interface_data(&l_used_connection_name, &l_used_connection_device); // connection must be upped - if(dap_strcmp(l_used_connection_name, s_conn_name) || dap_strcmp(l_used_connection_device, s_dev)) { + if(!s_dev || dap_strcmp(l_used_connection_name, s_conn_name) || dap_strcmp(l_used_connection_device, s_dev)) { DAP_DELETE(l_used_connection_name); DAP_DELETE(l_used_connection_device); return -1; } DAP_DELETE(l_used_connection_name); - DAP_DELETE(l_used_connection_device); + DAP_DELETE(l_used_connection_device);*/ // VPN client started return 0; diff --git a/modules/service/vpn/include/dap_chain_net_srv_vpn.h b/modules/service/vpn/include/dap_chain_net_srv_vpn.h index 014a4225f9..b7896676ff 100644 --- a/modules/service/vpn/include/dap_chain_net_srv_vpn.h +++ b/modules/service/vpn/include/dap_chain_net_srv_vpn.h @@ -155,6 +155,10 @@ typedef struct dap_chain_net_srv_vpn #define CH_VPN(a) ((dap_chain_net_srv_ch_vpn_t *) ((a)->internal) ) +bool is_dap_tun_in_worker(void); + +int dap_chain_net_srv_client_vpn_init(dap_config_t * g_config); + int dap_chain_net_srv_vpn_init(dap_config_t * g_config); void dap_chain_net_srv_vpn_deinit(void); diff --git a/modules/service/vpn/include/dap_chain_net_srv_vpn_cdb_auth.h b/modules/service/vpn/include/dap_chain_net_srv_vpn_cdb_auth.h index a5df0ae3e7..53345d54e2 100644 --- a/modules/service/vpn/include/dap_chain_net_srv_vpn_cdb_auth.h +++ b/modules/service/vpn/include/dap_chain_net_srv_vpn_cdb_auth.h @@ -32,6 +32,6 @@ void dap_chain_net_srv_vpn_cdb_auth_deinit(); void dap_chain_net_srv_vpn_cdb_auth_add_proc(dap_http_t * a_http, const char * a_url); void dap_chain_net_srv_vpn_cdb_auth_set_callback(dap_enc_http_callback_t a_callback_success); -int dap_chain_net_srv_vpn_cdb_auth_cli_cmd ( const char *a_user_str,int a_arg_index, int a_argc, char ** a_argv, char **a_str_reply); +int dap_chain_net_srv_vpn_cdb_auth_cli_cmd_user ( const char *a_user_str,int a_arg_index, int a_argc, char ** a_argv, char **a_str_reply); -int dap_chain_net_srv_vpn_cdb_auth_check(const char * a_login, const char * a_password); +int dap_chain_net_srv_vpn_cdb_auth_check_login(const char * a_login, const char * a_password); diff --git a/modules/service/vpn/include/dap_chain_net_vpn_client.h b/modules/service/vpn/include/dap_chain_net_vpn_client.h index a75a307f73..4f613e02c8 100644 --- a/modules/service/vpn/include/dap_chain_net_vpn_client.h +++ b/modules/service/vpn/include/dap_chain_net_vpn_client.h @@ -29,11 +29,22 @@ #include "dap_chain_net.h" #include "dap_chain_net_srv_vpn.h" +typedef enum dap_chain_net_vpn_client_status_enum{ + VPN_CLIENT_STATUS_NOT_STARTED=0, + VPN_CLIENT_STATUS_STARTED, + VPN_CLIENT_STATUS_STOPPED, + VPN_CLIENT_STATUS_CONN_LOST, +} dap_chain_net_vpn_client_status_t; + + dap_stream_ch_t* dap_chain_net_vpn_client_get_stream_ch(void); +int dap_chain_net_vpn_client_update(dap_chain_net_t *a_net, const char *a_wallet_name, const char *a_str_token, uint64_t a_value_datoshi); +int dap_chain_net_vpn_client_get_wallet_info(dap_chain_net_t *a_net, char **a_wallet_name, char **a_str_token, uint64_t *a_value_datoshi); + int dap_chain_net_vpn_client_start(dap_chain_net_t *a_net, const char *a_ipv4_str, const char *a_ipv6_str, int a_port); int dap_chain_net_vpn_client_stop(void); -int dap_chain_net_vpn_client_status(void); +dap_chain_net_vpn_client_status_t dap_chain_net_vpn_client_status(void); int dap_chain_net_vpn_client_init(dap_config_t * g_config); void dap_chain_net_vpn_client_deinit(); -- GitLab