Skip to content
Snippets Groups Projects
Commit b195dd9e authored by daniil.frolov's avatar daniil.frolov Committed by Roman Khlopkov
Browse files

hotfix-8964

parent b8c59153
No related branches found
No related tags found
1 merge request!1158hotfix-8964
...@@ -30,15 +30,15 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic ...@@ -30,15 +30,15 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic
#include "dap_hash.h" #include "dap_hash.h"
#include "rand/dap_rand.h" #include "rand/dap_rand.h"
#include "dap_chain.h" //#include "dap_chain.h"
#include "dap_chain_datum_tx.h" //#include "dap_chain_datum_tx.h"
#include "dap_chain_datum_tx_in.h" //#include "dap_chain_datum_tx_in.h"
#include "dap_chain_datum_tx_in_cond.h" //#include "dap_chain_datum_tx_in_cond.h"
#include "dap_chain_datum_tx_out.h" //#include "dap_chain_datum_tx_out.h"
#include "dap_chain_datum_tx_out_cond.h" //#include "dap_chain_datum_tx_out_cond.h"
#include "dap_chain_datum_tx_receipt.h" //#include "dap_chain_datum_tx_receipt.h"
#include "dap_chain_mempool.h" //#include "dap_chain_mempool.h"
#include "dap_common.h" //#include "dap_common.h"
#include "dap_chain_net_srv.h" #include "dap_chain_net_srv.h"
#include "dap_chain_net_srv_stream_session.h" #include "dap_chain_net_srv_stream_session.h"
...@@ -54,6 +54,11 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic ...@@ -54,6 +54,11 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic
#define LOG_TAG "dap_stream_ch_chain_net_srv" #define LOG_TAG "dap_stream_ch_chain_net_srv"
typedef struct usages_in_grace{
dap_hash_fast_t tx_cond_hash;
dap_chain_net_srv_grace_t *grace;
UT_hash_handle hh;
} usages_in_grace_t;
uint8_t dap_stream_ch_chain_net_srv_get_id() uint8_t dap_stream_ch_chain_net_srv_get_id()
{ {
...@@ -65,6 +70,62 @@ static void s_stream_ch_delete(dap_stream_ch_t* ch , void* arg); ...@@ -65,6 +70,62 @@ 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_in(dap_stream_ch_t* ch , void* arg);
static void s_stream_ch_packet_out(dap_stream_ch_t* ch , void* arg); static void s_stream_ch_packet_out(dap_stream_ch_t* ch , void* arg);
static bool s_unban_client(dap_chain_net_srv_banlist_item_t *a_item);
static void s_service_start(dap_stream_ch_t* a_ch , dap_stream_ch_chain_net_srv_pkt_request_t * a_request, size_t a_request_size);
static void s_grace_period_start(dap_chain_net_srv_grace_t *a_grace);
static bool s_grace_period_finish(usages_in_grace_t *a_grace);
static inline void s_grace_error(dap_chain_net_srv_grace_t *a_grace, dap_stream_ch_chain_net_srv_pkt_error_t a_err){
dap_stream_ch_t * l_ch = dap_stream_ch_find_by_uuid_unsafe(a_grace->stream_worker, a_grace->ch_uuid);
dap_chain_net_srv_stream_session_t *l_srv_session = l_ch && l_ch->stream && l_ch->stream->session ?
(dap_chain_net_srv_stream_session_t *)l_ch->stream->session->_inheritor : NULL;
a_grace->usage->is_grace = false;
if (a_grace->usage->receipt_next){ // If not first grace-period
log_it( L_WARNING, "Next receipt is rejected. Waiting until current limits is over.");
DAP_DEL_Z(a_grace->usage->receipt_next);
memset(&a_grace->usage->tx_cond_hash, 0, sizeof(a_grace->usage->tx_cond_hash));
DAP_DELETE(a_grace->request);
DAP_DELETE(a_grace);
return;
}
if (a_err.code) {
if(l_ch)
dap_stream_ch_pkt_write_unsafe(l_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &a_err, sizeof (a_err));
if (a_grace->usage->service && a_grace->usage->service->callbacks.response_error)
a_grace->usage->service->callbacks.response_error(a_grace->usage->service, 0, NULL, &a_err, sizeof(a_err));
}
if (a_grace->usage) { // add client pkey hash to banlist
a_grace->usage->is_active = false;
if (a_grace->usage->service) {
dap_chain_net_srv_banlist_item_t *l_item = NULL;
pthread_mutex_lock(&a_grace->usage->service->banlist_mutex);
HASH_FIND(hh, a_grace->usage->service->ban_list, &a_grace->usage->client_pkey_hash, sizeof(dap_chain_hash_fast_t), l_item);
if (l_item)
pthread_mutex_unlock(&a_grace->usage->service->banlist_mutex);
else {
l_item = DAP_NEW_Z(dap_chain_net_srv_banlist_item_t);
l_item->client_pkey_hash = a_grace->usage->client_pkey_hash;
l_item->ht_mutex = &a_grace->usage->service->banlist_mutex;
l_item->ht_head = &a_grace->usage->service->ban_list;
HASH_ADD(hh, a_grace->usage->service->ban_list, client_pkey_hash, sizeof(dap_chain_hash_fast_t), l_item);
pthread_mutex_unlock(&a_grace->usage->service->banlist_mutex);
dap_timerfd_start(a_grace->usage->service->grace_period * 1000, (dap_timerfd_callback_t)s_unban_client, l_item);
}
}
} else if (l_srv_session->usage_active)
dap_chain_net_srv_usage_delete(l_srv_session);
DAP_DELETE(a_grace->request);
DAP_DELETE(a_grace);
}
// TODO: move this to net_srv
static usages_in_grace_t * s_grace_table = NULL;
static pthread_mutex_t s_ht_grace_table_mutex;
/** /**
* @brief dap_stream_ch_chain_net_init * @brief dap_stream_ch_chain_net_init
* @return * @return
...@@ -73,6 +134,7 @@ int dap_stream_ch_chain_net_srv_init(void) ...@@ -73,6 +134,7 @@ int dap_stream_ch_chain_net_srv_init(void)
{ {
log_it(L_NOTICE,"Chain network services channel initialized"); log_it(L_NOTICE,"Chain network services channel initialized");
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); 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);
pthread_mutex_init(&s_ht_grace_table_mutex, NULL);
return 0; return 0;
} }
...@@ -105,7 +167,6 @@ void s_stream_ch_new(dap_stream_ch_t* a_ch , void* arg) ...@@ -105,7 +167,6 @@ void s_stream_ch_new(dap_stream_ch_t* a_ch , void* arg)
log_it(L_ERROR, "Session inheritor is already present!"); log_it(L_ERROR, "Session inheritor is already present!");
dap_chain_net_srv_call_opened_all( a_ch); dap_chain_net_srv_call_opened_all( a_ch);
} }
...@@ -120,6 +181,8 @@ void s_stream_ch_delete(dap_stream_ch_t* a_ch , void* a_arg) ...@@ -120,6 +181,8 @@ void s_stream_ch_delete(dap_stream_ch_t* a_ch , void* a_arg)
(void) a_arg; (void) a_arg;
log_it(L_DEBUG, "Stream ch chain net srv delete"); log_it(L_DEBUG, "Stream ch chain net srv delete");
dap_chain_net_srv_call_closed_all( a_ch); dap_chain_net_srv_call_closed_all( a_ch);
if (a_ch->stream->session && a_ch->stream->session->_inheritor)
dap_chain_net_srv_stream_session_delete( a_ch->stream->session );
DAP_DEL_Z(a_ch->internal); DAP_DEL_Z(a_ch->internal);
} }
...@@ -132,29 +195,41 @@ static bool s_unban_client(dap_chain_net_srv_banlist_item_t *a_item) ...@@ -132,29 +195,41 @@ static bool s_unban_client(dap_chain_net_srv_banlist_item_t *a_item)
return false; return false;
} }
static bool s_grace_period_control(dap_chain_net_srv_grace_t *a_grace) void dap_stream_ch_chain_net_srv_tx_cond_added_cb(void *a_arg, dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx)
{ {
assert(a_grace); UNUSED(a_ledger);
UNUSED(a_arg);
// TODO: 1. Get net_srv by srv_uid from tx_cond
// 2. Get usages in grace HT from service
usages_in_grace_t *l_item = NULL;
dap_hash_fast_t tx_cond_hash = {};
dap_hash_fast((void*)a_tx, dap_chain_datum_tx_get_size(a_tx), &tx_cond_hash);
pthread_mutex_lock(&s_ht_grace_table_mutex);
HASH_FIND(hh, s_grace_table, &tx_cond_hash, sizeof(dap_hash_fast_t), l_item);
if (l_item){
log_it(L_INFO, "Found tx in ledger by notify. Finish grace.");
// Stop timer
dap_timerfd_delete_mt(l_item->grace->stream_worker->worker, l_item->grace->timer_es_uuid);
// finish grace
s_grace_period_finish(l_item);
}
pthread_mutex_unlock(&s_ht_grace_table_mutex);
}
static void s_service_start(dap_stream_ch_t* a_ch , dap_stream_ch_chain_net_srv_pkt_request_t * a_request, size_t a_request_size)
{
assert(a_ch);
dap_stream_ch_chain_net_srv_pkt_error_t l_err; dap_stream_ch_chain_net_srv_pkt_error_t l_err;
memset(&l_err, 0, sizeof(l_err)); memset(&l_err, 0, sizeof(l_err));
dap_chain_net_srv_t * l_srv = NULL; dap_chain_net_srv_t * l_srv = NULL;
dap_chain_net_srv_usage_t *l_usage = NULL;
dap_stream_ch_t *l_ch = dap_stream_ch_find_by_uuid_unsafe(a_grace->stream_worker, a_grace->ch_uuid);
if (!l_ch) dap_chain_net_srv_stream_session_t *l_srv_session = a_ch->stream && a_ch->stream->session ?
goto free_exit; (dap_chain_net_srv_stream_session_t *)a_ch->stream->session->_inheritor : NULL;
l_srv = dap_chain_net_srv_get( a_request->hdr.srv_uid );
dap_chain_net_t * l_net = dap_chain_net_by_id( a_request->hdr.net_id );
dap_chain_net_srv_stream_session_t *l_srv_session = l_ch && l_ch->stream && l_ch->stream->session ? l_err.net_id.uint64 = a_request->hdr.net_id.uint64;
(dap_chain_net_srv_stream_session_t *)l_ch->stream->session->_inheritor : NULL; l_err.srv_uid.uint64 = a_request->hdr.srv_uid.uint64;
if (!l_srv_session)
goto free_exit;
dap_stream_ch_chain_net_srv_pkt_request_t *l_request = a_grace->request;
l_srv = dap_chain_net_srv_get( l_request->hdr.srv_uid );
dap_chain_net_t * l_net = dap_chain_net_by_id( l_request->hdr.net_id );
l_err.net_id.uint64 = l_request->hdr.net_id.uint64;
l_err.srv_uid.uint64 = l_request->hdr.srv_uid.uint64;
if ( ! l_net ) // Network not found if ( ! l_net ) // Network not found
l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_NETWORK_NOT_FOUND; l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_NETWORK_NOT_FOUND;
...@@ -162,83 +237,149 @@ static bool s_grace_period_control(dap_chain_net_srv_grace_t *a_grace) ...@@ -162,83 +237,149 @@ static bool s_grace_period_control(dap_chain_net_srv_grace_t *a_grace)
if ( ! l_srv ) // Service not found if ( ! l_srv ) // Service not found
l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_SERVICE_NOT_FOUND; l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_SERVICE_NOT_FOUND;
if ( l_err.code ){ if ( l_err.code || !l_srv_session){
goto free_exit; if(a_ch)
dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof (l_err));
if (l_srv && l_srv->callbacks.response_error)
l_srv->callbacks.response_error(l_srv, 0, NULL, &l_err, sizeof(l_err));
return;
}
dap_chain_net_srv_usage_t *l_usage = NULL;
l_usage = dap_chain_net_srv_usage_add(l_srv_session, l_net, l_srv);
if ( !l_usage ){ // Usage can't add
log_it( L_WARNING, "Can't add usage");
l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_CANT_ADD_USAGE;
if(a_ch)
dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof (l_err));
if (l_srv && l_srv->callbacks.response_error)
l_srv->callbacks.response_error(l_srv, 0, NULL, &l_err, sizeof(l_err));
return;
}
l_err.usage_id = l_usage->id;
// Create one client
l_usage->client = DAP_NEW_Z( dap_chain_net_srv_client_remote_t);
l_usage->client->stream_worker = a_ch->stream_worker;
l_usage->client->ch = a_ch;
l_usage->client->session_id = a_ch->stream->session->id;
l_usage->client->ts_created = time(NULL);
l_usage->tx_cond_hash = a_request->hdr.tx_cond;
l_usage->ts_created = time(NULL);
l_usage->net = l_net;
l_usage->service = l_srv;
dap_chain_net_srv_grace_t *l_grace = DAP_NEW_Z(dap_chain_net_srv_grace_t);
l_grace->request = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_request_t, a_request_size);
memcpy(l_grace->request, a_request, a_request_size);
l_grace->request_size = a_request_size;
l_grace->ch_uuid = a_ch->uuid;
l_grace->stream_worker = a_ch->stream_worker;
l_grace->usage = l_usage;
if (l_srv->pricelist){
// not free service
s_grace_period_start(l_grace);
} else {
// Start service for free
log_it( L_INFO, "Service provide for free");
l_grace->usage->is_free = true;
size_t l_success_size = sizeof (dap_stream_ch_chain_net_srv_pkt_success_hdr_t );
dap_stream_ch_chain_net_srv_pkt_success_t *l_success = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_success_t,
l_success_size);
l_success->hdr.usage_id = l_usage->id;
l_success->hdr.net_id.uint64 = l_usage->net->pub.id.uint64;
l_success->hdr.srv_uid.uint64 = l_usage->service->uid.uint64;
dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_SUCCESS, l_success, l_success_size);
if (l_usage->service->callbacks.response_success)
l_usage->service->callbacks.response_success(l_usage->service, l_usage->id, l_usage->client, NULL, 0);
DAP_DELETE(l_success);
}
return;
}
static void s_grace_period_start(dap_chain_net_srv_grace_t *a_grace)
{
assert(a_grace);
dap_stream_ch_chain_net_srv_pkt_error_t l_err;
memset(&l_err, 0, sizeof(l_err));
dap_stream_ch_t *l_ch = dap_stream_ch_find_by_uuid_unsafe(a_grace->stream_worker, a_grace->ch_uuid);
if (!l_ch){
s_grace_error(a_grace, l_err);
return;
} }
dap_ledger_t * l_ledger =l_net->pub.ledger; dap_chain_net_t * l_net = a_grace->usage->net;
l_err.net_id.uint64 = l_net->pub.id.uint64;
l_err.srv_uid.uint64 = a_grace->usage->service->uid.uint64;
dap_ledger_t * l_ledger = l_net->pub.ledger;
dap_chain_datum_tx_t * l_tx = NULL; dap_chain_datum_tx_t * l_tx = NULL;
dap_chain_tx_out_cond_t * l_tx_out_cond = NULL; dap_chain_tx_out_cond_t * l_tx_out_cond = NULL;
bool l_grace_start = false; dap_chain_net_srv_price_t * l_price = NULL;
if (l_srv->pricelist ){ // Is present pricelist, not free service if ( !l_ledger ){ // No ledger
log_it( L_WARNING, "No Ledger");
l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_NETWORK_NO_LEDGER ;
s_grace_error(a_grace, l_err);
return;
}
if ( !l_ledger ){ // No ledger l_tx = a_grace->usage->is_waiting_new_tx_cond ? NULL : dap_chain_ledger_tx_find_by_hash(l_ledger, &a_grace->usage->tx_cond_hash);
log_it( L_WARNING, "No Ledger"); if ( ! l_tx ){ // No tx cond transaction, start grace-period
l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_NETWORK_NO_LEDGER ; a_grace->usage->is_grace = true;
goto free_exit;
}
l_tx = dap_chain_ledger_tx_find_by_hash( l_ledger,& l_request->hdr.tx_cond ); l_price = DAP_NEW_Z(dap_chain_net_srv_price_t);
if ( ! l_tx ){ // No tx cond transaction memcpy(l_price, a_grace->usage->service->pricelist, sizeof(*l_price));
if (a_grace->usage) { // marker for reentry to function
log_it( L_WARNING, "No tx cond transaction");
l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_FOUND ;
goto free_exit;
} else
l_grace_start = true;
}
if (!l_grace_start) {
int l_tx_out_cond_size =0;
l_tx_out_cond = (dap_chain_tx_out_cond_t *)
dap_chain_datum_tx_item_get(l_tx, NULL, TX_ITEM_TYPE_OUT_COND, &l_tx_out_cond_size );
if ( ! l_tx_out_cond ) { // No conditioned output a_grace->usage->price = l_price;
log_it( L_WARNING, "No conditioned output");
l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NO_COND_OUT ;
goto free_exit;
}
// Check cond output if it equesl or not to request if (!a_grace->usage->receipt){
if (!dap_chain_net_srv_uid_compare(l_tx_out_cond->header.srv_uid, l_request->hdr.srv_uid)) { a_grace->usage->receipt = dap_chain_net_srv_issue_receipt(a_grace->usage->service, a_grace->usage->price, NULL, 0);
log_it( L_WARNING, "Wrong service uid in request, tx expect to close its output with 0x%016"DAP_UINT64_FORMAT_X, dap_stream_ch_pkt_write_unsafe(l_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_REQUEST,
l_tx_out_cond->header.srv_uid.uint64 ); a_grace->usage->receipt, a_grace->usage->receipt->size);
l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_WRONG_SRV_UID ;
goto free_exit;
}
} }
} usages_in_grace_t *l_item = DAP_NEW_Z_SIZE(usages_in_grace_t, sizeof(usages_in_grace_t));
if (!a_grace->usage) { l_item->grace = a_grace;
l_usage = dap_chain_net_srv_usage_add(l_srv_session, l_net, l_srv); l_item->tx_cond_hash = a_grace->usage->tx_cond_hash;
if ( !l_usage ){ // Usage can't add
log_it( L_WARNING, "Can't add usage"); pthread_mutex_lock(&s_ht_grace_table_mutex);
l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_CANT_ADD_USAGE; HASH_ADD(hh, s_grace_table, tx_cond_hash, sizeof(dap_hash_fast_t), l_item);
goto free_exit; pthread_mutex_unlock(&s_ht_grace_table_mutex);
a_grace->timer_es_uuid = dap_timerfd_start_on_worker(a_grace->stream_worker->worker, a_grace->usage->service->grace_period * 1000,
(dap_timerfd_callback_t)s_grace_period_finish, l_item)->esocket_uuid;
} else { // Start srvice in normal pay mode
a_grace->usage->tx_cond = l_tx;
l_tx_out_cond = dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, NULL );
if ( ! l_tx_out_cond ) { // No conditioned output
log_it( L_WARNING, "No conditioned output");
l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NO_COND_OUT ;
s_grace_error(a_grace, l_err);
return;
} }
l_err.usage_id = l_usage->id; // Check cond output if it equesl or not to request
if (!dap_chain_net_srv_uid_compare(l_tx_out_cond->header.srv_uid, a_grace->usage->service->uid)) {
log_it( L_WARNING, "Wrong service uid in request, tx expect to close its output with 0x%016"DAP_UINT64_FORMAT_X,
l_tx_out_cond->header.srv_uid.uint64 );
l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_WRONG_SRV_UID ;
s_grace_error(a_grace, l_err);
return;
}
// Create one client const char * l_ticker = NULL;
l_usage->client = DAP_NEW_Z( dap_chain_net_srv_client_remote_t); l_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, &a_grace->usage->tx_cond_hash);
l_usage->client->stream_worker = l_ch->stream_worker; dap_stpcpy(a_grace->usage->token_ticker, l_ticker);
l_usage->client->ch = l_ch;
l_usage->client->session_id = l_ch->stream->session->id;
l_usage->client->ts_created = time(NULL);
l_usage->tx_cond = l_tx;
l_usage->tx_cond_hash = l_request->hdr.tx_cond;
l_usage->ts_created = time(NULL);
} else {
l_usage = a_grace->usage;
l_usage->tx_cond = l_tx;
}
dap_chain_net_srv_price_t * l_price = NULL;
const char * l_ticker = NULL;
if (l_srv->pricelist && !l_grace_start) {
l_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_request->hdr.tx_cond );
dap_stpcpy(l_usage->token_ticker, l_ticker);
dap_chain_net_srv_price_t *l_price_tmp; dap_chain_net_srv_price_t *l_price_tmp;
DL_FOREACH(l_srv->pricelist, l_price_tmp) { DL_FOREACH(a_grace->usage->service->pricelist, l_price_tmp) {
if (l_price_tmp->net->pub.id.uint64 == l_request->hdr.net_id.uint64 if (l_price_tmp && l_price_tmp->net->pub.id.uint64 == a_grace->usage->net->pub.id.uint64
&& dap_strcmp(l_price_tmp->token, l_ticker) == 0 && dap_strcmp(l_price_tmp->token, l_ticker) == 0
&& l_price_tmp->units_uid.enm == l_tx_out_cond->subtype.srv_pay.unit.enm && l_price_tmp->units_uid.enm == l_tx_out_cond->subtype.srv_pay.unit.enm
)//&& (l_price_tmp->value_datoshi/l_price_tmp->units) < l_tx_out_cond->subtype.srv_pay.header.unit_price_max_datoshi) )//&& (l_price_tmp->value_datoshi/l_price_tmp->units) < l_tx_out_cond->subtype.srv_pay.header.unit_price_max_datoshi)
...@@ -251,102 +392,232 @@ static bool s_grace_period_control(dap_chain_net_srv_grace_t *a_grace) ...@@ -251,102 +392,232 @@ static bool s_grace_period_control(dap_chain_net_srv_grace_t *a_grace)
log_it( L_WARNING, "Request can't be processed because no acceptable price in pricelist for token %s in network %s", log_it( L_WARNING, "Request can't be processed because no acceptable price in pricelist for token %s in network %s",
l_ticker, l_net->pub.name ); l_ticker, l_net->pub.name );
l_err.code =DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_ACCEPT_TOKEN; l_err.code =DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_ACCEPT_TOKEN;
goto free_exit; s_grace_error(a_grace, l_err);
return;
}
a_grace->usage->price = l_price;
int ret;
if ((ret = a_grace->usage->service->callbacks.requested(a_grace->usage->service, a_grace->usage->id, a_grace->usage->client, a_grace->request, a_grace->request_size)) != 0) {
log_it( L_WARNING, "Request canceled by service callback, return code %d", ret);
l_err.code = (uint32_t) ret ;
s_grace_error(a_grace, l_err);
return;
} }
}
int ret;
if ((ret = l_srv->callbacks.requested(l_srv, l_usage->id, l_usage->client, l_request, a_grace->request_size)) != 0) {
log_it( L_WARNING, "Request canceled by service callback, return code %d", ret);
l_err.code = (uint32_t) ret ;
goto free_exit;
}
if ( l_srv->pricelist) { if (a_grace->usage->receipt_next){
if (l_price || l_grace_start) { DAP_DEL_Z(a_grace->usage->receipt_next);
if (l_price) { a_grace->usage->receipt_next = dap_chain_net_srv_issue_receipt(a_grace->usage->service, a_grace->usage->price, NULL, 0);
if (a_grace->usage) {
DAP_DELETE(l_usage->price);
}
} else {
l_price = DAP_NEW_Z(dap_chain_net_srv_price_t);
memcpy(l_price, l_srv->pricelist, sizeof(*l_price));
l_price->value_datoshi = uint256_0;
}
l_usage->price = l_price;
if (l_usage->receipt_next){
DAP_DEL_Z(l_usage->receipt_next);
l_usage->receipt_next = dap_chain_net_srv_issue_receipt(l_usage->service, l_usage->price, NULL, 0);
}else{
dap_chain_net_srv_price_t l_b_price = *l_usage->price;
if (l_grace_start || a_grace->usage){
l_b_price.units *= 2;
MULT_256_256(l_b_price.value_datoshi, GET_256_FROM_64((uint64_t)2), &l_b_price.value_datoshi);
}
l_usage->receipt = dap_chain_net_srv_issue_receipt(l_usage->service, &l_b_price, NULL, 0);
dap_stream_ch_pkt_write_unsafe(l_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_REQUEST,
l_usage->receipt, l_usage->receipt->size);
}
}else{ }else{
l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_PRICE_NOT_FOUND ; a_grace->usage->receipt = dap_chain_net_srv_issue_receipt(a_grace->usage->service, a_grace->usage->price, NULL, 0);
goto free_exit; dap_stream_ch_pkt_write_unsafe(l_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_REQUEST,
a_grace->usage->receipt, a_grace->usage->receipt->size);
} }
// If we a here we passed all the checks, wow, now if we're not for free we request the signature.
} else{
log_it( L_INFO, "Service provide for free");
l_usage->is_free = true;
size_t l_success_size = sizeof (dap_stream_ch_chain_net_srv_pkt_success_hdr_t );
dap_stream_ch_chain_net_srv_pkt_success_t *l_success = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_success_t,
l_success_size);
l_success->hdr.usage_id = l_usage->id;
l_success->hdr.net_id.uint64 = l_usage->net->pub.id.uint64;
l_success->hdr.srv_uid.uint64 = l_usage->service->uid.uint64;
dap_stream_ch_pkt_write_unsafe(l_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_SUCCESS, l_success, l_success_size);
if (l_usage->service->callbacks.response_success)
l_usage->service->callbacks.response_success(l_usage->service, l_usage->id, l_usage->client, NULL, 0);
DAP_DELETE(l_success);
}
if (l_grace_start) {
l_usage->is_grace = true;
a_grace->usage = l_usage;
dap_timerfd_start_on_worker(a_grace->stream_worker->worker, l_srv->grace_period * 1000,
(dap_timerfd_callback_t)s_grace_period_control, a_grace);
return false;
} else {
DAP_DELETE(a_grace->request); DAP_DELETE(a_grace->request);
DAP_DELETE(a_grace); DAP_DELETE(a_grace);
l_usage->is_grace = false;
}
}
static bool s_grace_period_finish(usages_in_grace_t *a_grace_item)
{
assert(a_grace_item);
dap_stream_ch_chain_net_srv_pkt_error_t l_err;
memset(&l_err, 0, sizeof(l_err));
dap_chain_net_srv_grace_t *l_grace = a_grace_item->grace;
dap_stream_ch_t *l_ch = dap_stream_ch_find_by_uuid_unsafe(l_grace->stream_worker, l_grace->ch_uuid);
if (l_grace->usage->price && !l_grace->usage->receipt_next){ // if first grace delete price and set actual
DAP_DEL_Z(l_grace->usage->price);
}
if (!l_ch){
s_grace_error(l_grace, l_err);
HASH_DEL(s_grace_table, a_grace_item);
DAP_DEL_Z(a_grace_item);
return false; return false;
} }
free_exit:
if (l_err.code) { if (l_grace->usage->is_waiting_new_tx_cond){
if(l_ch) log_it(L_INFO, "No new tx cond!");
dap_stream_ch_pkt_write_unsafe(l_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof (l_err)); s_grace_error(l_grace, l_err);
if (l_srv && l_srv->callbacks.response_error) l_grace->usage->is_waiting_new_tx_cond = false;
l_srv->callbacks.response_error(l_srv, 0, NULL, &l_err, sizeof(l_err)); HASH_DEL(s_grace_table, a_grace_item);
DAP_DEL_Z(a_grace_item);
return false;
} }
if (a_grace->usage) { // add client pkey hash to banlist
a_grace->usage->is_active = false; dap_chain_net_t * l_net = l_grace->usage->net;
if (l_srv) {
dap_chain_net_srv_banlist_item_t *l_item = NULL; l_err.net_id.uint64 = l_net->pub.id.uint64;
pthread_mutex_lock(&l_srv->banlist_mutex); l_err.srv_uid.uint64 = l_grace->usage->service->uid.uint64;
HASH_FIND(hh, l_srv->ban_list, &a_grace->usage->client_pkey_hash, sizeof(dap_chain_hash_fast_t), l_item);
if (l_item) dap_ledger_t * l_ledger = l_net->pub.ledger;
pthread_mutex_unlock(&l_srv->banlist_mutex); dap_chain_datum_tx_t * l_tx = NULL;
else { dap_chain_tx_out_cond_t * l_tx_out_cond = NULL;
l_item = DAP_NEW_Z(dap_chain_net_srv_banlist_item_t);
l_item->client_pkey_hash = a_grace->usage->client_pkey_hash; if ( !l_ledger ){ // No ledger
l_item->ht_mutex = &l_srv->banlist_mutex; log_it( L_WARNING, "No Ledger");
l_item->ht_head = &l_srv->ban_list; l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_NETWORK_NO_LEDGER ;
HASH_ADD(hh, l_srv->ban_list, client_pkey_hash, sizeof(dap_chain_hash_fast_t), l_item); s_grace_error(l_grace, l_err);
pthread_mutex_unlock(&l_srv->banlist_mutex); HASH_DEL(s_grace_table, a_grace_item);
dap_timerfd_start(l_srv->grace_period * 1000, (dap_timerfd_callback_t)s_unban_client, l_item); DAP_DEL_Z(a_grace_item);
return false;
}
log_it(L_INFO, "Grace period is over! Check tx in ledger.");
l_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, &l_grace->usage->tx_cond_hash);
if ( ! l_tx ){ // No tx cond transaction, start grace-period
log_it( L_WARNING, "No tx cond transaction");
l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_FOUND ;
s_grace_error(l_grace, l_err);
HASH_DEL(s_grace_table, a_grace_item);
DAP_DEL_Z(a_grace_item);
return false;
} else { // Start srvice in normal pay mode
log_it(L_INFO, "Tx is found in ledger.");
l_grace->usage->tx_cond = l_tx;
l_tx_out_cond = dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, NULL );
if ( ! l_tx_out_cond ) { // No conditioned output
log_it( L_WARNING, "No conditioned output");
l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NO_COND_OUT ;
s_grace_error(l_grace, l_err);
HASH_DEL(s_grace_table, a_grace_item);
DAP_DEL_Z(a_grace_item);
return false;
}
// Check cond output if it equesl or not to request
if (!dap_chain_net_srv_uid_compare(l_tx_out_cond->header.srv_uid, l_grace->usage->service->uid)) {
log_it( L_WARNING, "Wrong service uid in request, tx expect to close its output with 0x%016"DAP_UINT64_FORMAT_X,
l_tx_out_cond->header.srv_uid.uint64 );
l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_WRONG_SRV_UID ;
s_grace_error(l_grace, l_err);
HASH_DEL(s_grace_table, a_grace_item);
DAP_DEL_Z(a_grace_item);
return false;
}
dap_chain_net_srv_price_t * l_price = NULL;
const char * l_ticker = NULL;
l_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_grace->usage->tx_cond_hash);
dap_stpcpy(l_grace->usage->token_ticker, l_ticker);
dap_chain_net_srv_price_t *l_price_tmp;
DL_FOREACH(l_grace->usage->service->pricelist, l_price_tmp) {
if (l_price_tmp && l_price_tmp->net->pub.id.uint64 == l_grace->usage->net->pub.id.uint64
&& dap_strcmp(l_price_tmp->token, l_ticker) == 0
&& l_price_tmp->units_uid.enm == l_tx_out_cond->subtype.srv_pay.unit.enm
)//&& (l_price_tmp->value_datoshi/l_price_tmp->units) < l_tx_out_cond->subtype.srv_pay.header.unit_price_max_datoshi)
{
l_price = l_price_tmp;
break;
}
}
if ( !l_price ) {
log_it( L_WARNING, "Request can't be processed because no acceptable price in pricelist for token %s in network %s",
l_ticker, l_net->pub.name );
l_err.code =DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_ACCEPT_TOKEN;
s_grace_error(l_grace, l_err);
HASH_DEL(s_grace_table, a_grace_item);
DAP_DEL_Z(a_grace_item);
return false;
}
l_grace->usage->price = l_price;
int ret;
if ((ret = l_grace->usage->service->callbacks.requested(l_grace->usage->service, l_grace->usage->id, l_grace->usage->client, l_grace->request, l_grace->request_size)) != 0) {
log_it( L_WARNING, "Request canceled by service callback, return code %d", ret);
l_err.code = (uint32_t) ret ;
s_grace_error(l_grace, l_err);
HASH_DEL(s_grace_table, a_grace_item);
DAP_DEL_Z(a_grace_item);
return false;
}
// make receipt or tx
char *l_receipt_hash_str;
dap_chain_datum_tx_receipt_t *l_receipt = NULL;
if (l_grace->usage->receipt_next){
l_receipt = l_grace->usage->receipt_next;
} else if (l_grace->usage->receipt){
l_receipt = l_grace->usage->receipt;
} else {
// Send error???
}
size_t l_receipt_size = l_receipt->size;
// get a second signature - from the client (first sign in server, second sign in client)
dap_sign_t * l_receipt_sign = dap_chain_datum_tx_receipt_sign_get( l_receipt, l_receipt_size, 1);
if ( ! l_receipt_sign ){
log_it(L_WARNING, "Tx already in chain, but receipt is not signed by client. Finish grace and wait receipt sign responce.");
s_grace_error(l_grace, l_err);
HASH_DEL(s_grace_table, a_grace_item);
DAP_DEL_Z(a_grace_item);
return false;
}
dap_get_data_hash_str_static(l_receipt, l_receipt_size, l_receipt_hash_str);
dap_global_db_set("local.receipts", l_receipt_hash_str, l_receipt, l_receipt_size, false, NULL, NULL);
// Form input transaction
char *l_hash_str = dap_hash_fast_to_str_new(&l_grace->usage->tx_cond_hash);
log_it(L_NOTICE, "Trying create input tx cond from tx %s with active receipt", l_hash_str);
DAP_DEL_Z(l_hash_str);
dap_chain_addr_t *l_wallet_addr = dap_chain_wallet_get_addr(l_grace->usage->price->wallet, l_grace->usage->net->pub.id);
int ret_status = 0;
char *l_tx_in_hash_str = dap_chain_mempool_tx_create_cond_input(l_grace->usage->net, &l_grace->usage->tx_cond_hash, l_wallet_addr,
dap_chain_wallet_get_key(l_grace->usage->price->wallet, 0),
l_receipt, "hex", &ret_status);
DAP_DEL_Z(l_wallet_addr);
if (!ret_status) {
dap_chain_hash_fast_from_str(l_tx_in_hash_str, &l_grace->usage->tx_cond_hash);
log_it(L_NOTICE, "Formed tx %s for input with active receipt", l_tx_in_hash_str);
DAP_DELETE(l_tx_in_hash_str);
}else{
if(ret_status == DAP_CHAIN_MEMPOOl_RET_STATUS_NOT_ENOUGH){
// memset(&l_grace->usage->tx_cond_hash, 0, sizeof(l_grace->usage->tx_cond_hash));
// DAP_DEL_Z(l_grace->usage->receipt_next);
log_it(L_ERROR, "Tx cond have not enough funds");
dap_chain_net_srv_grace_t* l_grace_new = DAP_NEW_Z(dap_chain_net_srv_grace_t);
// Parse the request
l_grace_new->request = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_request_t, sizeof(dap_stream_ch_chain_net_srv_pkt_request_t));
l_grace_new->request->hdr.net_id = a_grace_item->grace->usage->net->pub.id;
memcpy(l_grace_new->request->hdr.token, a_grace_item->grace->usage->token_ticker, strlen(a_grace_item->grace->usage->token_ticker));
l_grace_new->request->hdr.srv_uid = a_grace_item->grace->usage->service->uid;
l_grace_new->request->hdr.tx_cond = a_grace_item->grace->usage->tx_cond_hash;
l_grace_new->request_size = sizeof(dap_stream_ch_chain_net_srv_pkt_request_t);
l_grace_new->ch_uuid = a_grace_item->grace->usage->client->ch->uuid;
l_grace_new->stream_worker = a_grace_item->grace->usage->client->ch->stream_worker;
l_grace_new->usage = a_grace_item->grace->usage;
l_grace_new->usage->is_waiting_new_tx_cond = true;
s_grace_period_start(l_grace_new);
l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_ENOUGH;
dap_stream_ch_pkt_write_unsafe(l_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof (l_err));
}else{
log_it(L_ERROR, "Can't create input tx cond transaction!");
memset(&l_grace->usage->tx_cond_hash, 0, sizeof(l_grace->usage->tx_cond_hash));
if (l_grace->usage->receipt_next){
DAP_DEL_Z(l_grace->usage->receipt_next);
} else if (l_grace->usage->receipt){
DAP_DEL_Z(l_grace->usage->receipt);
}
l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_SERVICE_NOT_FOUND;
dap_stream_ch_pkt_write_unsafe(l_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof (l_err));
if (l_grace->usage->service->callbacks.response_error)
l_grace->usage->service->callbacks.response_error(l_grace->usage->service,l_grace->usage->id, l_grace->usage->client,&l_err,sizeof (l_err));
} }
} }
} }
else if (l_usage) l_grace->usage->is_grace = false;
dap_chain_net_srv_usage_delete(l_srv_session, l_usage); DAP_DELETE(a_grace_item->grace->request);
DAP_DELETE(a_grace->request); DAP_DEL_Z(a_grace_item->grace);
DAP_DELETE(a_grace); HASH_DEL(s_grace_table, a_grace_item);
DAP_DEL_Z(a_grace_item);
return false; return false;
} }
...@@ -434,26 +705,27 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg) ...@@ -434,26 +705,27 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg)
log_it( L_WARNING, "Wrong request size, less than minimum"); log_it( L_WARNING, "Wrong request size, less than minimum");
break; break;
} }
dap_chain_net_srv_grace_t *l_grace = DAP_NEW_Z(dap_chain_net_srv_grace_t); dap_stream_ch_chain_net_srv_pkt_request_t *l_request = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_request_t, l_ch_pkt->hdr.data_size);
// Parse the request memcpy(l_request, l_ch_pkt->data, l_ch_pkt->hdr.data_size);
l_grace->request = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_request_t, l_ch_pkt->hdr.data_size); l_ch_chain_net_srv->srv_uid.uint64 = l_request->hdr.srv_uid.uint64;
memcpy(l_grace->request, l_ch_pkt->data, l_ch_pkt->hdr.data_size); s_service_start(a_ch, l_request, l_ch_pkt->hdr.data_size);
l_ch_chain_net_srv->srv_uid.uint64 = l_grace->request->hdr.srv_uid.uint64;
l_grace->request_size = l_ch_pkt->hdr.data_size;
l_grace->ch_uuid = a_ch->uuid;
l_grace->stream_worker = a_ch->stream_worker;
s_grace_period_control(l_grace);
} break; /* DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_REQUEST */ } break; /* DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_REQUEST */
case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_RESPONSE: { // Check receipt sign and make tx if success case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_RESPONSE: { // Check receipt sign and make tx if success
if (l_ch_pkt->hdr.data_size < sizeof(dap_chain_receipt_info_t)) { dap_chain_net_srv_usage_t * l_usage = l_srv_session->usage_active;
if (l_ch_pkt->hdr.data_size < sizeof(dap_chain_receipt_info_t)) {
log_it(L_ERROR, "Wrong sign response size, %u when expected at least %zu with smth", l_ch_pkt->hdr.data_size, log_it(L_ERROR, "Wrong sign response size, %u when expected at least %zu with smth", l_ch_pkt->hdr.data_size,
sizeof(dap_chain_receipt_info_t)); sizeof(dap_chain_receipt_info_t));
if ( l_usage->receipt_next ){ // If we have receipt next
DAP_DEL_Z(l_usage->receipt_next);
}else if (l_usage->receipt ){ // If we sign first receipt
DAP_DEL_Z(l_usage->receipt);
}
break; break;
} }
dap_chain_datum_tx_receipt_t * l_receipt = (dap_chain_datum_tx_receipt_t *) l_ch_pkt->data; 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.data_size; size_t l_receipt_size = l_ch_pkt->hdr.data_size;
dap_chain_net_srv_usage_t * l_usage = l_srv_session->usage_active;
bool l_is_found = false; bool l_is_found = false;
if ( l_usage->receipt_next ){ // If we have receipt next if ( l_usage->receipt_next ){ // If we have receipt next
if ( memcmp(&l_usage->receipt_next->receipt_info, &l_receipt->receipt_info,sizeof (l_receipt->receipt_info) )==0 ){ if ( memcmp(&l_usage->receipt_next->receipt_info, &l_receipt->receipt_info,sizeof (l_receipt->receipt_info) )==0 ){
...@@ -488,9 +760,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg) ...@@ -488,9 +760,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg)
&l_err, sizeof (l_err) ); &l_err, sizeof (l_err) );
break; break;
} }
int l_tx_out_cond_size =0; l_tx_out_cond = dap_chain_datum_tx_out_cond_get(l_usage->tx_cond, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, NULL );
l_tx_out_cond = (dap_chain_tx_out_cond_t *)dap_chain_datum_tx_item_get(l_usage->tx_cond, NULL,
TX_ITEM_TYPE_OUT_COND, &l_tx_out_cond_size );
if ( ! l_tx_out_cond ){ // No conditioned output if ( ! l_tx_out_cond ){ // No conditioned output
l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NO_COND_OUT ; l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NO_COND_OUT ;
dap_stream_ch_pkt_write_unsafe( a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof (l_err) ); dap_stream_ch_pkt_write_unsafe( a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof (l_err) );
...@@ -519,6 +789,19 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg) ...@@ -519,6 +789,19 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg)
HASH_FIND(hh, l_srv->ban_list, &l_usage->client_pkey_hash, sizeof(dap_chain_hash_fast_t), l_item); HASH_FIND(hh, l_srv->ban_list, &l_usage->client_pkey_hash, sizeof(dap_chain_hash_fast_t), l_item);
pthread_mutex_unlock(&l_srv->banlist_mutex); pthread_mutex_unlock(&l_srv->banlist_mutex);
if (l_item) { // client banned if (l_item) { // client banned
log_it(L_INFO, "Client pkey is banned!");
usages_in_grace_t *l_grace_item = NULL;
pthread_mutex_lock(&s_ht_grace_table_mutex);
HASH_FIND(hh, s_grace_table, &l_usage->tx_cond_hash, sizeof(dap_hash_fast_t), l_grace_item);
if (l_grace_item){
// Stop timer
dap_timerfd_delete_mt(l_grace_item->grace->stream_worker->worker, l_grace_item->grace->timer_es_uuid);
// finish grace
HASH_DEL(s_grace_table, l_grace_item);
DAP_DEL_Z(l_grace_item);
}
pthread_mutex_unlock(&s_ht_grace_table_mutex);
l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_RECEIPT_BANNED_PKEY_HASH ; l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_RECEIPT_BANNED_PKEY_HASH ;
dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof(l_err)); dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof(l_err));
if (l_usage->service->callbacks.response_error) if (l_usage->service->callbacks.response_error)
...@@ -579,26 +862,41 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg) ...@@ -579,26 +862,41 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg)
l_grace = DAP_NEW_Z(dap_chain_net_srv_grace_t); l_grace = DAP_NEW_Z(dap_chain_net_srv_grace_t);
UNUSED(l_grace); UNUSED(l_grace);
// Parse the request // Parse the request
// l_grace->request = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_request_t, sizeof(dap_stream_ch_chain_net_srv_pkt_request_t)); l_grace->request = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_request_t, sizeof(dap_stream_ch_chain_net_srv_pkt_request_t));
// l_grace->request->hdr.net_id = l_usage->net->pub.id; l_grace->request->hdr.net_id = l_usage->net->pub.id;
// memcpy(l_grace->request->hdr.token, l_usage->token_ticker, strlen(l_usage->token_ticker)); memcpy(l_grace->request->hdr.token, l_usage->token_ticker, strlen(l_usage->token_ticker));
// l_grace->request->hdr.srv_uid = l_usage->service->uid; l_grace->request->hdr.srv_uid = l_usage->service->uid;
// l_grace->request->hdr.tx_cond = l_usage->tx_cond_hash; l_grace->request->hdr.tx_cond = l_usage->tx_cond_hash;
// l_ch_chain_net_srv->srv_uid.uint64 = l_grace->request->hdr.srv_uid.uint64; l_ch_chain_net_srv->srv_uid.uint64 = l_grace->request->hdr.srv_uid.uint64;
// l_grace->request_size = l_ch_pkt->hdr.data_size; l_grace->request_size = l_ch_pkt->hdr.data_size;
// l_grace->ch_uuid = a_ch->uuid; l_grace->ch_uuid = a_ch->uuid;
// l_grace->stream_worker = a_ch->stream_worker; l_grace->stream_worker = a_ch->stream_worker;
// s_grace_period_control(l_grace); l_grace->usage = l_usage;
s_grace_period_start(l_grace);
DAP_DELETE(l_tx_in_hash_str);
break; break;
case DAP_CHAIN_MEMPOOl_RET_STATUS_NOT_ENOUGH: case DAP_CHAIN_MEMPOOl_RET_STATUS_NOT_ENOUGH:
// TODO send new tx cond request // TODO send new tx cond request
memset(&l_usage->tx_cond_hash, 0, sizeof(l_usage->tx_cond_hash));
DAP_DEL_Z(l_usage->receipt_next);
log_it(L_ERROR, "Tx cond have not enough funds"); log_it(L_ERROR, "Tx cond have not enough funds");
l_usage->is_waiting_new_tx_cond = true;
l_grace = DAP_NEW_Z(dap_chain_net_srv_grace_t);
// Parse the request
l_grace->request = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_request_t, sizeof(dap_stream_ch_chain_net_srv_pkt_request_t));
l_grace->request->hdr.net_id = l_usage->net->pub.id;
memcpy(l_grace->request->hdr.token, l_usage->token_ticker, strlen(l_usage->token_ticker));
l_grace->request->hdr.srv_uid = l_usage->service->uid;
l_grace->request->hdr.tx_cond = l_usage->tx_cond_hash;
l_ch_chain_net_srv->srv_uid.uint64 = l_grace->request->hdr.srv_uid.uint64;
l_grace->request_size = l_ch_pkt->hdr.data_size;
l_grace->ch_uuid = a_ch->uuid;
l_grace->stream_worker = a_ch->stream_worker;
l_grace->usage = l_usage;
s_grace_period_start(l_grace);
l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_ENOUGH; l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_ENOUGH;
dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof (l_err)); dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof (l_err));
// if (l_usage->service->callbacks.response_error) if (l_usage->service->callbacks.response_error)
// l_usage->service->callbacks.response_error(l_usage->service,l_usage->id, l_usage->client,&l_err,sizeof (l_err)); l_usage->service->callbacks.response_error(l_usage->service,l_usage->id, l_usage->client,&l_err,sizeof (l_err));
DAP_DELETE(l_tx_in_hash_str);
break; break;
case DAP_CHAIN_MEMPOOL_RET_STATUS_BAD_ARGUMENTS: case DAP_CHAIN_MEMPOOL_RET_STATUS_BAD_ARGUMENTS:
case DAP_CHAIN_MEMPOOl_RET_STATUS_WRONG_ADDR: case DAP_CHAIN_MEMPOOl_RET_STATUS_WRONG_ADDR:
...@@ -614,16 +912,17 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg) ...@@ -614,16 +912,17 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg)
dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof (l_err)); dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof (l_err));
if (l_usage->service->callbacks.response_error) if (l_usage->service->callbacks.response_error)
l_usage->service->callbacks.response_error(l_usage->service,l_usage->id, l_usage->client,&l_err,sizeof (l_err)); l_usage->service->callbacks.response_error(l_usage->service,l_usage->id, l_usage->client,&l_err,sizeof (l_err));
DAP_DELETE(l_tx_in_hash_str);
break; break;
} }
if (!l_usage->is_grace)
break;
break;
} }
l_success_size = sizeof(dap_stream_ch_chain_net_srv_pkt_success_hdr_t) + DAP_CHAIN_HASH_FAST_STR_SIZE;//sizeof(dap_chain_hash_fast_t); l_success_size = sizeof(dap_stream_ch_chain_net_srv_pkt_success_hdr_t) + DAP_CHAIN_HASH_FAST_STR_SIZE;//sizeof(dap_chain_hash_fast_t);
} else { } else {
l_success_size = sizeof(dap_stream_ch_chain_net_srv_pkt_success_hdr_t); l_success_size = sizeof(dap_stream_ch_chain_net_srv_pkt_success_hdr_t);
} }
dap_stream_ch_chain_net_srv_pkt_success_t *l_success = DAP_NEW_STACK_SIZE(dap_stream_ch_chain_net_srv_pkt_success_t, dap_stream_ch_chain_net_srv_pkt_success_t *l_success = DAP_NEW_STACK_SIZE(dap_stream_ch_chain_net_srv_pkt_success_t,
l_success_size); l_success_size);
memset(&l_success->hdr, 0, sizeof(l_success->hdr)); memset(&l_success->hdr, 0, sizeof(l_success->hdr));
...@@ -634,8 +933,9 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg) ...@@ -634,8 +933,9 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg)
if (l_usage->is_grace){ if (l_usage->is_grace){
char *l_hash_str = dap_hash_fast_to_str_new(&l_usage->tx_cond_hash); char *l_hash_str = dap_hash_fast_to_str_new(&l_usage->tx_cond_hash);
log_it(L_NOTICE, "Receipt is OK, but transaction %s can't be found. Start the grace period for %d seconds", l_hash_str, log_it(L_NOTICE, "Receipt is OK, but tx transaction %s %s. Start the grace period for %d seconds", l_hash_str,
l_srv->grace_period); l_usage->is_waiting_new_tx_cond ? "have no enough funds. New tx cond requested": "can't be found",
l_srv->grace_period);
DAP_DEL_Z(l_hash_str); DAP_DEL_Z(l_hash_str);
}else { }else {
char *l_hash_str = dap_hash_fast_to_str_new(&l_usage->tx_cond_hash); char *l_hash_str = dap_hash_fast_to_str_new(&l_usage->tx_cond_hash);
...@@ -708,10 +1008,51 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg) ...@@ -708,10 +1008,51 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg)
dap_chain_net_srv_usage_t * l_usage = NULL; dap_chain_net_srv_usage_t * l_usage = NULL;
l_usage = l_srv_session->usage_active; l_usage = l_srv_session->usage_active;
dap_stream_ch_chain_net_srv_pkt_request_t* l_responce = (dap_stream_ch_chain_net_srv_pkt_request_t*)l_ch_pkt->data; dap_stream_ch_chain_net_srv_pkt_request_t* l_responce = (dap_stream_ch_chain_net_srv_pkt_request_t*)l_ch_pkt->data;
l_usage->tx_cond_hash = l_responce->hdr.tx_cond;
char *l_tx_in_hash_str = dap_chain_hash_fast_to_str_new(&l_usage->tx_cond_hash); char *l_tx_in_hash_str = dap_chain_hash_fast_to_str_new(&l_responce->hdr.tx_cond);
log_it(L_NOTICE, "Received new tx cond %s", l_tx_in_hash_str); log_it(L_NOTICE, "Received new tx cond %s", l_tx_in_hash_str);
DAP_DELETE(l_tx_in_hash_str); DAP_DELETE(l_tx_in_hash_str);
l_usage->is_waiting_new_tx_cond = false;
usages_in_grace_t *l_curr_grace_item = NULL;
pthread_mutex_lock(&s_ht_grace_table_mutex);
HASH_FIND(hh, s_grace_table, &l_usage->tx_cond_hash, sizeof(dap_hash_fast_t), l_curr_grace_item);
pthread_mutex_unlock(&s_ht_grace_table_mutex);
// if (dap_hash_fast_compare(&l_responce->hdr.tx_cond, &l_usage->tx_cond_hash) || !l_usage->is_grace){ //check new tx not equals to old tx or tx waiting grace period is over
// // if equals delete receipt and tx and stop grace if running
// if (l_curr_grace_item){
// HASH_DEL(s_grace_table, l_curr_grace_item);
// dap_timerfd_delete_mt(l_curr_grace_item->grace->stream_worker->worker, l_curr_grace_item->grace->timer_es_uuid);
// }
// break;
// }
dap_chain_datum_tx_t *l_tx = dap_chain_ledger_tx_find_by_hash(l_usage->net->pub.ledger, &l_responce->hdr.tx_cond);
if (l_tx){
// Replace
if (l_curr_grace_item){
log_it(L_INFO, "Found tx in ledger by net tx responce handler. Finish waiting new tx grace period.");
// Stop timer
dap_timerfd_delete_mt(l_curr_grace_item->grace->stream_worker->worker, l_curr_grace_item->grace->timer_es_uuid);
// finish grace
l_usage->tx_cond_hash = l_responce->hdr.tx_cond;
l_curr_grace_item->grace->request->hdr.tx_cond = l_responce->hdr.tx_cond;
s_grace_period_finish(l_curr_grace_item);
}
}else{
if (l_curr_grace_item){
l_curr_grace_item->grace->usage->tx_cond_hash = l_responce->hdr.tx_cond;
l_curr_grace_item->grace->request->hdr.tx_cond = l_responce->hdr.tx_cond;
pthread_mutex_lock(&s_ht_grace_table_mutex);
HASH_DEL(s_grace_table, l_curr_grace_item);
l_curr_grace_item->tx_cond_hash = l_responce->hdr.tx_cond;
HASH_ADD(hh, s_grace_table, tx_cond_hash, sizeof(dap_hash_fast_t), l_curr_grace_item);
pthread_mutex_unlock(&s_ht_grace_table_mutex);
}
}
size_t l_success_size = sizeof (dap_stream_ch_chain_net_srv_pkt_success_hdr_t ); size_t l_success_size = sizeof (dap_stream_ch_chain_net_srv_pkt_success_hdr_t );
dap_stream_ch_chain_net_srv_pkt_success_t *l_success = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_success_t, dap_stream_ch_chain_net_srv_pkt_success_t *l_success = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_success_t,
l_success_size); l_success_size);
......
...@@ -29,6 +29,16 @@ ...@@ -29,6 +29,16 @@
#include "dap_stream_ch_pkt.h" #include "dap_stream_ch_pkt.h"
#include "dap_chain_common.h" #include "dap_chain_common.h"
#include "dap_chain.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.h"
#include "dap_chain_datum_tx_out_cond.h"
#include "dap_chain_datum_tx_receipt.h"
#include "dap_chain_mempool.h"
#include "dap_common.h"
typedef struct dap_stream_ch_chain_net_srv dap_stream_ch_chain_net_srv_t; typedef struct dap_stream_ch_chain_net_srv dap_stream_ch_chain_net_srv_t;
typedef void (*dap_stream_ch_chain_net_srv_callback_packet_t)(dap_stream_ch_chain_net_srv_t *, uint8_t, typedef void (*dap_stream_ch_chain_net_srv_callback_packet_t)(dap_stream_ch_chain_net_srv_t *, uint8_t,
...@@ -46,3 +56,5 @@ typedef struct dap_stream_ch_chain_net_srv { ...@@ -46,3 +56,5 @@ typedef struct dap_stream_ch_chain_net_srv {
uint8_t dap_stream_ch_chain_net_srv_get_id(); uint8_t dap_stream_ch_chain_net_srv_get_id();
int dap_stream_ch_chain_net_srv_init(void); int dap_stream_ch_chain_net_srv_init(void);
void dap_stream_ch_chain_net_srv_tx_cond_added_cb(void *a_arg, dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx);
...@@ -863,6 +863,8 @@ dap_chain_net_srv_t* dap_chain_net_srv_add(dap_chain_net_srv_uid_t a_uid, ...@@ -863,6 +863,8 @@ dap_chain_net_srv_t* dap_chain_net_srv_add(dap_chain_net_srv_uid_t a_uid,
l_sdata->srv = l_srv; l_sdata->srv = l_srv;
dap_chain_net_srv_parse_pricelist(l_srv, a_config_section); dap_chain_net_srv_parse_pricelist(l_srv, a_config_section);
HASH_ADD(hh, s_srv_list, uid, sizeof(l_srv->uid), l_sdata); HASH_ADD(hh, s_srv_list, uid, sizeof(l_srv->uid), l_sdata);
if (l_srv->pricelist)
dap_chain_ledger_tx_add_notify(l_srv->pricelist->net->pub.ledger, dap_stream_ch_chain_net_srv_tx_cond_added_cb, NULL);
}else{ }else{
log_it(L_ERROR, "Already present service with 0x%016"DAP_UINT64_FORMAT_X, a_uid.uint64); log_it(L_ERROR, "Already present service with 0x%016"DAP_UINT64_FORMAT_X, a_uid.uint64);
} }
......
...@@ -47,6 +47,22 @@ dap_chain_net_srv_stream_session_t * dap_chain_net_srv_stream_session_create( da ...@@ -47,6 +47,22 @@ dap_chain_net_srv_stream_session_t * dap_chain_net_srv_stream_session_create( da
return l_session_srv; return l_session_srv;
} }
/**
* @brief dap_chain_net_srv_stream_session_create
* @param a_session
* @return
*/
void dap_chain_net_srv_stream_session_delete( dap_stream_session_t * a_session)
{
if (!a_session){
log_it (L_ERROR, "Session is NULL!");
return;
}
dap_chain_net_srv_stream_session_t * l_session_srv = a_session->_inheritor;
dap_chain_net_srv_usage_delete(l_session_srv);
}
/** /**
* @brief dap_chain_net_srv_usage_add * @brief dap_chain_net_srv_usage_add
* @param a_srv_session * @param a_srv_session
...@@ -78,21 +94,20 @@ dap_chain_net_srv_usage_t* dap_chain_net_srv_usage_add (dap_chain_net_srv_stream ...@@ -78,21 +94,20 @@ dap_chain_net_srv_usage_t* dap_chain_net_srv_usage_add (dap_chain_net_srv_stream
* @param a_usage * @param a_usage
* @return * @return
*/ */
void dap_chain_net_srv_usage_delete (dap_chain_net_srv_stream_session_t * a_srv_session, void dap_chain_net_srv_usage_delete (dap_chain_net_srv_stream_session_t * a_srv_session)
dap_chain_net_srv_usage_t* a_usage)
{ {
if ( a_usage->receipt ) if ( a_srv_session->usage_active->receipt )
DAP_DELETE( a_usage->receipt ); DAP_DELETE( a_srv_session->usage_active->receipt );
if ( a_usage->client ){ if ( a_srv_session->usage_active->receipt_next )
for (dap_chain_net_srv_client_remote_t * l_srv_client = a_usage->client, * tmp = NULL; l_srv_client; ){ DAP_DELETE( a_srv_session->usage_active->receipt_next );
if ( a_srv_session->usage_active->client ){
for (dap_chain_net_srv_client_remote_t * l_srv_client = a_srv_session->usage_active->client, * tmp = NULL; l_srv_client; ){
tmp = l_srv_client; tmp = l_srv_client;
l_srv_client = l_srv_client->next; l_srv_client = l_srv_client->next;
DAP_DELETE( tmp); DAP_DELETE( tmp);
} }
} }
DAP_DELETE( a_usage ); DAP_DEL_Z(a_srv_session->usage_active);
} }
/** /**
......
...@@ -186,6 +186,7 @@ typedef struct dap_chain_net_srv_grace { ...@@ -186,6 +186,7 @@ typedef struct dap_chain_net_srv_grace {
dap_stream_worker_t *stream_worker; dap_stream_worker_t *stream_worker;
dap_stream_ch_uuid_t ch_uuid; dap_stream_ch_uuid_t ch_uuid;
dap_chain_net_srv_usage_t *usage; dap_chain_net_srv_usage_t *usage;
dap_events_socket_uuid_t timer_es_uuid;
dap_stream_ch_chain_net_srv_pkt_request_t *request; dap_stream_ch_chain_net_srv_pkt_request_t *request;
size_t request_size; size_t request_size;
} dap_chain_net_srv_grace_t; } dap_chain_net_srv_grace_t;
......
...@@ -55,6 +55,7 @@ typedef struct dap_chain_net_srv_usage{ ...@@ -55,6 +55,7 @@ typedef struct dap_chain_net_srv_usage{
bool is_active; bool is_active;
bool is_free; bool is_free;
bool is_grace; bool is_grace;
bool is_waiting_new_tx_cond;
// UT_hash_handle hh; // // UT_hash_handle hh; //
} dap_chain_net_srv_usage_t; } dap_chain_net_srv_usage_t;
...@@ -91,9 +92,9 @@ typedef struct dap_chain_net_srv_stream_session { ...@@ -91,9 +92,9 @@ typedef struct dap_chain_net_srv_stream_session {
#define DAP_CHAIN_NET_SRV_STREAM_SESSION(a) ((dap_chain_net_srv_stream_session_t *) (a)->_inheritor ) #define DAP_CHAIN_NET_SRV_STREAM_SESSION(a) ((dap_chain_net_srv_stream_session_t *) (a)->_inheritor )
dap_chain_net_srv_stream_session_t * dap_chain_net_srv_stream_session_create( dap_stream_session_t * a_session); dap_chain_net_srv_stream_session_t * dap_chain_net_srv_stream_session_create( dap_stream_session_t * a_session);
void dap_chain_net_srv_stream_session_delete( dap_stream_session_t * a_session);
dap_chain_net_srv_usage_t* dap_chain_net_srv_usage_add (dap_chain_net_srv_stream_session_t * a_srv_session, dap_chain_net_srv_usage_t* dap_chain_net_srv_usage_add (dap_chain_net_srv_stream_session_t * a_srv_session,
dap_chain_net_t * a_net, dap_chain_net_srv_t * a_srv); dap_chain_net_t * a_net, dap_chain_net_srv_t * a_srv);
void dap_chain_net_srv_usage_delete (dap_chain_net_srv_stream_session_t * a_srv_session, void dap_chain_net_srv_usage_delete (dap_chain_net_srv_stream_session_t * a_srv_session);
dap_chain_net_srv_usage_t* a_usage);
dap_chain_net_srv_usage_t* dap_chain_net_srv_usage_find_unsafe (dap_chain_net_srv_stream_session_t * a_srv_session, dap_chain_net_srv_usage_t* dap_chain_net_srv_usage_find_unsafe (dap_chain_net_srv_stream_session_t * a_srv_session,
uint32_t a_usage_id); uint32_t a_usage_id);
...@@ -1076,7 +1076,7 @@ void s_ch_vpn_new(dap_stream_ch_t* a_ch, void* a_arg) ...@@ -1076,7 +1076,7 @@ void s_ch_vpn_new(dap_stream_ch_t* a_ch, void* a_arg)
dap_chain_net_srv_stream_session_t * l_srv_session = (dap_chain_net_srv_stream_session_t *) a_ch->stream->session->_inheritor; dap_chain_net_srv_stream_session_t * l_srv_session = (dap_chain_net_srv_stream_session_t *) a_ch->stream->session->_inheritor;
l_srv_vpn->usage_id = l_srv_session->usage_active? l_srv_session->usage_active->id : 0; l_srv_vpn->usage_id = l_srv_session->usage_active ? l_srv_session->usage_active->id : 0;
if( l_srv_vpn->usage_id) { if( l_srv_vpn->usage_id) {
// So complicated to update usage client to be sure that nothing breaks it // So complicated to update usage client to be sure that nothing breaks it
...@@ -1088,7 +1088,6 @@ void s_ch_vpn_new(dap_stream_ch_t* a_ch, void* a_arg) ...@@ -1088,7 +1088,6 @@ void s_ch_vpn_new(dap_stream_ch_t* a_ch, void* a_arg)
} }
pthread_rwlock_unlock(&s_clients_rwlock); pthread_rwlock_unlock(&s_clients_rwlock);
} }
} }
...@@ -1146,6 +1145,7 @@ static void s_ch_vpn_delete(dap_stream_ch_t* a_ch, void* arg) ...@@ -1146,6 +1145,7 @@ static void s_ch_vpn_delete(dap_stream_ch_t* a_ch, void* arg)
l_ch_vpn->ch = NULL; l_ch_vpn->ch = NULL;
l_ch_vpn->net_srv = NULL; l_ch_vpn->net_srv = NULL;
l_ch_vpn->is_allowed =false; l_ch_vpn->is_allowed =false;
DAP_DEL_Z(a_ch->internal);
} }
/** /**
...@@ -1162,21 +1162,20 @@ static void s_update_limits(dap_stream_ch_t * a_ch , ...@@ -1162,21 +1162,20 @@ static void s_update_limits(dap_stream_ch_t * a_ch ,
bool l_issue_new_receipt = false; bool l_issue_new_receipt = false;
// Check if there are time limits // Check if there are time limits
if (a_usage->is_free) if (a_usage->is_free || !a_usage->receipt || !a_usage->is_active)
return; return;
if (a_usage->receipt->receipt_info.units_type.enm == SERV_UNIT_DAY || if (a_usage->receipt->receipt_info.units_type.enm == SERV_UNIT_DAY ||
a_usage->receipt->receipt_info.units_type.enm == SERV_UNIT_SEC){ a_usage->receipt->receipt_info.units_type.enm == SERV_UNIT_SEC){
time_t l_current_limit_ts = 0; time_t l_current_limit_ts = 0;
if ( a_usage->receipt){
switch( a_usage->receipt->receipt_info.units_type.enm){ switch( a_usage->receipt->receipt_info.units_type.enm){
case SERV_UNIT_DAY:{ case SERV_UNIT_DAY:{
l_current_limit_ts = (time_t)a_usage->receipt->receipt_info.units*24*3600; l_current_limit_ts = (time_t)a_usage->receipt->receipt_info.units*24*3600;
} break; } break;
case SERV_UNIT_SEC:{ case SERV_UNIT_SEC:{
l_current_limit_ts = (time_t)a_usage->receipt->receipt_info.units; l_current_limit_ts = (time_t)a_usage->receipt->receipt_info.units;
} }
}
} }
a_srv_session->limits_ts -= time(NULL) - a_srv_session->last_update_ts; a_srv_session->limits_ts -= time(NULL) - a_srv_session->last_update_ts;
......
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