diff --git a/dap-sdk/core/include/dap_common.h b/dap-sdk/core/include/dap_common.h index 874a5dc568b5c008beefcfcfbeeeb7d9e6c5a460..c40a3791fd59dddad6d5c92ac320d8623aa972b2 100755 --- a/dap-sdk/core/include/dap_common.h +++ b/dap-sdk/core/include/dap_common.h @@ -413,6 +413,12 @@ void dap_lendian_put32(uint8_t *a_buf, uint32_t a_val); uint64_t dap_lendian_get64(const uint8_t *a_buf); void dap_lendian_put64(uint8_t *a_buf, uint64_t a_val); +// crossplatform usleep +#define DAP_USEC_PER_SEC 1000000 +void dap_usleep(time_t a_microseconds); + + + #ifdef __MINGW32__ int exec_silent(const char *a_cmd); #endif diff --git a/dap-sdk/core/include/dap_strfuncs.h b/dap-sdk/core/include/dap_strfuncs.h index 79f00942eaeb5050de51017e3d9ab36b2cd165e6..b929c3a891bf169fc475dfbc52f9a1f5a604f0db 100755 --- a/dap-sdk/core/include/dap_strfuncs.h +++ b/dap-sdk/core/include/dap_strfuncs.h @@ -112,6 +112,3 @@ char *dap_itoa128(char *a_str, int128_t a_value, int a_base); char *_strndup(const char *str, unsigned long len); #endif -#define DAP_USEC_PER_SEC 1000000 -void dap_usleep(time_t a_microseconds); - diff --git a/dap-sdk/core/src/dap_common.c b/dap-sdk/core/src/dap_common.c index ea8ffebd01d7250b93e8f5aae6ed0f936c6efa63..09909bb97f9c431f17ecfcfac03d75569a16b102 100755 --- a/dap-sdk/core/src/dap_common.c +++ b/dap-sdk/core/src/dap_common.c @@ -1020,3 +1020,23 @@ void dap_lendian_put64(uint8_t *a_buf, uint64_t a_val) dap_lendian_put32(a_buf, a_val); dap_lendian_put32(a_buf + 4, a_val >> 32); } + +/** + * dap_usleep: + * @a_microseconds: number of microseconds to pause + * + * Pauses the current thread for the given number of microseconds. + */ +void dap_usleep(time_t a_microseconds) +{ +#ifdef DAP_OS_WINDOWS + Sleep (a_microseconds / 1000); +#else + struct timespec l_request, l_remaining; + l_request.tv_sec = a_microseconds / DAP_USEC_PER_SEC; + l_request.tv_nsec = 1000 * (a_microseconds % DAP_USEC_PER_SEC); + while(nanosleep(&l_request, &l_remaining) == -1 && errno == EINTR) + l_request = l_remaining; +#endif +} + diff --git a/dap-sdk/core/src/dap_strfuncs.c b/dap-sdk/core/src/dap_strfuncs.c index 2685947f96e330bdc41bb865cfac7434e6e2d326..a766b125633417400291f7f06c78a35b2ed9a02f 100755 --- a/dap-sdk/core/src/dap_strfuncs.c +++ b/dap-sdk/core/src/dap_strfuncs.c @@ -866,22 +866,3 @@ char *_strndup(const char *str, unsigned long len) { } #endif -/** - * dap_usleep: - * @a_microseconds: number of microseconds to pause - * - * Pauses the current thread for the given number of microseconds. - */ -void dap_usleep(time_t a_microseconds) -{ -#ifdef _WIN32 - Sleep (a_microseconds / 1000); -#else - struct timespec l_request, l_remaining; - l_request.tv_sec = a_microseconds / DAP_USEC_PER_SEC; - l_request.tv_nsec = 1000 * (a_microseconds % DAP_USEC_PER_SEC); - while(nanosleep(&l_request, &l_remaining) == -1 && errno == EINTR) - l_request = l_remaining; -#endif -} - diff --git a/dap-sdk/net/core/dap_client_remote.c b/dap-sdk/net/core/dap_client_remote.c deleted file mode 100644 index 567ef6954111c59af407bca8e043c158dddbd74d..0000000000000000000000000000000000000000 --- a/dap-sdk/net/core/dap_client_remote.c +++ /dev/null @@ -1,354 +0,0 @@ -/* - * Authors: - * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net> - * DeM Labs Inc. https://demlabs.net - * Kelvin Project https://github.com/kelvinblockchain - * Copyright (c) 2017-2018 - * All rights reserved. - - This file is part of DAP (Deus Applications Prototypes) the open source project - - DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - DAP is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. -*/ -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> - -#ifndef _WIN32 -#include <unistd.h> -#include <arpa/inet.h> -#include <sys/epoll.h> -#include <sys/timerfd.h> -#else -#include <winsock2.h> -#include <windows.h> -#include <mswsock.h> -#include <ws2tcpip.h> -#include <io.h> -#include <pthread.h> -#endif - -#include "dap_common.h" -#include "dap_server.h" -#include "dap_client_remote.h" - -#define LOG_TAG "dap_client_remote" - -/** - * @brief dap_client_init Init clients module - * @return Zero if ok others if no - */ -int dap_client_remote_init( ) -{ - log_it( L_NOTICE, "Initialized socket client module" ); - - return 0; -} - -/** - * @brief dap_client_deinit Deinit clients module - */ -void dap_client_remote_deinit( ) -{ - - return; -} - -/** - * @brief _save_ip_and_port - * @param cl - */ -void _save_ip_and_port( dap_client_remote_t * cl ) -{ - struct sockaddr_in ip_adr_get; - socklen_t ip_adr_len = sizeof(ip_adr_get); - - int l_res = getpeername( cl->socket, (struct sockaddr * restrict)&ip_adr_get, &ip_adr_len ); - if(l_res == -1) - log_it(L_ERROR, "%s error: %s", __PRETTY_FUNCTION__, strerror(errno)); - - cl->port = ntohs( ip_adr_get.sin_port ); - strcpy( cl->s_ip, inet_ntoa(ip_adr_get.sin_addr) ); -} - -/** - * @brief dap_client_remote_create Create new client and add it to the list - * @param sh Server instance - * @param s Client's socket - * @return Pointer to the new list's node - */ -dap_client_remote_t *dap_client_remote_create( dap_server_t *sh, int s, dap_server_thread_t *t ) -{ - dap_client_remote_t *dsc = DAP_NEW_Z( dap_client_remote_t ); - - dap_random_string_fill( dsc->id, CLIENT_ID_SIZE ); - - dsc->socket = s; - dsc->server = sh; - dsc->tn = t->thread_num; - dsc->thread = t; - dsc->efd = t->epoll_fd; - dsc->time_connection = dsc->last_time_active = time( NULL) ; - - dsc->pevent.events = EPOLLIN | EPOLLOUT | EPOLLERR; - dsc->pevent.data.ptr = dsc; - - dsc->flags = DAP_SOCK_READY_TO_READ; - dsc->buf_out_offset = 0; - - _save_ip_and_port( dsc ); - - pthread_mutex_lock( &t->mutex_on_hash ); - HASH_ADD_INT( t->hclients, socket, dsc ); - pthread_mutex_unlock( &t->mutex_on_hash ); - - if ( sh->client_new_callback ) - sh->client_new_callback( dsc, NULL ); // Init internal structure - - log_it(L_DEBUG, "Create remote client: ip: %s port %d", dsc->s_ip, dsc->port ); - - //log_it(L_DEBUG, "Create new client. ID: %s", dsc->id); - return dsc; -} - -/** - * @brief safe_client_remove Removes the client from the list - * @param sc Client instance - */ -void dap_client_remote_remove( dap_client_remote_t *sc ) -{ - log_it(L_DEBUG, "dap_client_remote_remove [THREAD %u] efd %u", sc->tn , sc->efd ); - - dap_server_thread_t *t = sc->thread; - - pthread_mutex_lock( &t->mutex_on_hash ); - HASH_DEL( t->hclients, sc ); - pthread_mutex_unlock( &t->mutex_on_hash ); - - if( sc->server->client_delete_callback ) { - sc->server->client_delete_callback( sc, NULL ); // Init internal structure - } - - if( sc->_inheritor ) { - free( sc->_inheritor ); - } - - if( sc->socket ) { - log_it( L_INFO, "dap_client_remote_remove close( %d );", sc->socket ); -#ifdef _WIN32 - closesocket( sc->socket ); -#else - close( sc->socket ); -#endif - } - - free( sc ); -} - -/** - * @brief dap_server_client_find - * @param sock - * @param sh - * @return - */ -dap_client_remote_t *dap_client_remote_find( int sock, dap_server_thread_t *t ) -{ - dap_client_remote_t *ret = NULL; - - pthread_mutex_lock( &t->mutex_on_hash ); - HASH_FIND_INT( t->hclients, &sock, ret ); - pthread_mutex_unlock( &t->mutex_on_hash ); - - return ret; -} - -/** - * @brief dap_client_remote_ready_to_read - * @param sc - * @param isReady - */ -void dap_client_remote_ready_to_read( dap_client_remote_t *sc, bool is_ready ) -{ - if( is_ready == (bool)(sc->flags & DAP_SOCK_READY_TO_READ) ) - return; - -// log_it( L_ERROR, "remote_ready_to_read() %u efd %X", sc->socket, sc->efd ); - - if ( is_ready ) - sc->flags |= DAP_SOCK_READY_TO_READ; - else - sc->flags ^= DAP_SOCK_READY_TO_READ; - - int events = EPOLLERR; - - if( sc->flags & DAP_SOCK_READY_TO_READ ) - events |= EPOLLIN; - - if( sc->flags & DAP_SOCK_READY_TO_WRITE ) - events |= EPOLLOUT; - - sc->pevent.events = events; - - if( epoll_ctl(sc->efd, EPOLL_CTL_MOD, sc->socket, &sc->pevent) != 0 ) - log_it( L_ERROR, "epoll_ctl failed 000" ); -} - -/** - * @brief dap_client_remote_ready_to_write - * @param sc - * @param isReady - */ -void dap_client_remote_ready_to_write( dap_client_remote_t *sc, bool is_ready ) -{ - if ( is_ready == (bool)(sc->flags & DAP_SOCK_READY_TO_WRITE) ) - return; - -// log_it( L_ERROR, "remote_ready_to_write() %u efd %X", sc->socket, sc->efd ); - - if ( is_ready ) - sc->flags |= DAP_SOCK_READY_TO_WRITE; - else - sc->flags ^= DAP_SOCK_READY_TO_WRITE; - - int events = EPOLLERR; - - if( sc->flags & DAP_SOCK_READY_TO_READ ) - events |= EPOLLIN; - - if( sc->flags & DAP_SOCK_READY_TO_WRITE ) - events |= EPOLLOUT; - - sc->pevent.events = events; - - if( epoll_ctl(sc->efd, EPOLL_CTL_MOD, sc->socket, &sc->pevent) != 0 ) - log_it( L_ERROR, "epoll_ctl failed 001" ); -} - -/** - * @brief dap_client_write Write data to the client - * @param sc Client instance - * @param data Pointer to data - * @param data_size Size of data to write - * @return Number of bytes that were placed into the buffer - */ -size_t dap_client_remote_write( dap_client_remote_t *sc, const void * data, size_t data_size ) -{ - if ( sc->buf_out_size + data_size > sizeof(sc->buf_out) ) { - log_it( L_WARNING, "Client buffer overflow. Packet loosed" ); - return 0; - } - - memcpy( sc->buf_out + sc->buf_out_size, data, data_size ); - sc->buf_out_size += data_size; - return data_size; -} - -/** - * @brief dap_client_write_f Write formatted text to the client - * @param a_client Client instance - * @param a_format Format - * @return Number of bytes that were placed into the buffer - */ -size_t dap_client_remote_write_f( dap_client_remote_t *a_client, const char * a_format, ... ) -{ - size_t max_data_size = sizeof( a_client->buf_out ) - a_client->buf_out_size; - - va_list ap; - va_start( ap, a_format ); - - int ret = dap_vsnprintf( a_client->buf_out + a_client->buf_out_size, max_data_size, a_format, ap ); - - va_end( ap ); - - if( ret > 0 ) { - a_client->buf_out_size += (unsigned long)ret; - return (size_t)ret; - } - else { - log_it( L_ERROR, "Can't write out formatted data '%s'", a_format ); - return 0; - } -} - -/** - * @brief dap_client_read Read data from input buffer - * @param a_client Client instasnce - * @param a_data Pointer to memory where to store the data - * @param a_data_size Size of data to read - * @return Actual bytes number that were read - */ -size_t dap_client_remote_read( dap_client_remote_t *a_client, void *a_data, size_t a_data_size ) -{ - if ( a_data_size < a_client->buf_in_size ) { - - memcpy( a_data, a_client->buf_in, a_data_size ); - memmove( a_client->buf_in, a_client->buf_in + a_data_size, a_client->buf_in_size - a_data_size ); - } - else { - if ( a_data_size > a_client->buf_in_size ) { - a_data_size = a_client->buf_in_size; - } - memcpy( a_data, a_client->buf_in, a_data_size ); - } - - a_client->buf_in_size -= a_data_size; - - return a_data_size; -} - - -/** - * @brief dap_client_remote_shrink_client_buf_in Shrink input buffer (shift it left) - * @param a_client Client instance - * @param a_shrink_size Size on wich we shrink the buffer with shifting it left - */ -void dap_client_remote_shrink_buf_in( dap_client_remote_t *a_client, size_t a_shrink_size ) -{ -#if 0 - if((a_shrink_size==0)||(a_client->buf_in_size==0) ){ - return; - }else if(a_client->buf_in_size>a_shrink_size){ - size_t buf_size=a_client->buf_in_size-a_shrink_size; - void * buf = malloc(buf_size); - memcpy(buf,a_client->buf_in+ a_shrink_size,buf_size ); - memcpy(a_client->buf_in,buf,buf_size); - a_client->buf_in_size=buf_size; - free(buf); - }else { - a_client->buf_in_size=0; - } -#endif - - if ( a_shrink_size == 0 || a_client->buf_in_size == 0 ) - return; - - if ( a_client->buf_in_size > a_shrink_size ) { - - size_t buf_size = a_client->buf_in_size - a_shrink_size; - memmove( a_client->buf_in, a_client->buf_in + a_shrink_size, buf_size ); -/** - void *buf = malloc( buf_size ); - memcpy( buf, a_client->buf_in + a_shrink_size, buf_size ); - memcpy( a_client->buf_in, buf, buf_size ); - // holy shit - a_client->buf_in_size = buf_size; - free( buf ); -**/ - a_client->buf_in_size = buf_size; - } - else { - a_client->buf_in_size = 0; - } -} diff --git a/dap-sdk/net/core/dap_events.c b/dap-sdk/net/core/dap_events.c index 042ff1895d00c77c690ef2456795df746b8cfca8..c54c5472a54514896bd0d595bc539b70f3656483 100644 --- a/dap-sdk/net/core/dap_events.c +++ b/dap-sdk/net/core/dap_events.c @@ -31,29 +31,32 @@ #include <stddef.h> #include <stdint.h> -#ifndef _WIN32 +#ifdef DAP_OS_UNIX #include <arpa/inet.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/types.h> #include <sys/stat.h> - -#include <sys/epoll.h> +#endif #include <netdb.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <signal.h> +#include <sched.h> -#if 1 +#ifdef DAP_OS_LINUX #include <sys/timerfd.h> -#elif defined(DAP_OS_ANDROID) +#endif + +#if defined(DAP_OS_ANDROID) #define NO_POSIX_SHED #define NO_TIMER +#else #endif -#else +#ifdef DAP_OS_WINDOWS #include <winsock2.h> #include <windows.h> #include <mswsock.h> @@ -63,7 +66,6 @@ #endif #include <utlist.h> -#include <sched.h> #include "dap_common.h" #include "dap_strfuncs.h" @@ -71,28 +73,13 @@ #include "dap_events.h" #include "dap_events_socket.h" -#define DAP_MAX_EPOLL_EVENTS 8192 - -//typedef struct open_connection_info_s { -// dap_events_socket_t *es; -// struct open_connection_info *prev; -// struct open_connection_info *next; -//} dap_events_socket_info_t; -//dap_events_socket_info_t **s_dap_events_sockets; #define LOG_TAG "dap_events" -static uint32_t s_threads_count = 1; -static time_t s_connection_timeout = 6000; -static struct epoll_event *g_epoll_events = NULL; -static volatile bool bEventsAreActive = true; - bool s_workers_init = false; +static uint32_t s_threads_count = 1; dap_worker_t *s_workers = NULL; dap_thread_t *s_threads = NULL; -static void s_new_es_callback( dap_events_socket_t * a_es, void * a_arg); -static void s_delete_es_callback( dap_events_socket_t * a_es, void * a_arg); -static void s_reassign_es_callback( dap_events_socket_t * a_es, void * a_arg); uint32_t dap_get_cpu_count( ) @@ -125,39 +112,34 @@ uint32_t dap_get_cpu_count( ) * @arg a_threads_count number of events processor workers in parallel threads * @return Zero if ok others if no */ -int32_t dap_events_init( uint32_t a_threads_count, size_t conn_timeout ) +int dap_events_init( uint32_t a_threads_count, size_t a_conn_timeout ) { - s_threads_count = a_threads_count ? a_threads_count : dap_get_cpu_count( ); - - if ( conn_timeout ) - s_connection_timeout = conn_timeout; - - s_workers = (dap_worker_t *) calloc( 1, sizeof(dap_worker_t) * s_threads_count ); - s_threads = (dap_thread_t *) calloc( 1, sizeof(dap_thread_t) * s_threads_count ); - if ( !s_workers || !s_threads ) - goto err; + s_threads_count = a_threads_count ? a_threads_count : dap_get_cpu_count( ); - g_epoll_events = (struct epoll_event *)malloc( sizeof(struct epoll_event) * DAP_MAX_EPOLL_EVENTS * s_threads_count ); - if ( !g_epoll_events ) - goto err; + s_workers = DAP_NEW_S_SIZE(dap_worker_t,sizeof(dap_worker_t) * s_threads_count ); + s_threads = DAP_NEW_Z_SIZE(dap_thread_t, sizeof(dap_thread_t) * s_threads_count ); + if ( !s_workers || !s_threads ) + return -1; - if ( dap_events_socket_init() != 0 ) { + s_workers_init = true; - log_it( L_CRITICAL, "Can't init client submodule dap_events_socket_init( )" ); - goto err; - } - s_workers_init = true; + dap_worker_init(a_conn_timeout); + if ( dap_events_socket_init() != 0 ) { + log_it( L_CRITICAL, "Can't init client submodule dap_events_socket_init( )" ); + goto err; + } - log_it( L_NOTICE, "Initialized socket server module" ); + log_it( L_NOTICE, "Initialized socket server module" ); - #ifndef _WIN32 +#ifdef DAP_OS_UNIX signal( SIGPIPE, SIG_IGN ); - #endif - return 0; +#endif + return 0; err: - dap_events_deinit( ); - return -1; + dap_events_deinit(); + dap_worker_deinit(); + return -1; } /** @@ -165,16 +147,13 @@ err: */ void dap_events_deinit( ) { - dap_events_socket_deinit( ); - - if ( g_epoll_events ) - free( g_epoll_events ); + dap_events_socket_deinit(); + dap_worker_deinit(); + if ( s_threads ) + DAP_DELETE( s_threads ); - if ( s_threads ) - free( s_threads ); - - if ( s_workers ) - free( s_workers ); + if ( s_workers ) + DAP_DELETE( s_workers ); } /** @@ -197,531 +176,124 @@ dap_events_t * dap_events_new( ) */ void dap_events_delete( dap_events_t *a_events ) { - dap_events_socket_t *cur, *tmp; - - if ( a_events ) { - - HASH_ITER( hh, a_events->sockets,cur, tmp ) { - dap_events_socket_delete_unsafe( cur, true ); - } - - if ( a_events->_inheritor ) - free( a_events->_inheritor ); - - pthread_rwlock_destroy( &a_events->servers_rwlock ); - pthread_rwlock_destroy( &a_events->sockets_rwlock ); - - free( a_events ); - } -} - -/** - * @brief s_socket_info_all_check_activity - * @param n_thread - * @param sh - */ -static void s_socket_all_check_activity( dap_worker_t *dap_worker, dap_events_t *a_events, time_t cur_time ) -{ - dap_events_socket_t *a_es, *tmp; - - pthread_rwlock_rdlock(&a_events->sockets_rwlock); - HASH_ITER(hh, a_events->sockets, a_es, tmp ) { - - if ( a_es->type == DESCRIPTOR_TYPE_FILE) - continue; - - if ( !a_es->kill_signal && cur_time >= (time_t)a_es->last_time_active + s_connection_timeout && !a_es->no_close ) { + if (a_events) { + dap_events_socket_t *l_cur, *l_tmp; + HASH_ITER( hh, a_events->sockets,l_cur, l_tmp ) { + dap_events_socket_delete_unsafe( l_cur, true ); + } - log_it( L_INFO, "Socket %u timeout, closing...", a_es->socket ); - if (a_es->callbacks.error_callback) { - a_es->callbacks.error_callback(a_es, (void *)ETIMEDOUT); - } + if ( a_events->_inheritor ) + DAP_DELETE( a_events->_inheritor ); - if ( epoll_ctl( dap_worker->epoll_fd, EPOLL_CTL_DEL, a_es->socket, &a_es->ev) == -1 ) - log_it( L_ERROR,"Can't remove event socket's handler from the epoll_fd" ); - else - log_it( L_DEBUG,"Removed epoll's event from dap_worker #%u", dap_worker->id ); + pthread_rwlock_destroy( &a_events->servers_rwlock ); + pthread_rwlock_destroy( &a_events->sockets_rwlock ); - pthread_rwlock_unlock(&a_events->sockets_rwlock); - dap_events_socket_delete_unsafe(a_es, true ); - pthread_rwlock_rdlock(&a_events->sockets_rwlock); + DAP_DELETE( a_events ); } - } - pthread_rwlock_unlock(&a_events->sockets_rwlock); - } /** - * @brief s_thread_worker_function - * @param arg - * @return + * @brief sa_server_loop Main server loop + * @param sh Server instance + * @return Zero if ok others if not */ -static void *s_thread_worker_function(void *arg) +int dap_events_start( dap_events_t *a_events ) { - dap_events_socket_t *l_cur; - dap_worker_t *l_worker = (dap_worker_t *) arg; - time_t l_next_time_timeout_check = time( NULL) + s_connection_timeout / 2; - uint32_t l_tn = l_worker->id; - -#ifndef _WIN32 -#ifndef NO_POSIX_SHED - cpu_set_t mask; - CPU_ZERO(&mask); - CPU_SET(l_tn, &mask); - - int err; -#ifndef __ANDROID__ - err = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &mask); -#else - err = sched_setaffinity(pthread_self(), sizeof(cpu_set_t), &mask); -#endif - if(err) - { - log_it(L_CRITICAL, "Error pthread_setaffinity_np() You really have %d or more core in CPU?", *(int* )arg); - abort(); - } -#endif -#else - - if ( !SetThreadAffinityMask( GetCurrentThread(), (DWORD_PTR)(1 << tn) ) ) { - log_it( L_CRITICAL, "Error pthread_setaffinity_np() You really have %d or more core in CPU?", tn ); - abort(); - } - #endif - - l_worker->event_new_es = dap_events_socket_create_type_event( l_worker, s_new_es_callback); - l_worker->event_delete_es = dap_events_socket_create_type_event( l_worker, s_new_es_callback); - - log_it(L_INFO, "Worker %d started, epoll fd %d", l_worker->id, l_worker->epoll_fd); - - struct epoll_event *events = &g_epoll_events[ DAP_MAX_EPOLL_EVENTS * l_tn]; - -// memset( &ev, 0, sizeof(ev) ); -// memset( &events, 0, sizeof(events) ); - - size_t total_sent; - int bytes_sent = 0; - - while(bEventsAreActive) { - - int selected_sockets = epoll_wait(l_worker->epoll_fd, events, DAP_MAX_EPOLL_EVENTS, 1000); - - if(selected_sockets == -1) { - if( errno == EINTR) - continue; - log_it(L_ERROR, "Worker thread %d got errno: %d", l_worker->id, errno); - break; - } - - time_t cur_time = time( NULL); - for(int32_t n = 0; n < selected_sockets; n++) { - - l_cur = (dap_events_socket_t *) events[n].data.ptr; - - if(!l_cur) { - - log_it(L_ERROR, "dap_events_socket NULL"); - continue; - } - l_cur->last_time_active = cur_time; - //log_it(L_DEBUG, "Worker=%d fd=%d socket=%d event=0x%x(%d)", w->number_thread, w->epoll_fd,cur->socket, events[n].events,events[n].events); - int l_sock_err = 0, l_sock_err_size = sizeof(l_sock_err); - //connection already closed (EPOLLHUP - shutdown has been made in both directions) - if(events[n].events & EPOLLHUP) { // && events[n].events & EPOLLERR) { - switch (l_cur->type ){ - case DESCRIPTOR_TYPE_SOCKET_LISTENING: - case DESCRIPTOR_TYPE_SOCKET: - getsockopt(l_cur->socket, SOL_SOCKET, SO_ERROR, (void *)&l_sock_err, (socklen_t *)&l_sock_err_size); - //if(!(events[n].events & EPOLLIN)) - //cur->no_close = false; - if (l_sock_err) { - l_cur->flags |= DAP_SOCK_SIGNAL_CLOSE; - log_it(L_DEBUG, "Socket shutdown (EPOLLHUP): %s", strerror(l_sock_err)); - } - default: log_it(L_WARNING, "Unimplemented EPOLLHUP for socket type %d", l_cur->type); - } - } - - if(events[n].events & EPOLLERR) { - switch (l_cur->type ){ - case DESCRIPTOR_TYPE_SOCKET_LISTENING: - case DESCRIPTOR_TYPE_SOCKET: - getsockopt(l_cur->socket, SOL_SOCKET, SO_ERROR, (void *)&l_sock_err, (socklen_t *)&l_sock_err_size); - log_it(L_ERROR, "Socket error: %s", strerror(l_sock_err)); - default: ; - } - l_cur->flags |= DAP_SOCK_SIGNAL_CLOSE; - l_cur->callbacks.error_callback(l_cur, NULL); // Call callback to process error event - } - - - if(events[n].events & EPOLLIN) { - - //log_it(DEBUG,"Comes connection in active read set"); - if(l_cur->buf_in_size == sizeof(l_cur->buf_in)) { - log_it(L_WARNING, "Buffer is full when there is smth to read. Its dropped!"); - l_cur->buf_in_size = 0; - } - - int32_t bytes_read = 0; - int l_errno=0; - bool l_must_read_smth = false; - switch (l_cur->type) { - case DESCRIPTOR_TYPE_FILE: - l_must_read_smth = true; - bytes_read = read(l_cur->socket, (char *) (l_cur->buf_in + l_cur->buf_in_size), - sizeof(l_cur->buf_in) - l_cur->buf_in_size); - l_errno = errno; - break; - case DESCRIPTOR_TYPE_SOCKET: - l_must_read_smth = true; - bytes_read = recv(l_cur->fd, (char *) (l_cur->buf_in + l_cur->buf_in_size), - sizeof(l_cur->buf_in) - l_cur->buf_in_size, 0); - l_errno = errno; - break; - case DESCRIPTOR_TYPE_SOCKET_LISTENING: - // Accept connection - break; - case DESCRIPTOR_TYPE_TIMER:{ - uint64_t val; - /* if we not reading data from socket, he triggered again */ - read( l_cur->fd, &val, 8); - if (l_cur->callbacks.timer_callback) - l_cur->callbacks.timer_callback(l_cur); - else - log_it(L_ERROR, "Socket %d with timer callback fired, but callback is NULL ", l_cur->socket); - - } break; - case DESCRIPTOR_TYPE_EVENT: - if (l_cur->callbacks.event_callback){ - void * l_event_ptr = NULL; -#if defined(DAP_EVENTS_CAPS_EVENT_PIPE_PKT_MODE) - if(read( l_cur->fd, &l_event_ptr,sizeof (&l_event_ptr)) == sizeof (&l_event_ptr)) - l_cur->callbacks.event_callback(l_cur, l_event_ptr); - else if ( (errno != EAGAIN) && (errno != EWOULDBLOCK) ) // we use blocked socket for now but who knows... - log_it(L_WARNING, "Can't read packet from pipe"); -#endif - }else - log_it(L_ERROR, "Socket %d with event callback fired, but callback is NULL ", l_cur->socket); - break; - } - - if (l_must_read_smth){ // Socket/Descriptor read - if(bytes_read > 0) { - l_cur->buf_in_size += bytes_read; - //log_it(DEBUG, "Received %d bytes", bytes_read); - l_cur->callbacks.read_callback(l_cur, NULL); // Call callback to process read event. At the end of callback buf_in_size should be zero if everything was read well - } - else if(bytes_read < 0) { - if (l_errno != EAGAIN && l_errno != EWOULDBLOCK){ // Socket is blocked - log_it(L_ERROR, "Some error occured in recv() function: %s", strerror(errno)); - dap_events_socket_set_readable_unsafe(l_cur, false); - l_cur->flags |= DAP_SOCK_SIGNAL_CLOSE; - } - } - else if(bytes_read == 0) { - log_it(L_INFO, "Client socket disconnected"); - dap_events_socket_set_readable_unsafe(l_cur, false); - l_cur->flags |= DAP_SOCK_SIGNAL_CLOSE; - } - } - } - - // Socket is ready to write - if(((events[n].events & EPOLLOUT) || (l_cur->flags & DAP_SOCK_READY_TO_WRITE)) - && !(l_cur->flags & DAP_SOCK_SIGNAL_CLOSE)) { - ///log_it(DEBUG, "Main loop output: %u bytes to send",sa_cur->buf_out_size); - if(l_cur->callbacks.write_callback) - l_cur->callbacks.write_callback(l_cur, NULL); // Call callback to process write event - - if(l_cur->flags & DAP_SOCK_READY_TO_WRITE) { - - static const uint32_t buf_out_zero_count_max = 20; - l_cur->buf_out[l_cur->buf_out_size] = 0; - - if(!l_cur->buf_out_size) { - - //log_it(L_WARNING, "Output: nothing to send. Why we are in write socket set?"); - l_cur->buf_out_zero_count++; - - if(l_cur->buf_out_zero_count > buf_out_zero_count_max) { // How many time buf_out on write event could be empty - log_it(L_ERROR, "Output: nothing to send %u times, remove socket from the write set", - buf_out_zero_count_max); - dap_events_socket_set_writable_unsafe(l_cur, false); - } - } - else - l_cur->buf_out_zero_count = 0; - } - //for(total_sent = 0; total_sent < cur->buf_out_size;) { // If after callback there is smth to send - we do it - int l_errno; - if(l_cur->type == DESCRIPTOR_TYPE_SOCKET) { - bytes_sent = send(l_cur->socket, (char *) (l_cur->buf_out + total_sent), - l_cur->buf_out_size - total_sent, MSG_DONTWAIT | MSG_NOSIGNAL); - l_errno = errno; - }else if(l_cur->type == DESCRIPTOR_TYPE_FILE) { - bytes_sent = write(l_cur->socket, (char *) (l_cur->buf_out + total_sent), - l_cur->buf_out_size - total_sent); - l_errno = errno; - } - - if(bytes_sent < 0) { - if (l_errno != EAGAIN && l_errno != EWOULDBLOCK ){ // If we have non-blocking socket - log_it(L_ERROR, "Some error occured in send(): %s", strerror(errno)); - l_cur->flags |= DAP_SOCK_SIGNAL_CLOSE; - break; - } - }else{ - total_sent += bytes_sent; - //log_it(L_DEBUG, "Output: %u from %u bytes are sent ", total_sent,sa_cur->buf_out_size); - //} - //log_it(L_DEBUG,"Output: sent %u bytes",total_sent); - if (total_sent) { - pthread_mutex_lock(&l_cur->mutex); - l_cur->buf_out_size -= total_sent; - if (l_cur->buf_out_size) { - memmove(l_cur->buf_out, &l_cur->buf_out[total_sent], l_cur->buf_out_size); - } else { - l_cur->flags &= ~DAP_SOCK_READY_TO_WRITE; - } - pthread_mutex_unlock(&l_cur->mutex); - } - } - } - - if((l_cur->flags & DAP_SOCK_SIGNAL_CLOSE) && !l_cur->no_close) { - // protect against double deletion - l_cur->kill_signal = true; - //dap_events_socket_remove_and_delete(cur, true); - log_it(L_INFO, "Got signal to close %s, sock %u [thread %u]", l_cur->hostaddr, l_cur->socket, l_tn); - } - - if(l_cur->kill_signal) { - log_it(L_INFO, "Kill %u socket (processed).... [ thread %u ]", l_cur->socket, l_tn); - dap_events_socket_delete_unsafe( l_cur, false); - } - - } - -#ifndef NO_TIMER - if(cur_time >= l_next_time_timeout_check) { - s_socket_all_check_activity(l_worker, l_worker->events, cur_time); - l_next_time_timeout_check = cur_time + s_connection_timeout / 2; + for( uint32_t i = 0; i < s_threads_count; i++) { + s_workers[i].id = i; + s_workers[i].events = a_events; +#ifdef DAP_EVENTS_CAPS_EPOLL + s_workers[i].epoll_fd = epoll_create( DAP_MAX_EPOLL_EVENTS ); + if ( (intptr_t)s_workers[i].epoll_fd == -1 ) { + int l_errno = errno; + char l_errbuf[128]; + strerror_r(l_errno, l_errbuf, sizeof ( l_errbuf) ); + log_it(L_CRITICAL, "Error create epoll fd: %s (%d)", l_errbuf, l_errno); + return -1; } #endif - - } // while - - return NULL; -} - -/** - * @brief s_new_es_callback - * @param a_es - * @param a_arg - */ -static void s_new_es_callback( dap_events_socket_t * a_es, void * a_arg) -{ - dap_events_socket_t * l_es_new =(dap_events_socket_t *) a_arg; - dap_worker_t * w = a_es->worker; - log_it(L_DEBUG, "Received event socket %p to add on worker", l_es_new); - l_es_new->worker = w; - if ( l_es_new->type == DESCRIPTOR_TYPE_SOCKET || l_es_new->type == DESCRIPTOR_TYPE_SOCKET_LISTENING ){ - int l_cpu = w->id; - setsockopt(l_es_new->socket , SOL_SOCKET, SO_INCOMING_CPU, &l_cpu, sizeof(l_cpu)); - } - - if ( ! l_es_new->is_initalized ){ - if (l_es_new->callbacks.new_callback) - l_es_new->callbacks.new_callback(l_es_new, NULL); - l_es_new->is_initalized = true; - } - - if (l_es_new->socket>0){ - pthread_rwlock_wrlock(&w->events->sockets_rwlock); - HASH_ADD_INT(w->events->sockets, socket, l_es_new ); - pthread_rwlock_unlock(&w->events->sockets_rwlock); - - struct epoll_event l_ev={0}; - l_ev.events = l_es_new->flags ; - if(l_es_new->flags & DAP_SOCK_READY_TO_READ ) - l_ev.events |= EPOLLIN; - if(l_es_new->flags & DAP_SOCK_READY_TO_WRITE ) - l_ev.events |= EPOLLOUT; - l_ev.data.ptr = l_es_new; - - if ( epoll_ctl(w->epoll_fd, EPOLL_CTL_ADD, l_es_new->socket, &l_ev) == 1 ) - log_it(L_CRITICAL,"Can't add event socket's handler to epoll_fd"); - else{ - log_it(L_DEBUG, "Added socket %d on worker %u", l_es_new->socket, w->id); - if (l_es_new->callbacks.worker_assign_callback) - l_es_new->callbacks.worker_assign_callback(l_es_new, w); - - } - }else{ - log_it(L_ERROR, "Incorrect socket %d after new callback. Dropping this handler out", l_es_new->socket); - dap_events_socket_delete_unsafe( l_es_new, false ); + pthread_mutex_init( &s_workers[i].locker_on_count, NULL ); + pthread_create( &s_threads[i].tid, NULL, dap_worker_thread, &s_workers[i] ); } + return 0; } /** - * @brief s_delete_es_callback - * @param a_es - * @param a_arg + * @brief dap_events_wait + * @param sh + * @return */ -static void s_delete_es_callback( dap_events_socket_t * a_es, void * a_arg) +int dap_events_wait( dap_events_t *a_events ) { - ((dap_events_socket_t*)a_arg)->kill_signal = true; // Send signal to socket to kill + (void) a_events; + for( uint32_t i = 0; i < s_threads_count; i ++ ) { + void *ret; + pthread_join( s_threads[i].tid, &ret ); + } + return 0; } /** - * @brief s_reassign_es_callback - * @param a_es - * @param a_arg + * @brief dap_events_stop + * @param a_events */ -static void s_reassign_es_callback( dap_events_socket_t * a_es, void * a_arg) +void dap_events_stop_all( ) { - dap_events_socket_t * l_es_reassign = ((dap_events_socket_t* ) a_arg); - dap_events_socket_remove_from_worker_unsafe( l_es_reassign, a_es->worker ); - if (l_es_reassign->callbacks.worker_unassign_callback) - l_es_reassign->callbacks.worker_unassign_callback(l_es_reassign, a_es->worker); - - dap_events_socket_assign_on_worker( l_es_reassign, l_es_reassign->worker ); + // TODO implement signal to stop the workers } -/** - * @brief dap_worker_get_min - * @return - */ -dap_worker_t *dap_worker_get_min( ) -{ - // wait for s_workers init - while(!s_workers_init) - dap_usleep(DAP_USEC_PER_SEC / 1000); - dap_worker_t *l_workers = &s_workers[dap_worker_get_index_min()]; - // wait for worker start - while(!l_workers->events) - dap_usleep(DAP_USEC_PER_SEC / 1000); - return l_workers; -} - /** * @brief dap_worker_get_index_min * @return */ -uint32_t dap_worker_get_index_min( ) +uint32_t dap_events_worker_get_index_min( ) { - uint32_t min = 0; - uint32_t i; + uint32_t min = 0; + uint32_t i; - for( i = 1; i < s_threads_count; i++ ) { + for( i = 1; i < s_threads_count; i++ ) { if ( s_workers[min].event_sockets_count > s_workers[i].event_sockets_count ) - min = i; - } - - return min; -} - -dap_worker_t * dap_worker_get_index(uint8_t a_index) -{ - return a_index < s_threads_count ? &s_workers[a_index] : NULL; -} - -/** - * @brief dap_worker_print_all - */ -void dap_worker_print_all( ) -{ - uint32_t i; - - for( i = 0; i < s_threads_count; i ++ ) { - - log_it( L_INFO, "Worker: %d, count open connections: %d", - s_workers[i].id, s_workers[i].event_sockets_count ); - } -} - -/** - * @brief sa_server_loop Main server loop - * @param sh Server instance - * @return Zero if ok others if not - */ -int dap_events_start( dap_events_t *a_events ) -{ - for( uint32_t i = 0; i < s_threads_count; i++) { - - s_workers[i].epoll_fd = epoll_create( DAP_MAX_EPOLL_EVENTS ); - if ( (intptr_t)s_workers[i].epoll_fd == -1 ) { - log_it(L_CRITICAL, "Error create epoll fd"); - return -1; + min = i; } - //s_workers[i].event_to_kill_count = 0; - s_workers[i].event_sockets_count = 0; - s_workers[i].id = i; - s_workers[i].events = a_events; - - pthread_mutex_init( &s_workers[i].locker_on_count, NULL ); - pthread_create( &s_threads[i].tid, NULL, s_thread_worker_function, &s_workers[i] ); - } - - return 0; + return min; } -void dap_events_stop() +uint32_t dap_events_worker_get_count() { - bEventsAreActive = false; + return s_threads_count; } /** - * @brief dap_events_wait - * @param sh + * @brief dap_worker_get_min * @return */ -int dap_events_wait( dap_events_t *sh ) +dap_worker_t *dap_events_worker_get_min( ) { - (void) sh; - - for( uint32_t i = 0; i < s_threads_count; i ++ ) { - void *ret; - pthread_join( s_threads[i].tid, &ret ); - } - - return 0; -} - -/** - * @brief sap_worker_add_events_socket - * @param a_events_socket - * @param a_worker - */ -void dap_worker_add_events_socket(dap_events_socket_t * a_events_socket, dap_worker_t * a_worker) -{ - dap_events_socket_send_event( a_worker->event_new_es, a_events_socket ); + dap_worker_t *l_workers = &s_workers[dap_events_worker_get_index_min()]; + return l_workers; } /** - * @brief dap_worker_add_events_socket - * @param a_worker - * @param a_events_socket + * @brief dap_worker_get_index + * @param a_index + * @return */ -void dap_worker_add_events_socket_auto( dap_events_socket_t *a_es) +dap_worker_t * dap_events_worker_get_index(uint8_t a_index) { -// struct epoll_event ev = {0}; - dap_worker_t *l_worker = dap_worker_get_min( ); - - a_es->worker = l_worker; - a_es->events = a_es->worker->events; + return a_index < s_threads_count ? &s_workers[a_index] : NULL; } /** - * @brief dap_events__thread_wake_up - * @param th + * @brief dap_worker_print_all */ -void dap_events_thread_wake_up( dap_thread_t *th ) +void dap_events_worker_print_all( ) { - (void) th; - //pthread_kill(th->tid,SIGUSR1); + uint32_t i; + for( i = 0; i < s_threads_count; i ++ ) { + log_it( L_INFO, "Worker: %d, count open connections: %d", + s_workers[i].id, s_workers[i].event_sockets_count ); + } } diff --git a/dap-sdk/net/core/dap_events_socket.c b/dap-sdk/net/core/dap_events_socket.c index 87ab55d6252d87a191db44c0aa4c3c7ee889f93f..76f24690f60b7b2bcc146d1419d234cfff70cd71 100644 --- a/dap-sdk/net/core/dap_events_socket.c +++ b/dap-sdk/net/core/dap_events_socket.c @@ -1,27 +1,27 @@ /* * Authors: * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net> - * DeM Labs Inc. https://demlabs.net - * Kelvin Project https://github.com/kelvinblockchain - * Copyright (c) 2017-2019 + * DeM Labs Ltd. https://demlabs.net + * Copyright (c) 2017 * All rights reserved. - This file is part of DAP (Deus Applications Prototypes) the open source project + This file is part of DAP SDK the open source project - DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify + DAP SDK is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - DAP is distributed in the hope that it will be useful, + DAP SDK is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. + along with any DAP SDK based project. If not, see <http://www.gnu.org/licenses/>. */ + #include <stdlib.h> #include <stdio.h> #include <stdarg.h> @@ -118,7 +118,7 @@ dap_events_socket_t * dap_events_socket_create_type_event(dap_worker_t * a_w, da l_es->worker = a_w; l_es->callbacks.event_callback = a_callback; // Arm event callback -#ifdef DAP_EVENTS_CAPS_EVENT_PIPE_PKT_MODE +#ifdef DAP_EVENTS_CAPS_EVENT_PIPE2 int l_pipe[2]; int l_errno; char l_errbuf[128]; @@ -154,7 +154,7 @@ dap_events_socket_t * dap_events_socket_create_type_event(dap_worker_t * a_w, da */ void dap_events_socket_send_event( dap_events_socket_t * a_es, void* a_arg) { -#if defined(DAP_EVENTS_CAPS_EVENT_PIPE_PKT_MODE) +#if defined(DAP_EVENTS_CAPS_EVENT_PIPE2) write( a_es->fd2, &a_arg,sizeof(a_arg)); #endif } @@ -283,10 +283,12 @@ void dap_events_socket_set_readable_unsafe( dap_events_socket_t *sc, bool is_rea sc->ev.events = events; - if ( epoll_ctl(sc->worker->epoll_fd, EPOLL_CTL_MOD, sc->socket, &sc->ev) == -1 ) - log_it( L_ERROR,"Can't update read client socket state in the epoll_fd" ); - else - dap_events_thread_wake_up( &sc->events->proc_thread ); + if ( epoll_ctl(sc->worker->epoll_fd, EPOLL_CTL_MOD, sc->socket, &sc->ev) == -1 ){ + int l_errno = errno; + char l_errbuf[128]; + strerror_r( l_errno, l_errbuf, sizeof (l_errbuf)); + log_it( L_ERROR,"Can't update read client socket state in the epoll_fd: \"%s\" (%d)", l_errbuf, l_errno ); + } } /** @@ -296,7 +298,6 @@ void dap_events_socket_set_readable_unsafe( dap_events_socket_t *sc, bool is_rea */ void dap_events_socket_set_writable_unsafe( dap_events_socket_t *sc, bool is_ready ) { - char l_errbuf[128]; if ( is_ready == (bool)(sc->flags & DAP_SOCK_READY_TO_WRITE) ) { return; } @@ -317,8 +318,10 @@ void dap_events_socket_set_writable_unsafe( dap_events_socket_t *sc, bool is_rea sc->ev.events = events; if ( epoll_ctl(sc->worker->epoll_fd, EPOLL_CTL_MOD, sc->socket, &sc->ev) ){ - strerror_r(errno, l_errbuf, sizeof (l_errbuf)); - log_it(L_ERROR,"Can't update write client socket state in the epoll_fd: %s (%d)", l_errbuf, errno); + int l_errno = errno; + char l_errbuf[128]; + strerror_r(l_errno, l_errbuf, sizeof (l_errbuf)); + log_it(L_ERROR,"Can't update write client socket state in the epoll_fd: \"%s\" (%d)", l_errbuf, l_errno); } } @@ -328,44 +331,45 @@ void dap_events_socket_set_writable_unsafe( dap_events_socket_t *sc, bool is_rea */ void dap_events_socket_delete_unsafe( dap_events_socket_t *a_es, bool preserve_inheritor ) { - if ( !a_es ) return; + if ( !a_es ) + return; - log_it( L_DEBUG, "es is going to be removed from the lists and free the memory (0x%016X)", a_es ); + log_it( L_DEBUG, "es is going to be removed from the lists and free the memory (0x%016X)", a_es ); - if(!dap_events_socket_find(a_es->socket, a_es->events)){ - log_it( L_ERROR, "dap_events_socket 0x%x already deleted", a_es); - return ; - } + if(!dap_events_socket_find(a_es->socket, a_es->events)){ + log_it( L_ERROR, "dap_events_socket 0x%x already deleted", a_es); + return ; + } - dap_events_socket_remove_from_worker_unsafe(a_es, a_es->worker); - pthread_rwlock_wrlock( &a_es->events->sockets_rwlock ); - if(a_es->events->sockets) + dap_events_socket_remove_from_worker_unsafe(a_es, a_es->worker); + pthread_rwlock_wrlock( &a_es->events->sockets_rwlock ); + if(a_es->events->sockets) HASH_DEL( a_es->events->sockets, a_es ); - pthread_rwlock_unlock( &a_es->events->sockets_rwlock ); + pthread_rwlock_unlock( &a_es->events->sockets_rwlock ); - log_it( L_DEBUG, "dap_events_socket wrapped around %d socket is removed", a_es->socket ); + log_it( L_DEBUG, "dap_events_socket wrapped around %d socket is removed", a_es->socket ); - if( a_es->callbacks.delete_callback ) - a_es->callbacks.delete_callback( a_es, NULL ); // Init internal structure + if( a_es->callbacks.delete_callback ) + a_es->callbacks.delete_callback( a_es, NULL ); // Init internal structure - if ( a_es->_inheritor && !preserve_inheritor ) - DAP_DELETE( a_es->_inheritor ); + if ( a_es->_inheritor && !preserve_inheritor ) + DAP_DELETE( a_es->_inheritor ); - if ( a_es->socket ) { + if ( a_es->socket ) { #ifdef _WIN32 - closesocket( a_es->socket ); + closesocket( a_es->socket ); #else - close( a_es->socket ); -#ifdef DAP_EVENTS_CAPS_EVENT_PIPE_PKT_MODE - if( a_es->type == DESCRIPTOR_TYPE_EVENT){ - close( a_es->fd2); - } + close( a_es->socket ); +#ifdef DAP_EVENTS_CAPS_EVENT_PIPE2 + if( a_es->type == DESCRIPTOR_TYPE_EVENT){ + close( a_es->fd2); + } #endif #endif - } - pthread_mutex_destroy(&a_es->mutex); - DAP_DELETE( a_es ); + } + pthread_mutex_destroy(&a_es->mutex); + DAP_DELETE( a_es ); } /** @@ -374,11 +378,11 @@ void dap_events_socket_delete_unsafe( dap_events_socket_t *a_es, bool preserve_i */ void dap_events_socket_remove_from_worker_unsafe( dap_events_socket_t *a_es, dap_worker_t * a_worker) { - if ( epoll_ctl( a_worker->epoll_fd, EPOLL_CTL_DEL, a_es->socket, &a_es->ev) == -1 ) - log_it( L_ERROR,"Can't remove event socket's handler from the epoll_fd" ); - else - log_it( L_DEBUG,"Removed epoll's event from dap_worker #%u", a_worker->id ); - a_worker->event_sockets_count--; + if ( epoll_ctl( a_worker->epoll_fd, EPOLL_CTL_DEL, a_es->socket, &a_es->ev) == -1 ) + log_it( L_ERROR,"Can't remove event socket's handler from the epoll_fd" ); + else + log_it( L_DEBUG,"Removed epoll's event from dap_worker #%u", a_worker->id ); + a_worker->event_sockets_count--; } /** @@ -391,21 +395,44 @@ void dap_events_socket_queue_remove_and_delete( dap_events_socket_t *a_es ) dap_events_socket_send_event( a_es->worker->event_delete_es, a_es ); } +/** + * @brief dap_events_socket_set_readable_mt + * @param sc + * @param is_ready + */ void dap_events_socket_set_readable_mt(dap_events_socket_t * sc,bool is_ready) { } +/** + * @brief dap_events_socket_set_writable_mt + * @param sc + * @param is_ready + */ void dap_events_socket_set_writable_mt(dap_events_socket_t * sc,bool is_ready) { } +/** + * @brief dap_events_socket_write_mt + * @param sc + * @param data + * @param data_size + * @return + */ size_t dap_events_socket_write_mt(dap_events_socket_t *sc, const void * data, size_t data_size) { } +/** + * @brief dap_events_socket_write_f_mt + * @param sc + * @param format + * @return + */ size_t dap_events_socket_write_f_mt(dap_events_socket_t *sc, const char * format,...) { diff --git a/dap-sdk/net/core/dap_server.c b/dap-sdk/net/core/dap_server.c index bbc3bbd5e526c50636b85f3bec4531814a7a8e32..f8d3756140045d82e29b535ad616934fe18ec5bf 100644 --- a/dap-sdk/net/core/dap_server.c +++ b/dap-sdk/net/core/dap_server.c @@ -1,847 +1,250 @@ /* - Copyright (c) 2017-2018 (c) Project "DeM Labs Inc" https://github.com/demlabsinc - All rights reserved. + * Authors: + * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net> + * DeM Labs Ltd. https://demlabs.net + * Copyright (c) 2017 + * All rights reserved. - This file is part of DAP (Deus Applications Prototypes) the open source project + This file is part of DAP SDK the open source project - DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by + DAP SDK is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - DAP is distributed in the hope that it will be useful, + DAP SDK is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. + GNU General Public License for more details. - You should have received a copy of the GNU Lesser General Public License - along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. + You should have received a copy of the GNU General Public License + along with any DAP SDK based project. If not, see <http://www.gnu.org/licenses/>. */ -#define __USE_GNU - -#include <string.h> -#include <time.h> -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <stdint.h> - -//#include <errno.h> -#include <signal.h> -#include <stdint.h> -#include <stdatomic.h> - -#ifndef _WIN32 #include <arpa/inet.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/types.h> #include <sys/stat.h> -#include <sys/select.h> -#include <errno.h> + +#include <sys/epoll.h> + #include <netdb.h> #include <unistd.h> #include <fcntl.h> -#include <sys/epoll.h> +#include <string.h> +#include <time.h> + +#include <stdio.h> +#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <errno.h> +#include <signal.h> #include <sys/timerfd.h> -#else -#include <winsock2.h> -#include <windows.h> -#include <mswsock.h> -#include <ws2tcpip.h> -#include <io.h> -#include <pthread.h> +#include <utlist.h> +#if ! defined(_GNU_SOURCE) +#define _GNU_SOURCE #endif - -#include <sched.h> - -#if 0 -#define NI_NUMERICHOST 1 /* Don't try to look up hostname. */ -#define NI_NUMERICSERV 2 /* Don't convert port number to name. */ -#define NI_NOFQDN 4 /* Only return nodename portion. */ -#define NI_NAMEREQD 8 /* Don't return numeric addresses. */ -#define NI_DGRAM 16 /* Look up UDP service rather than TCP. */ +#if ! defined (__USE_GNU) +#define __USE_GNU #endif - +#include <sched.h> #include "dap_common.h" +#include "dap_config.h" #include "dap_server.h" -#include "dap_strfuncs.h" - -#define LOG_TAG "server" - -#define DAP_MAX_THREAD_EVENTS 8192 -#define DAP_MAX_THREADS 16 - -#define SOCKET_TIMEOUT_TIME 300 -#define SOCKETS_TIMEOUT_CHECK_PERIOD 15 - -static uint32_t _count_threads = 0; -static uint32_t epoll_max_events = 0; -static bool bQuitSignal = false; -static bool moduleInit = false; - -static struct epoll_event *threads_epoll_events = NULL; -static dap_server_t *_current_run_server = NULL; - -static void read_write_cb( dap_client_remote_t *dap_cur, int32_t revents ); -void *thread_loop( void *arg ); - -dap_server_thread_t dap_server_threads[ DAP_MAX_THREADS ]; - -/* -=============================================== - get_epoll_max_user_watches( ) - - return max epoll() event watches -=============================================== -*/ -static uint32_t get_epoll_max_user_watches( void ) -{ - static const char *maxepollpath = "/proc/sys/fs/epoll/max_user_watches"; - uint32_t v = 0, len; - char str[32]; - - FILE *fp = fopen( maxepollpath, "r" ); - if ( !fp ) { -// printf("can't open %s\n", maxepollpath ); - return v; - } - - len = fread( &str[0], 1, 31, fp ); - if ( !len ) { - return v; - } - - str[ len ] = 0; - v = atoi( str ); - - return v; -} - -/* -=============================================== - dap_server_init( ) - - Init server module - return Zero if ok others if no -=============================================== -*/ -int32_t dap_server_init( uint32_t count_threads ) -{ - dap_server_thread_t *dap_thread; - moduleInit = true; - - #ifndef _WIN32 - signal( SIGPIPE, SIG_IGN ); - #endif - - if ( count_threads > DAP_MAX_THREADS ) - count_threads = DAP_MAX_THREADS; - - _count_threads = count_threads; - log_it( L_NOTICE, "dap_server_init() threads %u", count_threads ); - - epoll_max_events = get_epoll_max_user_watches( ); - if ( epoll_max_events > DAP_MAX_THREAD_EVENTS ) - epoll_max_events = DAP_MAX_THREAD_EVENTS; - - threads_epoll_events = (struct epoll_event *)malloc( sizeof(struct epoll_event) * _count_threads * epoll_max_events ); - if ( !threads_epoll_events ) - goto err; - - memset( threads_epoll_events, 0, sizeof(struct epoll_event) * _count_threads * epoll_max_events ); - - dap_thread = &dap_server_threads[0]; - memset( dap_thread, 0, sizeof(dap_server_thread_t) * DAP_MAX_THREADS ); - - for ( uint32_t i = 0; i < _count_threads; ++i, ++dap_thread ) { - #ifndef _WIN32 - dap_thread->epoll_fd = -1; - #else - dap_thread->epoll_fd = (void*)-1; - #endif - dap_thread->thread_num = i; - dap_thread->epoll_events = &threads_epoll_events[ i * epoll_max_events ]; - - pthread_mutex_init( &dap_thread->mutex_dlist_add_remove, NULL ); - pthread_mutex_init( &dap_thread->mutex_on_hash, NULL ); - } - - log_it( L_NOTICE, "Initialized socket server module" ); - - dap_client_remote_init( ); +#include "dap_events.h" +#define LOG_TAG "dap_server" - pthread_t thread_listener[ DAP_MAX_THREADS ]; +static void s_es_server_read(dap_events_socket_t *a_events, void * a_arg); +static void s_es_server_error(dap_events_socket_t *a_events, void * a_arg); - for( uint32_t i = 0; i < _count_threads; ++i ) { - - EPOLL_HANDLE efd = epoll_create1( 0 ); - if ( (intptr_t)efd == -1 ) { - log_it( L_ERROR, "Can't create epoll instance" ); - goto err; - } - dap_server_threads[ i ].epoll_fd = efd; - dap_server_threads[ i ].thread_num = i; - } - - for( uint32_t i = 0; i < _count_threads; ++i ) { - pthread_create( &thread_listener[i], NULL, thread_loop, &dap_server_threads[i] ); - } - - - return 0; - -err:; - - dap_server_deinit( ); - return 1; -} - -void dap_server_loop_stop( void ){ - bQuitSignal = true; -} - -/* -========================================================= - dap_server_deinit( ) - - Deinit server module -========================================================= -*/ -void dap_server_deinit( void ) +static void s_server_delete(dap_server_t * a_server); +/** + * @brief dap_server_init + * @return + */ +int dap_server_init() { - if (moduleInit) { - dap_client_remote_t *dap_cur, *tmp; - dap_server_thread_t *t = &dap_server_threads[0]; - - dap_client_remote_deinit( ); - - if ( threads_epoll_events ) { - free( threads_epoll_events ); - - for ( uint32_t i = 0; i < _count_threads; ++i, ++t ) { - - HASH_ITER( hh, t->hclients, dap_cur, tmp ) - dap_client_remote_remove( dap_cur ); - - pthread_mutex_destroy( &dap_server_threads[i].mutex_on_hash ); - pthread_mutex_destroy( &dap_server_threads[i].mutex_dlist_add_remove ); - - if ( (intptr_t)dap_server_threads[ i ].epoll_fd != -1 ) { - #ifndef _WIN32 - close( dap_server_threads[ i ].epoll_fd ); - #else - epoll_close( dap_server_threads[ i ].epoll_fd ); - #endif - } - } - } - moduleInit = false; - } + log_it(L_NOTICE,"Server module init"); + return 0; } -/* -========================================================= - dap_server_new( ) - - Creates new empty instance of dap_server_t -========================================================= -*/ -dap_server_t *dap_server_new( void ) +/** + * @brief dap_server_deinit + */ +void dap_server_deinit() { - return (dap_server_t *)calloc( 1, sizeof(dap_server_t) ); } -/* -========================================================= - dap_server_new( ) - - Delete server instance -========================================================= -*/ -void dap_server_delete( dap_server_t *sh ) +/** + * @brief dap_server_delete + * @param a_server + */ +void s_server_delete(dap_server_t * a_server) { - if ( !sh ) return; - - if( sh->address ) - free( sh->address ); - - if( sh->server_delete_callback ) - sh->server_delete_callback( sh, NULL ); - - if ( sh->_inheritor ) - free( sh->_inheritor ); - - free( sh ); + if(a_server->delete_callback) + a_server->delete_callback(a_server,NULL); + if( a_server->address ) + DAP_DELETE(a_server->address ); + if( a_server->_inheritor ) + DAP_DELETE( a_server->_inheritor ); + DAP_DELETE(a_server); } -/* -========================================================= - set_nonblock_socket( ) -========================================================= -*/ -int32_t set_nonblock_socket( int32_t fd ) +/** + * @brief dap_server_new + * @param a_events + * @param a_addr + * @param a_port + * @param a_type + * @return + */ +dap_server_t* dap_server_new(dap_events_t *a_events, const char * a_addr, uint16_t a_port, dap_server_type_t a_type) { -#ifdef _WIN32 - unsigned long arg = 1; - return ioctlsocket( fd, FIONBIO, &arg ); -#else - int32_t flags; - - flags = fcntl( fd, F_GETFL ); - flags |= O_NONBLOCK; - - return fcntl( fd, F_SETFL, flags ); -#endif -} + assert(a_events); + dap_server_t *l_server = DAP_NEW_Z(dap_server_t); + l_server->socket_listener=-1; // To diff it from 0 fd + l_server->address = a_addr? strdup( a_addr) : strdup("0.0.0.0"); // If NULL we listen everything + l_server->port = a_port; + l_server->type = a_type; -/* -========================================================= - get_thread_min_connections( ) - - return number thread which has minimum open connections -========================================================= -*/ -static inline uint32_t get_thread_index_min_connections( ) -{ - uint32_t min = 0; + if(l_server->type == DAP_SERVER_TCP) + l_server->socket_listener = socket(AF_INET, SOCK_STREAM, 0); - for( uint32_t i = 1; i < _count_threads; i ++ ) { - if ( dap_server_threads[min].connections_count > dap_server_threads[i].connections_count ) { - min = i; + if (l_server->socket_listener < 0) { + int l_errno = errno; + log_it (L_ERROR,"Socket error %s (%d)",strerror(l_errno), l_errno); + return NULL; } - } - - return min; -} -/* -========================================================= - print_online( ) + log_it(L_NOTICE,"Listen socket created..."); + int reuse=1; -========================================================= -*/ -static inline void print_online() -{ - for( uint32_t i = 0; i < _count_threads; i ++ ) { - log_it( L_INFO, "Thread number: %u, count: %u", i, dap_server_threads[i].connections_count ); - } -} - -void dap_server_kill_socket( dap_client_remote_t *dcr ) -{ - if ( !dcr ) { - log_it( L_ERROR, "dap_server_kill_socket( NULL )" ); - return; - } - - dap_server_thread_t *dsth = &dap_server_threads[ dcr->tn ]; - - pthread_mutex_lock( &dsth->mutex_dlist_add_remove ); - - if ( dcr->kill_signal ) { - pthread_mutex_unlock( &dsth->mutex_dlist_add_remove ); - return; - } - - log_it( L_DEBUG, "KILL %u socket! [ thread %u ]", dcr->socket, dcr->tn ); - - dcr->kill_signal = true; - - DL_LIST_ADD_NODE_HEAD( dsth->dap_clients_to_kill, dcr, kprev, knext, dsth->to_kill_count ); - pthread_mutex_unlock( &dsth->mutex_dlist_add_remove ); - - return; -} - -/* -========================================================= - dap_server_add_socket( ) - -========================================================= -*/ -dap_client_remote_t *dap_server_add_socket( int32_t fd, int32_t forced_thread_n ) -{ - uint32_t tn = (forced_thread_n == -1) ? get_thread_index_min_connections( ) : forced_thread_n; - dap_server_thread_t *dsth = &dap_server_threads[ tn ]; - dap_client_remote_t *dcr = dap_client_remote_create( _current_run_server, fd, dsth ); - - if ( !dcr ) { - log_it( L_ERROR, "accept %d dap_client_remote_create() == NULL", fd ); -// pthread_mutex_unlock( &dsth->mutex_dlist_add_remove ); - return dcr; - } - - log_it( L_DEBUG, "accept %d Client, thread %d", fd, tn ); - - pthread_mutex_lock( &dsth->mutex_dlist_add_remove ); - - - DL_APPEND( dsth->dap_remote_clients, dcr ); - dsth->connections_count ++; - if ( epoll_ctl( dsth->epoll_fd, EPOLL_CTL_ADD, fd, &dcr->pevent) != 0 ) { - log_it( L_ERROR, "epoll_ctl failed 005" ); - } - pthread_mutex_unlock( &dsth->mutex_dlist_add_remove ); - - return dcr; -} - -/* -========================================================= - dap_server_remove_socket( ) - -========================================================= -*/ -void dap_server_remove_socket( dap_client_remote_t *dcr ) -{ - if ( !dcr ) { - log_it( L_ERROR, "dap_server_remove_socket( NULL )" ); - return; - } - - uint32_t tn = dcr->tn; - log_it( L_DEBUG, "dap_server_remove_socket %u thread %u", dcr->socket, tn ); - - dap_server_thread_t *dsth = &dap_server_threads[ tn ]; - - if ( epoll_ctl( dcr->efd, EPOLL_CTL_DEL, dcr->socket, &dcr->pevent ) == -1 ) - log_it( L_ERROR,"Can't remove event socket's handler from the epoll_fd" ); - -// pthread_mutex_lock( &dsth->mutex_dlist_add_remove ); - DL_DELETE( dsth->dap_remote_clients, dcr ); - dsth->connections_count --; - -// pthread_mutex_unlock( &dsth->mutex_dlist_add_remove ); - -// log_it( L_DEBUG, "dcr = %X", dcr ); -} - -static void s_socket_all_check_activity( uint32_t tn, time_t cur_time ) -{ - dap_client_remote_t *dcr, *tmp; - dap_server_thread_t *dsth = &dap_server_threads[ tn ]; - -// log_it( L_INFO,"s_socket_info_all_check_activity() on thread %u", tn ); - - pthread_mutex_lock( &dsth->mutex_dlist_add_remove ); - - DL_FOREACH_SAFE( dsth->dap_remote_clients, dcr, tmp ) { - - if ( !dcr->kill_signal && cur_time >= dcr->last_time_active + SOCKET_TIMEOUT_TIME && !dcr->no_close ) { - - log_it( L_INFO, "Socket %u timeout, closing...", dcr->socket ); - - if ( epoll_ctl( dcr->efd, EPOLL_CTL_DEL, dcr->socket, &dcr->pevent ) == -1 ) - log_it( L_ERROR,"Can't remove event socket's handler from the epoll_fd" ); - - DL_DELETE( dsth->dap_remote_clients, dcr ); - dsth->connections_count --; - - dap_client_remote_remove( dcr ); - } - } - pthread_mutex_unlock( &dsth->mutex_dlist_add_remove ); -} - -/* -========================================================= - read_write_cb( ) - -========================================================= -*/ -static void read_write_cb( dap_client_remote_t *dap_cur, int32_t revents ) -{ -// log_it( L_NOTICE, "[THREAD %u] read_write_cb fd %u revents %u", dap_cur->tn, dap_cur->socket, revents ); -// sleep( 5 ); // ????????? - - if( !dap_cur ) { - - log_it( L_ERROR, "read_write_cb: dap_client_remote NULL" ); - return; - } - - if ( revents & EPOLLIN ) { - -// log_it( L_DEBUG, "[THREAD %u] socket read %d ", dap_cur->tn, dap_cur->socket ); - - int32_t bytes_read = recv( dap_cur->socket, - dap_cur->buf_in + dap_cur->buf_in_size, - sizeof(dap_cur->buf_in) - dap_cur->buf_in_size, - 0 ); - if ( bytes_read > 0 ) { -// log_it( L_DEBUG, "[THREAD %u] read %u socket client said: %s", dap_cur->tn, bytes_read, dap_cur->buf_in + dap_cur->buf_in_size ); - - dap_cur->buf_in_size += (size_t)bytes_read; - dap_cur->upload_stat.buf_size_total += (size_t)bytes_read; - -// log_it( L_DEBUG, "[THREAD %u] read %u socket read callback()", dap_cur->tn, bytes_read ); - _current_run_server->client_read_callback( dap_cur ,NULL ); - } - else if ( bytes_read < 0 ) { - log_it( L_ERROR,"Bytes read Error %s",strerror(errno) ); - if ( strcmp(strerror(errno),"Resource temporarily unavailable") != 0 ) - dap_cur->flags |= DAP_SOCK_SIGNAL_CLOSE; - } - else { // bytes_read == 0 - dap_cur->flags |= DAP_SOCK_SIGNAL_CLOSE; - log_it( L_DEBUG, "0 bytes read" ); - } - } - - if( ( (revents & EPOLLOUT) || (dap_cur->flags & DAP_SOCK_READY_TO_WRITE) ) && !(dap_cur->flags & DAP_SOCK_SIGNAL_CLOSE) ) { - -// log_it(L_DEBUG, "[THREAD %u] socket write %d ", dap_cur->tn, dap_cur->socket ); - _current_run_server->client_write_callback( dap_cur, NULL ); // Call callback to process write event - - if( dap_cur->buf_out_size == 0 ) { - //log_it(L_DEBUG, "dap_cur->buf_out_size = 0, set ev_read watcher " ); - - dap_cur->pevent.events = EPOLLIN | EPOLLERR; - if( epoll_ctl(dap_cur->efd, EPOLL_CTL_MOD, dap_cur->socket, &dap_cur->pevent) != 0 ) { - log_it( L_ERROR, "epoll_ctl failed 003" ); - } - } - else { -// log_it(L_DEBUG, "[THREAD %u] send dap_cur->buf_out_size = %u , %s", dap_cur->tn, dap_cur->buf_out_size, dap_cur->buf_out ); - - size_t total_sent = dap_cur->buf_out_offset; - - while ( total_sent < dap_cur->buf_out_size ) { - //log_it(DEBUG, "Output: %u from %u bytes are sent ", total_sent, dap_cur->buf_out_size); - ssize_t bytes_sent = send( dap_cur->socket, - dap_cur->buf_out + total_sent, - dap_cur->buf_out_size - total_sent, - MSG_DONTWAIT | MSG_NOSIGNAL ); - if( bytes_sent < 0 ) { - if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { - dap_cur->pevent.events = EPOLLOUT | EPOLLERR; - if( epoll_ctl(dap_cur->efd, EPOLL_CTL_MOD, dap_cur->socket, &dap_cur->pevent) != 0 ) { - log_it( L_ERROR, "epoll_ctl failed..." ); - dap_cur->flags |= DAP_SOCK_SIGNAL_CLOSE; - break; - } - } else { - log_it(L_ERROR,"[THREAD %u] Error occured in send() function %s", dap_cur->tn, strerror(errno) ); - dap_cur->flags |= DAP_SOCK_SIGNAL_CLOSE; - break; - } - } - - total_sent += (size_t)bytes_sent; - dap_cur->download_stat.buf_size_total += (size_t)bytes_sent; - } - -// log_it( L_ERROR, "check !" ); - - if( total_sent == dap_cur->buf_out_size ) { - dap_cur->buf_out_offset = dap_cur->buf_out_size = 0; - } - else { - dap_cur->buf_out_offset = total_sent; - } - } // else - } // write - - -// log_it(L_ERROR,"OPA !") ; -// Sleep(200); - -// if ( (dap_cur->flags & DAP_SOCK_SIGNAL_CLOSE) && !dap_cur->no_close ) { -// log_it(L_ERROR,"Close signal" ); - -// dap_server_remove_socket( dap_cur ); -// dap_client_remote_remove( dap_cur, _current_run_server ); -// } - -} - - -/* -========================================================= - dap_server_listen( ) - - Create server_t instance and start to listen tcp port with selected address - -========================================================= -*/ -dap_server_t *dap_server_listen( const char *addr, uint16_t port, dap_server_type_t type ) -{ - dap_server_t* sh = dap_server_new( ); - - sh->socket_listener = -111; - - if( type == DAP_SERVER_TCP ) - sh->socket_listener = socket( AF_INET, SOCK_STREAM, 0 ); - else { - dap_server_delete( sh ); - return NULL; - } - - if ( set_nonblock_socket(sh->socket_listener) == -1 ) { - log_it( L_WARNING, "error server socket nonblock" ); - dap_server_delete( sh ); - return NULL; - } - - if ( sh->socket_listener < 0 ) { - log_it ( L_ERROR,"Socket error %s", strerror(errno) ); - dap_server_delete( sh ); - return NULL; - } - - log_it( L_NOTICE," Socket created..." ); - - int32_t reuse = 1; - - if ( reuse ) - if ( setsockopt( sh->socket_listener, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0 ) - log_it( L_WARNING, "Can't set up REUSEADDR flag to the socket" ); - - sh->listener_addr.sin_family = AF_INET; - sh->listener_addr.sin_port = htons( port ); - inet_pton( AF_INET, addr, &(sh->listener_addr.sin_addr) ); - - if( bind(sh->socket_listener, (struct sockaddr *)&(sh->listener_addr), sizeof(sh->listener_addr)) < 0 ) { - log_it( L_ERROR,"Bind error: %s",strerror(errno) ); - dap_server_delete( sh ); - return NULL; - } - - log_it( L_INFO,"Binded %s:%u", addr, port ); - listen( sh->socket_listener, DAP_MAX_THREAD_EVENTS * _count_threads ); - - return sh; -} - - -/* -========================================================= - thread_loop( ) - - Server listener thread loop -========================================================= -*/ -void *thread_loop( void *arg ) -{ - dap_client_remote_t *dap_cur, *tmp; - dap_server_thread_t *dsth = (dap_server_thread_t *)arg; - uint32_t tn = dsth->thread_num; - EPOLL_HANDLE efd = dsth->epoll_fd; - struct epoll_event *events = dsth->epoll_events; - time_t next_time_timeout_check = time( NULL ) + SOCKETS_TIMEOUT_CHECK_PERIOD; - - log_it(L_NOTICE, "Start loop listener socket thread %u efd %u", tn, efd ); - - #ifndef _WIN32 - cpu_set_t mask; - CPU_ZERO( &mask ); - CPU_SET( tn, &mask ); - - int err; - int l_sock_err = 0, l_sock_err_size = sizeof(l_sock_err); -#ifndef ANDROID - err = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &mask); -#else - err = sched_setaffinity(pthread_self(), sizeof(cpu_set_t), &mask); + if (setsockopt(l_server->socket_listener, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0) + log_it(L_WARNING, "Can't set up REUSEADDR flag to the socket"); +#ifdef SO_REUSEPORT + if (setsockopt(l_server->socket_listener, SOL_SOCKET, SO_REUSEPORT, (const char*)&reuse, sizeof(reuse)) < 0) + log_it(L_WARNING, "Can't set up REUSEPORT flag to the socket"); #endif - if (err) { - log_it( L_CRITICAL, "Error pthread_setaffinity_np() You really have %d or more core in CPU?", tn ); - abort(); - } - #else - - if ( !SetThreadAffinityMask( GetCurrentThread(), (DWORD_PTR)(1 << tn) ) ) { - log_it( L_CRITICAL, "Error pthread_setaffinity_np() You really have %d or more core in CPU?", tn ); - abort(); - } - - #endif - - do { - - int32_t n = epoll_wait( efd, events, DAP_MAX_THREAD_EVENTS, 1000 ); -// log_it(L_WARNING,"[THREAD %u] epoll events %u", tn, n ); -// Sleep(300); - - if ( bQuitSignal ) - break; - - if ( n < 0 ) { - if ( errno == EINTR ) - continue; - break; +//create socket + l_server->listener_addr.sin_family = AF_INET; + l_server->listener_addr.sin_port = htons(l_server->port); + inet_pton(AF_INET, l_server->address, &(l_server->listener_addr.sin_addr)); + + if(bind (l_server->socket_listener, (struct sockaddr *) &(l_server->listener_addr), sizeof(l_server->listener_addr)) < 0){ + log_it(L_ERROR,"Bind error: %s",strerror(errno)); + return NULL; + }else{ + log_it(L_INFO,"Binded %s:%u",l_server->address,l_server->port); + listen(l_server->socket_listener, SOMAXCONN); } - time_t cur_time = time( NULL ); - - for ( int32_t i = 0; i < n; ++ i ) { - -// log_it(L_ERROR,"[THREAD %u] process epoll event %u", tn, i ); - dap_cur = (dap_client_remote_t *)events[i].data.ptr; - - if ( !dap_cur ) { - log_it( L_ERROR,"dap_client_remote_t NULL" ); - continue; - } - - dap_cur->last_time_active = cur_time; - if( events[i].events & EPOLLERR ) { - getsockopt(dap_cur->socket, SOL_SOCKET, SO_ERROR, (void *)&l_sock_err, (socklen_t *)&l_sock_err_size); - log_it( L_ERROR,"Socket %u error: %s, remove it" , dap_cur->socket, strerror(l_sock_err)); - dap_cur->flags |= DAP_SOCK_SIGNAL_CLOSE; - } - set_nonblock_socket(dap_cur->socket); - if ( !(dap_cur->flags & DAP_SOCK_SIGNAL_CLOSE) || dap_cur->no_close ) - read_write_cb( dap_cur, events[i].events ); - - if ( (dap_cur->flags & DAP_SOCK_SIGNAL_CLOSE) && !dap_cur->no_close ) { - - pthread_mutex_lock( &dsth->mutex_dlist_add_remove ); - - if ( dap_cur->kill_signal ) { - pthread_mutex_unlock( &dsth->mutex_dlist_add_remove ); - continue; + fcntl( l_server->socket_listener, F_SETFL, O_NONBLOCK); + + dap_events_socket_callbacks_t l_callbacks = {{ 0 }}; + l_callbacks.read_callback = s_es_server_read; + l_callbacks.error_callback = s_es_server_error; + + for(size_t l_worker_id = 0; l_worker_id < dap_events_worker_get_count() ; l_worker_id++){ + dap_events_socket_t * l_es = dap_events_socket_wrap_no_add( a_events, l_server->socket_listener, &l_callbacks); + if ( l_es){ + log_it(L_DEBUG, "Wrapped server socket %p on worker %u", l_es, l_worker_id); + l_es->_inheritor = l_server; + l_es->server = l_server; + l_es->type = DESCRIPTOR_TYPE_SOCKET_LISTENING; +#ifdef DAP_EVENTS_CAPS_EPOLL + // Prepare for multi thread listening + l_es->ev_base_flags = EPOLLET| EPOLLIN | EPOLLEXCLUSIVE; +#endif + dap_worker_add_events_socket( l_es, dap_events_worker_get_index(l_worker_id) ); + } else{ + log_it(L_WARNING, "Can't wrap event socket for %s:%u server", a_addr, a_port); + return NULL; } - -// pthread_mutex_unlock( &dsth->mutex_dlist_add_remove ); -// dap_server_kill_socket( dap_cur ); -// continue; - - log_it( L_INFO, "Got signal to close %u socket, closing...[ %u ]", dap_cur->socket, tn ); - - dap_server_remove_socket( dap_cur ); - dap_client_remote_remove( dap_cur ); - - pthread_mutex_unlock( &dsth->mutex_dlist_add_remove ); - } - - } // for - - if ( cur_time >= next_time_timeout_check ) { - - s_socket_all_check_activity( tn, cur_time ); - next_time_timeout_check = cur_time + SOCKETS_TIMEOUT_CHECK_PERIOD; - } - - pthread_mutex_lock( &dsth->mutex_dlist_add_remove ); - if ( !dsth->to_kill_count ) { - - pthread_mutex_unlock( &dsth->mutex_dlist_add_remove ); - continue; } + return l_server; +} + + +/** + * @brief s_es_server_error + * @param a_es + * @param a_arg + */ +static void s_es_server_error(dap_events_socket_t *a_es, void * a_arg) +{ + (void) a_arg; + (void) a_es; + char l_buf[128]; + strerror_r(errno, l_buf, sizeof (l_buf)); + log_it(L_WARNING, "Listening socket error: %s, ", l_buf); +} + +/** + * @brief s_es_server_read + * @param a_es + * @param a_arg + */ +static void s_es_server_read(dap_events_socket_t *a_es,void * a_arg) +{ + (void) a_arg; + a_es->buf_in_size = 0; // It should be 1 so we reset it to 0 + //log_it(L_DEBUG, "Server socket %d is active",i); + dap_server_t * l_server = (dap_server_t*) a_es->_inheritor; + if( l_server ){ + dap_events_socket_t * l_es_new = NULL; + log_it(L_DEBUG, "Listening socket (binded on %s:%u) got new incomming connection",l_server->address,l_server->port); + struct sockaddr client_addr = {0}; + socklen_t client_addr_size = sizeof(struct sockaddr); + int l_es_new_socket; + while ( (l_es_new_socket = accept(a_es->socket ,&client_addr,&client_addr_size)) > 0){ + log_it(L_DEBUG, "Accepted new connection (sock %d from %d)", l_es_new_socket, a_es->socket); + l_es_new = dap_server_events_socket_new(a_es->events,l_es_new_socket,&l_server->client_callbacks,l_server); + + getnameinfo(&client_addr,client_addr_size, l_es_new->hostaddr + , sizeof(l_es_new->hostaddr),l_es_new->service,sizeof(l_es_new->service), + NI_NUMERICHOST | NI_NUMERICSERV); + log_it(L_INFO,"Connection accepted from %s (%s)", l_es_new->hostaddr, l_es_new->service ); + dap_worker_add_events_socket_auto(l_es_new); + } + if ( l_es_new_socket == -1 && errno == EAGAIN){ + // Everything is good, we'll receive ACCEPT on next poll + return; + }else{ + log_it(L_WARNING,"accept() returned %d",l_es_new_socket); + } - dap_cur = dsth->dap_clients_to_kill; - - do { - - if ( dap_cur->no_close ) { - dap_cur = dap_cur->knext; - continue; - } - - log_it( L_INFO, "Kill %u socket ...............[ thread %u ]", dap_cur->socket, tn ); - - tmp = dap_cur->knext; - DL_LIST_REMOVE_NODE( dsth->dap_clients_to_kill, dap_cur, kprev, knext, dsth->to_kill_count ); - - dap_server_remove_socket( dap_cur ); - dap_client_remote_remove( dap_cur ); - dap_cur = tmp; - - } while ( dap_cur ); - - log_it( L_INFO, "[ Thread %u ] coneections: %u, to kill: %u", tn, dsth->connections_count, dsth->to_kill_count ); - pthread_mutex_unlock( &dsth->mutex_dlist_add_remove ); - - } while( !bQuitSignal ); - - return NULL; + }else + log_it(L_ERROR, "No sap_server object related with socket %d in the select loop",a_es->socket); } -/* -========================================================= - dap_server_loop( ) - - Main server loop - @param a_server Server instance - @return Zero if ok others if not -========================================================= -*/ -int32_t dap_server_loop( dap_server_t *d_server ) +/** + * @brief dap_server_events_socket_new + * @param a_events + * @param a_sock + * @param a_callbacks + * @param a_server + * @return + */ +dap_events_socket_t * dap_server_events_socket_new(dap_events_t * a_events, int a_sock, + dap_events_socket_callbacks_t * a_callbacks, dap_server_t * a_server) { - int errCode = 0; - - if(d_server == NULL){ - log_it(L_ERROR, "Server is NULL"); - return -1; - } - - _current_run_server = d_server; - - EPOLL_HANDLE efd = epoll_create1( 0 ); - if ( (intptr_t)efd == -1 ) { - return -10; - } - - struct epoll_event pev; - struct epoll_event events[ 16 ]; - - memset(&pev, 0, sizeof(pev)); - pev.events = EPOLLIN | EPOLLERR; - pev.data.fd = d_server->socket_listener; + dap_events_socket_t * ret = NULL; + if (a_sock > 0) { + // set it nonblock + //fcntl(a_sock, F_SETFL, O_NONBLOCK); - if( epoll_ctl( efd, EPOLL_CTL_ADD, d_server->socket_listener, &pev) != 0 ) { - log_it( L_ERROR, "epoll_ctl failed 004" ); - return -20; - } + ret = dap_events_socket_wrap_no_add(a_events, a_sock, a_callbacks); + ret->type = DESCRIPTOR_TYPE_SOCKET; + ret->server = a_server; - while( !bQuitSignal && errCode == 0 ) { - int32_t n = epoll_wait( efd, &events[0], 16, 1000 ); - - if ( bQuitSignal ) - break; - - if ( n < 0 ) { - if ( errno == EINTR ) - continue; - log_it( L_ERROR, "Server wakeup on error: %i", errno ); - errCode = -30; + } else { + log_it(L_CRITICAL,"Accept error: %s",strerror(errno)); } - - for( int32_t i = 0; i < n && errCode == 0; ++i ) { - - if ( events[i].events & EPOLLIN ) { - int client_fd = accept( events[i].data.fd, 0, 0 ); - - if ( client_fd < 0 ) { - log_it( L_ERROR, "accept_cb: error accept socket"); - continue; - } - - set_nonblock_socket( client_fd ); - dap_server_add_socket( client_fd, -1 ); - } - else if( events[i].events & EPOLLERR ) { - log_it( L_ERROR, "Server socket error event" ); - errCode = -40; - } - - } // for - } // while - - if (efd != -1) { - #ifndef _WIN32 - close( efd ); - #else - epoll_close( efd ); - #endif - } - - return errCode; + return ret; } diff --git a/dap-sdk/net/core/dap_timerfd.c b/dap-sdk/net/core/dap_timerfd.c index 625139a0422a68c0bb4c20aff26be734256d546d..a81f2024f1a6725d76062062aedfdec3ecd9ab04 100644 --- a/dap-sdk/net/core/dap_timerfd.c +++ b/dap-sdk/net/core/dap_timerfd.c @@ -1,26 +1,25 @@ /* * Authors: * Alexander Lysikov <alexander.lysikov@demlabs.net> - * DeM Labs Inc. https://demlabs.net - * Kelvin Project https://github.com/kelvinblockchain + * DeM Labs Ltd. https://demlabs.net * Copyright (c) 2020 * All rights reserved. - This file is part of DAP (Deus Applications Prototypes) the open source project + This file is part of DAP SDK the open source project - DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + DAP SDK is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - DAP is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + DAP SDK is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. - */ + You should have received a copy of the GNU General Public License + along with any DAP SDK based project. If not, see <http://www.gnu.org/licenses/>. +*/ #ifndef WIN32 #include <stdint.h> #include <stdbool.h> diff --git a/dap-sdk/net/core/dap_traffic_track.c b/dap-sdk/net/core/dap_traffic_track.c deleted file mode 100644 index 44c7506a6c426d84dcdfd0ce7aec280e8f766b46..0000000000000000000000000000000000000000 --- a/dap-sdk/net/core/dap_traffic_track.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Authors: - * Anatoliy Kurotich <anatoliy.kurotich@demlabs.net> - * DeM Labs Inc. https://demlabs.net - * Kelvin Project https://github.com/kelvinblockchain - * Copyright (c) 2017-2018 - * All rights reserved. - - This file is part of DAP (Deus Applications Prototypes) the open source project - - DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - DAP is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include <string.h> -#include <time.h> -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> - -#ifndef _WIN32 -#include <pthread.h> -#include <ev.h> -#else -#include <winsock2.h> -#include <windows.h> -#include <mswsock.h> -#include <ws2tcpip.h> -#include <io.h> -#include <pthread.h> -#endif - -#include "dap_traffic_track.h" -#include "dap_common.h" -#include "dap_cpu_monitor.h" - -#define LOG_TAG "dap_traffic_track" - -#define BITS_IN_BYTE 8 -#define ALLOC_STEP 100 - -static dap_traffic_callback_t _callback = NULL; -static dap_server_t *_dap_server; - -#ifndef _WIN32 -static ev_timer _timeout_watcher; -static struct ev_loop *loop; -#else -static HANDLE _timeout_watcher; -#endif -static size_t timertimeout = 1; - -static pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t _cond = PTHREAD_COND_INITIALIZER; -static pthread_t worker_thread; -static bool _stop_worker_signal = false; - - -/** - * @brief calculate_mbits_speed - * @param count_bytes - * @details timeout we gots from _timeout_watcher.repeat - * @return mbit/second speed - */ -static double _calculate_mbits_speed( size_t count_bytes ) -{ - size_t bits_per_second = (count_bytes / timertimeout) * BITS_IN_BYTE; - // log_it(L_DEBUG, "TIMEOUT: %d, bits_per_second: %d mbits: %f", - // (size_t)_timeout_watcher.repeat, bits_per_second, bits_per_second / 1000000.0); - return (double)bits_per_second / 1000000.0; // convert to mbits -} - -void *_worker_run( void *a ) -{ - (void)a; - - pthread_mutex_lock( &_mutex ); - - while( true ) { - pthread_cond_wait( &_cond, &_mutex ); - if ( _stop_worker_signal ) { - log_it(L_INFO, "Dap traffic track worker stopped"); - _stop_worker_signal = false; - break; - } - _callback( _dap_server ); - } - - pthread_mutex_unlock( &_mutex ); - return NULL; -} - -void _worker_start( ) -{ - pthread_mutex_init( &_mutex, NULL ); - pthread_cond_init( &_cond, NULL ); - pthread_create( &worker_thread, NULL, _worker_run, NULL ); -} - -void _worker_stop() -{ - pthread_mutex_lock( &_mutex ); - _stop_worker_signal = true; - pthread_cond_signal( &_cond ); - pthread_mutex_unlock( &_mutex ); - - // wait for exit worker_thread - pthread_join( worker_thread, NULL ); - - pthread_mutex_destroy( &_mutex ); - pthread_cond_destroy( &_cond ); - _callback = NULL; -} - -#ifndef _WIN32 -static void _timeout_cb( ) -#else -VOID CALLBACK _timeout_cb( void *lpParameter, BOOL TimerOrWaitFired ) -#endif -{ -#if 0 - pthread_mutex_lock( &_dap_server->mutex_on_hash ); - - size_t count_users = HASH_COUNT(_dap_server->clients ); - - if ( count_users ) { -// size_t idx = 0; - dap_client_remote_t *dap_cur, *tmp; - HASH_ITER( hh, _dap_server->clients, dap_cur, tmp ) { - - dap_cur->upload_stat.speed_mbs = _calculate_mbits_speed( dap_cur->upload_stat.buf_size_total - - dap_cur->upload_stat.buf_size_total_old ); - - dap_cur->upload_stat.buf_size_total_old = dap_cur->upload_stat.buf_size_total; - - dap_cur->download_stat.speed_mbs = _calculate_mbits_speed( dap_cur->download_stat.buf_size_total - - dap_cur->download_stat.buf_size_total_old ); - - dap_cur->download_stat.buf_size_total_old = dap_cur->download_stat.buf_size_total; - -// idx ++; - } - } - - /* TODO find some better solution and place for this line */ - _dap_server->cpu_stats = dap_cpu_get_stats( ); - - pthread_mutex_unlock( &_dap_server->mutex_on_hash ); -#endif - - if ( _callback != NULL ) { - pthread_mutex_lock( &_mutex ); - pthread_cond_signal( &_cond ); - pthread_mutex_unlock( &_mutex ); - } -} - -void dap_traffic_track_init( dap_server_t * server, - time_t timeout ) -{ - dap_cpu_monitor_init( ); - - _dap_server = server; -#ifndef _WIN32 - _timeout_watcher.repeat = timeout; - - loop = EV_DEFAULT; - - ev_init( &_timeout_watcher, _timeout_cb ); - ev_timer_again( loop, &_timeout_watcher ); -#else - - timertimeout = timeout; - - CreateTimerQueueTimer( &_timeout_watcher, NULL, (WAITORTIMERCALLBACK)_timeout_cb, NULL, timertimeout, timertimeout, 0 ); - -#endif - - log_it(L_NOTICE, "Initialized traffic track module"); -} - -void dap_traffic_track_deinit() -{ - if ( _callback != NULL ) - _worker_stop(); - -#ifndef _WIN32 - ev_timer_stop( loop, &_timeout_watcher ); - ev_loop_destroy( loop ); -#else - DeleteTimerQueueTimer( NULL, _timeout_watcher, NULL ); -#endif - - log_it( L_NOTICE, "Deinitialized traffic track module" ); - dap_cpu_monitor_deinit( ); -} - -void dap_traffic_callback_stop() { - - if ( _callback == NULL ) { - log_it( L_WARNING, "worker not running" ); - return; - } - _worker_stop(); -} - -void dap_traffic_callback_set(dap_traffic_callback_t cb) -{ - if( _callback == NULL ) { - _callback = cb; - _worker_start(); - return; - } - - log_it( L_WARNING, "Callback already setted" ); -} diff --git a/dap-sdk/net/core/dap_worker.c b/dap-sdk/net/core/dap_worker.c new file mode 100644 index 0000000000000000000000000000000000000000..6477a4b2055c36592f00bf5e5ba9a7161cb04257 --- /dev/null +++ b/dap-sdk/net/core/dap_worker.c @@ -0,0 +1,460 @@ +/* + * Authors: + * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net> + * DeM Labs Ltd. https://demlabs.net + * Copyright (c) 2017 + * All rights reserved. + + This file is part of DAP SDK the open source project + + DAP SDK is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + DAP SDK is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with any DAP SDK based project. If not, see <http://www.gnu.org/licenses/>. +*/ +#include <time.h> +#include <errno.h> +#include <unistd.h> +#include "dap_common.h" +#include "dap_math_ops.h" +#include "dap_worker.h" +#include "dap_events.h" + +#define LOG_TAG "dap_worker" + + +static time_t s_connection_timeout = 6000; + + +static void s_socket_all_check_activity( dap_worker_t *dap_worker, dap_events_t *a_events, time_t cur_time ); +static void s_new_es_callback( dap_events_socket_t * a_es, void * a_arg); +static void s_delete_es_callback( dap_events_socket_t * a_es, void * a_arg); +static void s_reassign_es_callback( dap_events_socket_t * a_es, void * a_arg); + +/** + * @brief dap_worker_init + * @param a_threads_count + * @param conn_timeout + * @return + */ +int dap_worker_init( size_t a_conn_timeout ) +{ + if ( a_conn_timeout ) + s_connection_timeout = a_conn_timeout; + return 0; +} + +void dap_worker_deinit( ) +{ +} + +/** + * @brief dap_worker_thread + * @param arg + * @return + */ +void *dap_worker_thread(void *arg) +{ + dap_events_socket_t *l_cur; + dap_worker_t *l_worker = (dap_worker_t *) arg; + time_t l_next_time_timeout_check = time( NULL) + s_connection_timeout / 2; + uint32_t l_tn = l_worker->id; + +#ifndef _WIN32 +#ifndef NO_POSIX_SHED + cpu_set_t mask; + CPU_ZERO(&mask); + CPU_SET(l_tn, &mask); + + int err; +#ifndef __ANDROID__ + err = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &mask); +#else + err = sched_setaffinity(pthread_self(), sizeof(cpu_set_t), &mask); +#endif + if(err) + { + log_it(L_CRITICAL, "Error pthread_setaffinity_np() You really have %d or more core in CPU?", *(int* )arg); + abort(); + } +#endif +#else + + if ( !SetThreadAffinityMask( GetCurrentThread(), (DWORD_PTR)(1 << tn) ) ) { + log_it( L_CRITICAL, "Error pthread_setaffinity_np() You really have %d or more core in CPU?", tn ); + abort(); + } + #endif + + l_worker->event_new_es = dap_events_socket_create_type_event( l_worker, s_new_es_callback); + l_worker->event_delete_es = dap_events_socket_create_type_event( l_worker, s_new_es_callback); + + log_it(L_INFO, "Worker %d started, epoll fd %d", l_worker->id, l_worker->epoll_fd); +#ifdef DAP_EVENTS_CAPS_EPOLL + struct epoll_event l_epoll_events[ DAP_MAX_EPOLL_EVENTS]= {{0}}; +#else +#error "Unimplemented socket array for this platform" +#endif + + bool s_loop_is_active = true; + + while(s_loop_is_active) { +#ifdef DAP_EVENTS_CAPS_EPOLL + int l_selected_sockets = epoll_wait(l_worker->epoll_fd, l_epoll_events, DAP_MAX_EPOLL_EVENTS, -1); +#else +#error "Unimplemented poll wait analog for this platform" +#endif + if(l_selected_sockets == -1) { + if( errno == EINTR) + continue; + log_it(L_ERROR, "Worker thread %d got errno: %d", l_worker->id, errno); + break; + } + + time_t l_cur_time = time( NULL); + for(int32_t n = 0; n < l_selected_sockets; n++) { + + l_cur = (dap_events_socket_t *) l_epoll_events[n].data.ptr; + if(!l_cur) { + log_it(L_ERROR, "dap_events_socket NULL"); + continue; + } + l_cur->last_time_active = l_cur_time; + + //log_it(L_DEBUG, "Worker=%d fd=%d socket=%d event=0x%x(%d)", w->number_thread, w->epoll_fd,cur->socket, events[n].events,events[n].events); + int l_sock_err = 0, l_sock_err_size = sizeof(l_sock_err); + //connection already closed (EPOLLHUP - shutdown has been made in both directions) + if(l_epoll_events[n].events & EPOLLHUP) { // && events[n].events & EPOLLERR) { + switch (l_cur->type ){ + case DESCRIPTOR_TYPE_SOCKET_LISTENING: + case DESCRIPTOR_TYPE_SOCKET: + getsockopt(l_cur->socket, SOL_SOCKET, SO_ERROR, (void *)&l_sock_err, (socklen_t *)&l_sock_err_size); + //if(!(events[n].events & EPOLLIN)) + //cur->no_close = false; + if (l_sock_err) { + l_cur->flags |= DAP_SOCK_SIGNAL_CLOSE; + log_it(L_DEBUG, "Socket shutdown (EPOLLHUP): %s", strerror(l_sock_err)); + } + default: log_it(L_WARNING, "Unimplemented EPOLLHUP for socket type %d", l_cur->type); + } + } + + if(l_epoll_events[n].events & EPOLLERR) { + switch (l_cur->type ){ + case DESCRIPTOR_TYPE_SOCKET_LISTENING: + case DESCRIPTOR_TYPE_SOCKET: + getsockopt(l_cur->socket, SOL_SOCKET, SO_ERROR, (void *)&l_sock_err, (socklen_t *)&l_sock_err_size); + log_it(L_ERROR, "Socket error: %s", strerror(l_sock_err)); + default: ; + } + l_cur->flags |= DAP_SOCK_SIGNAL_CLOSE; + l_cur->callbacks.error_callback(l_cur, NULL); // Call callback to process error event + } + + + if(l_epoll_events[n].events & EPOLLIN) { + + //log_it(DEBUG,"Comes connection in active read set"); + if(l_cur->buf_in_size == sizeof(l_cur->buf_in)) { + log_it(L_WARNING, "Buffer is full when there is smth to read. Its dropped!"); + l_cur->buf_in_size = 0; + } + + int32_t l_bytes_read = 0; + int l_errno=0; + bool l_must_read_smth = false; + switch (l_cur->type) { + case DESCRIPTOR_TYPE_FILE: + l_must_read_smth = true; + l_bytes_read = read(l_cur->socket, (char *) (l_cur->buf_in + l_cur->buf_in_size), + sizeof(l_cur->buf_in) - l_cur->buf_in_size); + l_errno = errno; + break; + case DESCRIPTOR_TYPE_SOCKET: + l_must_read_smth = true; + l_bytes_read = recv(l_cur->fd, (char *) (l_cur->buf_in + l_cur->buf_in_size), + sizeof(l_cur->buf_in) - l_cur->buf_in_size, 0); + l_errno = errno; + break; + case DESCRIPTOR_TYPE_SOCKET_LISTENING: + // Accept connection + break; + case DESCRIPTOR_TYPE_TIMER:{ + uint64_t val; + /* if we not reading data from socket, he triggered again */ + read( l_cur->fd, &val, 8); + if (l_cur->callbacks.timer_callback) + l_cur->callbacks.timer_callback(l_cur); + else + log_it(L_ERROR, "Socket %d with timer callback fired, but callback is NULL ", l_cur->socket); + + } break; + case DESCRIPTOR_TYPE_EVENT: + if (l_cur->callbacks.event_callback){ + void * l_event_ptr = NULL; +#if defined(DAP_EVENTS_CAPS_EVENT_PIPE2) + if(read( l_cur->fd, &l_event_ptr,sizeof (&l_event_ptr)) == sizeof (&l_event_ptr)) + l_cur->callbacks.event_callback(l_cur, l_event_ptr); + else if ( (errno != EAGAIN) && (errno != EWOULDBLOCK) ) // we use blocked socket for now but who knows... + log_it(L_WARNING, "Can't read packet from pipe"); +#endif + }else + log_it(L_ERROR, "Socket %d with event callback fired, but callback is NULL ", l_cur->socket); + break; + } + + if (l_must_read_smth){ // Socket/Descriptor read + if(l_bytes_read > 0) { + l_cur->buf_in_size += l_bytes_read; + //log_it(DEBUG, "Received %d bytes", bytes_read); + l_cur->callbacks.read_callback(l_cur, NULL); // Call callback to process read event. At the end of callback buf_in_size should be zero if everything was read well + } + else if(l_bytes_read < 0) { + if (l_errno != EAGAIN && l_errno != EWOULDBLOCK){ // Socket is blocked + log_it(L_ERROR, "Some error occured in recv() function: %s", strerror(errno)); + dap_events_socket_set_readable_unsafe(l_cur, false); + l_cur->flags |= DAP_SOCK_SIGNAL_CLOSE; + } + } + else if(l_bytes_read == 0) { + log_it(L_INFO, "Client socket disconnected"); + dap_events_socket_set_readable_unsafe(l_cur, false); + l_cur->flags |= DAP_SOCK_SIGNAL_CLOSE; + } + } + } + + // Socket is ready to write + if(((l_epoll_events[n].events & EPOLLOUT) || (l_cur->flags & DAP_SOCK_READY_TO_WRITE)) + && !(l_cur->flags & DAP_SOCK_SIGNAL_CLOSE)) { + ///log_it(DEBUG, "Main loop output: %u bytes to send",sa_cur->buf_out_size); + if(l_cur->callbacks.write_callback) + l_cur->callbacks.write_callback(l_cur, NULL); // Call callback to process write event + + if(l_cur->flags & DAP_SOCK_READY_TO_WRITE) { + + static const uint32_t buf_out_zero_count_max = 20; + l_cur->buf_out[l_cur->buf_out_size] = 0; + + if(!l_cur->buf_out_size) { + + //log_it(L_WARNING, "Output: nothing to send. Why we are in write socket set?"); + l_cur->buf_out_zero_count++; + + if(l_cur->buf_out_zero_count > buf_out_zero_count_max) { // How many time buf_out on write event could be empty + log_it(L_ERROR, "Output: nothing to send %u times, remove socket from the write set", + buf_out_zero_count_max); + dap_events_socket_set_writable_unsafe(l_cur, false); + } + } + else + l_cur->buf_out_zero_count = 0; + } + //for(total_sent = 0; total_sent < cur->buf_out_size;) { // If after callback there is smth to send - we do it + size_t l_bytes_sent =0; + int l_errno; + if(l_cur->type == DESCRIPTOR_TYPE_SOCKET) { + l_bytes_sent = send(l_cur->socket, l_cur->buf_out, + l_cur->buf_out_size, MSG_DONTWAIT | MSG_NOSIGNAL); + l_errno = errno; + }else if(l_cur->type == DESCRIPTOR_TYPE_FILE) { + l_bytes_sent = write(l_cur->socket, (char *) (l_cur->buf_out + l_bytes_sent), + l_cur->buf_out_size ); + l_errno = errno; + } + + if(l_bytes_sent < 0) { + if (l_errno != EAGAIN && l_errno != EWOULDBLOCK ){ // If we have non-blocking socket + log_it(L_ERROR, "Some error occured in send(): %s", strerror(errno)); + l_cur->flags |= DAP_SOCK_SIGNAL_CLOSE; + break; + } + }else{ + l_bytes_sent += l_bytes_sent; + //log_it(L_DEBUG, "Output: %u from %u bytes are sent ", total_sent,sa_cur->buf_out_size); + //} + //log_it(L_DEBUG,"Output: sent %u bytes",total_sent); + if (l_bytes_sent) { + pthread_mutex_lock(&l_cur->mutex); + l_cur->buf_out_size -= l_bytes_sent; + if (l_cur->buf_out_size) { + memmove(l_cur->buf_out, &l_cur->buf_out[l_bytes_sent], l_cur->buf_out_size); + } else { + l_cur->flags &= ~DAP_SOCK_READY_TO_WRITE; + } + pthread_mutex_unlock(&l_cur->mutex); + } + } + } + + if((l_cur->flags & DAP_SOCK_SIGNAL_CLOSE) && !l_cur->no_close) { + // protect against double deletion + l_cur->kill_signal = true; + //dap_events_socket_remove_and_delete(cur, true); + log_it(L_INFO, "Got signal to close %s, sock %u [thread %u]", l_cur->hostaddr, l_cur->socket, l_tn); + } + + if(l_cur->kill_signal) { + log_it(L_INFO, "Kill %u socket (processed).... [ thread %u ]", l_cur->socket, l_tn); + dap_events_socket_delete_unsafe( l_cur, false); + } + + } + +#ifndef NO_TIMER + if(l_cur_time >= l_next_time_timeout_check) { + s_socket_all_check_activity(l_worker, l_worker->events, l_cur_time); + l_next_time_timeout_check = l_cur_time + s_connection_timeout / 2; + } +#endif + + } // while + + return NULL; +} + +/** + * @brief s_new_es_callback + * @param a_es + * @param a_arg + */ +static void s_new_es_callback( dap_events_socket_t * a_es, void * a_arg) +{ + dap_events_socket_t * l_es_new =(dap_events_socket_t *) a_arg; + dap_worker_t * w = a_es->worker; + log_it(L_DEBUG, "Received event socket %p to add on worker", l_es_new); + l_es_new->worker = w; + if ( l_es_new->type == DESCRIPTOR_TYPE_SOCKET || l_es_new->type == DESCRIPTOR_TYPE_SOCKET_LISTENING ){ + int l_cpu = w->id; + setsockopt(l_es_new->socket , SOL_SOCKET, SO_INCOMING_CPU, &l_cpu, sizeof(l_cpu)); + } + + if ( ! l_es_new->is_initalized ){ + if (l_es_new->callbacks.new_callback) + l_es_new->callbacks.new_callback(l_es_new, NULL); + l_es_new->is_initalized = true; + } + + if (l_es_new->socket>0){ + pthread_rwlock_wrlock(&w->events->sockets_rwlock); + HASH_ADD_INT(w->events->sockets, socket, l_es_new ); + pthread_rwlock_unlock(&w->events->sockets_rwlock); + + struct epoll_event l_ev={0}; + l_ev.events = l_es_new->flags ; + if(l_es_new->flags & DAP_SOCK_READY_TO_READ ) + l_ev.events |= EPOLLIN; + if(l_es_new->flags & DAP_SOCK_READY_TO_WRITE ) + l_ev.events |= EPOLLOUT; + l_ev.data.ptr = l_es_new; + + if ( epoll_ctl(w->epoll_fd, EPOLL_CTL_ADD, l_es_new->socket, &l_ev) == 1 ) + log_it(L_CRITICAL,"Can't add event socket's handler to epoll_fd"); + else{ + log_it(L_DEBUG, "Added socket %d on worker %u", l_es_new->socket, w->id); + if (l_es_new->callbacks.worker_assign_callback) + l_es_new->callbacks.worker_assign_callback(l_es_new, w); + + } + }else{ + log_it(L_ERROR, "Incorrect socket %d after new callback. Dropping this handler out", l_es_new->socket); + dap_events_socket_delete_unsafe( l_es_new, false ); + } +} + +/** + * @brief s_delete_es_callback + * @param a_es + * @param a_arg + */ +static void s_delete_es_callback( dap_events_socket_t * a_es, void * a_arg) +{ + ((dap_events_socket_t*)a_arg)->kill_signal = true; // Send signal to socket to kill +} + +/** + * @brief s_reassign_es_callback + * @param a_es + * @param a_arg + */ +static void s_reassign_es_callback( dap_events_socket_t * a_es, void * a_arg) +{ + dap_events_socket_t * l_es_reassign = ((dap_events_socket_t* ) a_arg); + dap_events_socket_remove_from_worker_unsafe( l_es_reassign, a_es->worker ); + if (l_es_reassign->callbacks.worker_unassign_callback) + l_es_reassign->callbacks.worker_unassign_callback(l_es_reassign, a_es->worker); + + dap_events_socket_assign_on_worker( l_es_reassign, l_es_reassign->worker ); +} + +/** + * @brief s_socket_info_all_check_activity + * @param n_thread + * @param sh + */ +static void s_socket_all_check_activity( dap_worker_t *dap_worker, dap_events_t *a_events, time_t cur_time ) +{ + dap_events_socket_t *a_es, *tmp; + + pthread_rwlock_rdlock(&a_events->sockets_rwlock); + HASH_ITER(hh, a_events->sockets, a_es, tmp ) { + + if ( a_es->type == DESCRIPTOR_TYPE_FILE) + continue; + + if ( !a_es->kill_signal && cur_time >= (time_t)a_es->last_time_active + s_connection_timeout && !a_es->no_close ) { + + log_it( L_INFO, "Socket %u timeout, closing...", a_es->socket ); + if (a_es->callbacks.error_callback) { + a_es->callbacks.error_callback(a_es, (void *)ETIMEDOUT); + } + + if ( epoll_ctl( dap_worker->epoll_fd, EPOLL_CTL_DEL, a_es->socket, &a_es->ev) == -1 ) + log_it( L_ERROR,"Can't remove event socket's handler from the epoll_fd" ); + else + log_it( L_DEBUG,"Removed epoll's event from dap_worker #%u", dap_worker->id ); + + pthread_rwlock_unlock(&a_events->sockets_rwlock); + dap_events_socket_delete_unsafe(a_es, true ); + pthread_rwlock_rdlock(&a_events->sockets_rwlock); + } + } + pthread_rwlock_unlock(&a_events->sockets_rwlock); + +} + +/** + * @brief sap_worker_add_events_socket + * @param a_events_socket + * @param a_worker + */ +void dap_worker_add_events_socket(dap_events_socket_t * a_events_socket, dap_worker_t * a_worker) +{ + dap_events_socket_send_event( a_worker->event_new_es, a_events_socket ); +} + +/** + * @brief dap_worker_add_events_socket + * @param a_worker + * @param a_events_socket + */ +void dap_worker_add_events_socket_auto( dap_events_socket_t *a_es) +{ +// struct epoll_event ev = {0}; + dap_worker_t *l_worker = dap_events_worker_get_min( ); + + a_es->worker = l_worker; + a_es->events = a_es->worker->events; + dap_worker_add_events_socket( a_es, l_worker); +} + + + diff --git a/dap-sdk/net/core/include/dap_client_remote.h b/dap-sdk/net/core/include/dap_client_remote.h deleted file mode 100644 index 00a70653d7f63c2d836c17f9586b6b6f6a61eab6..0000000000000000000000000000000000000000 --- a/dap-sdk/net/core/include/dap_client_remote.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Authors: - * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net> - * DeM Labs Inc. https://demlabs.net - * Kelvin Project https://github.com/kelvinblockchain - * Copyright (c) 2017-2018 - * All rights reserved. - - This file is part of DAP (Deus Applications Prototypes) the open source project - - DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - DAP is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. -*/ -#pragma once - -#include <stdint.h> -#include <stddef.h> -#include <stdbool.h> -#include "uthash.h" - -#ifndef WIN32 -#include <sys/epoll.h> -#include <sys/timerfd.h> -#endif - -#ifndef EPOLL_HANDLE - #ifndef WIN32 - #define EPOLL_HANDLE int - #else - #define EPOLL_HANDLE HANDLE - #include "wepoll.h" - #endif -#endif - -typedef char str_ip[16]; - -typedef struct dap_server dap_server_t; -typedef struct dap_server_thread_s dap_server_thread_t; - -struct dap_client_remote; - -typedef void (*dap_server_client_callback_t) (struct dap_client_remote *,void * arg); // Callback for specific client operations - -#define DAP_CLIENT_REMOTE_BUF 500000 -#define CLIENT_ID_SIZE 12 - -typedef char dap_server_client_id[CLIENT_ID_SIZE]; - -typedef struct traffic_stats { - - size_t buf_size_total; - size_t buf_size_total_old; // for calculate speed - double speed_mbs; // MegaBits per second -} traffic_stats_t; - -typedef struct dap_client_remote { - - int socket; - dap_server_client_id id; - - uint32_t flags; - bool no_close; - bool kill_signal; - - uint16_t port; - str_ip s_ip; - - uint32_t buf_out_zero_count; - char buf_in[DAP_CLIENT_REMOTE_BUF]; // Internal buffer for input data - - size_t buf_in_size; // size of data that is in the input buffer - - traffic_stats_t upload_stat; - traffic_stats_t download_stat; - - char buf_out[DAP_CLIENT_REMOTE_BUF]; // Internal buffer for output data - size_t buf_out_offset; - - char hostaddr[1024]; // Address - char service[128]; - - size_t buf_out_size; // size of data that is in the output buffer - struct epoll_event pevent; - - EPOLL_HANDLE efd; // Epoll fd - int tn; // working thread index - - time_t time_connection; - time_t last_time_active; - - struct dap_server *server; - dap_server_thread_t *thread; - - UT_hash_handle hh; - struct dap_client_remote *next, *prev; - struct dap_client_remote *knext, *kprev; - - void *_internal; - void *_inheritor; // Internal data to specific client type, usualy states for state machine - -} dap_client_remote_t; // Node of bidirectional list of clients - -int dap_client_remote_init( void ); // Init clients module -void dap_client_remote_deinit( void ); // Deinit clients module - -dap_client_remote_t *dap_client_remote_create( dap_server_t *sh, int s, dap_server_thread_t *dsth ); -dap_client_remote_t *dap_client_remote_find( int sock, dap_server_thread_t *t ); - -bool dap_client_remote_is_ready_to_read( dap_client_remote_t * sc ); -bool dap_client_remote_is_ready_to_write( dap_client_remote_t * sc ); -void dap_client_remote_ready_to_read( dap_client_remote_t * sc,bool is_ready ); -void dap_client_remote_ready_to_write( dap_client_remote_t * sc,bool is_ready ); - -size_t dap_client_remote_write( dap_client_remote_t *sc, const void * data, size_t data_size ); -size_t dap_client_remote_write_f( dap_client_remote_t *a_client, const char * a_format,... ); -size_t dap_client_remote_read( dap_client_remote_t *sc, void * data, size_t data_size ); - -//void dap_client_remote_remove( dap_client_remote_t *sc, struct dap_server * sh ); // Removes the client from the list -void dap_client_remote_remove( dap_client_remote_t *sc ); - -void dap_client_remote_shrink_buf_in( dap_client_remote_t * cl, size_t shrink_size ); - diff --git a/dap-sdk/net/core/include/dap_events.h b/dap-sdk/net/core/include/dap_events.h index 16e5eb3abc2c0800ffc324083e8732b8abe1344e..7e4adebcfd9f0d5183ae7abee8f1a52563a29cd7 100644 --- a/dap-sdk/net/core/include/dap_events.h +++ b/dap-sdk/net/core/include/dap_events.h @@ -23,23 +23,12 @@ */ #pragma once -#ifndef WIN32 -#include <netinet/in.h> - -#include <stdint.h> -#include <pthread.h> -#include <stdatomic.h> -#include <sys/eventfd.h> -#define EPOLL_HANDLE int -#else -#define EPOLL_HANDLE HANDLE -#endif - #include "uthash.h" #include "dap_events_socket.h" #include "dap_server.h" - +#include "dap_worker.h" struct dap_events; +#define DAP_MAX_EPOLL_EVENTS 8192 typedef void (*dap_events_callback_t) (struct dap_events *, void *arg); // Callback for specific server's operations @@ -47,8 +36,6 @@ typedef struct dap_thread { pthread_t tid; } dap_thread_t; -struct dap_worker; - typedef struct dap_events { dap_events_socket_t *sockets; // Hashmap of event sockets @@ -59,37 +46,20 @@ typedef struct dap_events { } dap_events_t; -typedef struct dap_worker -{ - uint32_t id; - atomic_uint event_sockets_count; - - dap_events_socket_t * event_new_es; // Events socket for new socket - dap_events_socket_t * event_delete_es; // Events socket for new socket - EPOLL_HANDLE epoll_fd; - pthread_mutex_t locker_on_count; - dap_events_t *events; -} dap_worker_t; - -int32_t dap_events_init( uint32_t a_threads_count, size_t conn_t ); // Init server module +int dap_events_init( uint32_t a_threads_count, size_t a_conn_timeout ); // Init server module void dap_events_deinit( ); // Deinit server module -void dap_events_thread_wake_up( dap_thread_t *th ); dap_events_t* dap_events_new( ); -void dap_events_delete( dap_events_t * sh ); - -int32_t dap_events_start( dap_events_t *sh ); -void dap_events_stop(); -int32_t dap_events_wait( dap_events_t *sh ); - -uint32_t dap_worker_get_index_min( ); -dap_worker_t *dap_worker_get_min( ); +void dap_events_delete( dap_events_t * a_events ); -uint32_t dap_get_cpu_count( ); -dap_worker_t * dap_worker_get_index(uint8_t a_index); +int32_t dap_events_start( dap_events_t *a_events ); +void dap_events_stop_all(); +int32_t dap_events_wait( dap_events_t *a_events ); -void dap_events_socket_assign_on_worker(dap_events_socket_t * a_es, struct dap_worker * a_worker); -void dap_worker_add_events_socket(dap_events_socket_t * a_events_socket, dap_worker_t * a_worker); -void dap_worker_add_events_socket_auto( dap_events_socket_t * a_events_socket ); -void dap_worker_print_all( ); +void dap_events_worker_print_all( ); +uint32_t dap_events_worker_get_index_min( ); +uint32_t dap_events_worker_get_count(); +dap_worker_t *dap_events_worker_get_min( ); +dap_worker_t * dap_events_worker_get_index(uint8_t a_index); +uint32_t dap_get_cpu_count(); diff --git a/dap-sdk/net/core/include/dap_events_socket.h b/dap-sdk/net/core/include/dap_events_socket.h index 8f1d846930bdd37607daa0f5dc488aa4e5226286..e2fffd4c8b27eaa8b51a1cfdc282b2a4e5a38713 100644 --- a/dap-sdk/net/core/include/dap_events_socket.h +++ b/dap-sdk/net/core/include/dap_events_socket.h @@ -1,25 +1,24 @@ /* * Authors: * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net> - * DeM Labs Inc. https://demlabs.net - * Kelvin Project https://github.com/kelvinblockchain - * Copyright (c) 2017-2019 + * DeM Labs Ltd. https://demlabs.net + * Copyright (c) 2017 * All rights reserved. - This file is part of DAP (Deus Applications Prototypes) the open source project + This file is part of DAP SDK the open source project - DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify + DAP SDK is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - DAP is distributed in the hope that it will be useful, + DAP SDK is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. + along with any DAP SDK based project. If not, see <http://www.gnu.org/licenses/>. */ #pragma once #include <stdint.h> @@ -32,10 +31,13 @@ // Caps for different platforms #if defined(DAP_OS_LINUX) #define DAP_EVENTS_CAPS_EPOLL - #define DAP_EVENTS_CAPS_EVENT_PIPE_PKT_MODE + #define DAP_EVENTS_CAPS_EVENT_PIPE2 + #include <netinet/in.h> + #include <sys/eventfd.h> #elif defined (DAP_OS_UNIX) - #define DAP_EVENTS_CAPS_POLL - #define DAP_EVENTS_CAPS_EVENT_PIPE + #define DAP_EVENTS_CAPS_KQUEUE + #define DAP_EVENTS_CAPS_EVENT_SOCKETPAIR + #include <netinet/in.h> #elif defined (DAP_OS_WINDOWS) #define DAP_EVENTS_CAPS_WEPOLL #define DAP_EVENTS_CAPS_EPOLL @@ -44,8 +46,10 @@ #if defined(DAP_EVENTS_CAPS_EPOLL) #include <sys/epoll.h> +#define EPOLL_HANDLE int #elif defined (DAP_EVENTS_CAPS_WEPOLL) #include "wepoll.h" +#define EPOLL_HANDLE HANDLE #endif typedef struct dap_events dap_events_t; @@ -92,8 +96,10 @@ typedef struct dap_events_socket { int socket; int fd; }; -#ifdef DAP_EVENTS_CAPS_EVENT_PIPE_PKT_MODE +#ifdef DAP_EVENTS_CAPS_EVENT_PIPE2 int fd2; + + int write_pipe; #endif dap_events_desc_type_t type; @@ -123,6 +129,7 @@ typedef struct dap_events_socket { dap_events_t *events; dap_worker_t *worker; + dap_server_t *server; // If this socket assigned with server #ifdef DAP_EVENTS_CAPS_EPOLL uint32_t ev_base_flags; struct epoll_event ev; @@ -134,14 +141,10 @@ typedef struct dap_events_socket { time_t last_time_active; time_t last_ping_request; bool is_pingable; - - UT_hash_handle hh; - struct dap_events_socket *next, *prev; - struct dap_events_socket *knext, *kprev; + pthread_mutex_t mutex; void *_inheritor; // Inheritor data to specific client type, usualy states for state machine - - pthread_mutex_t mutex; + UT_hash_handle hh; } dap_events_socket_t; // Node of bidirectional list of clients typedef struct dap_events_socket_event{ diff --git a/dap-sdk/net/core/include/dap_server.h b/dap-sdk/net/core/include/dap_server.h index 77f0004e0d1ee306a409e37969f55df2a37c6397..88e0d157eebedfc10db89ca114298a08f562c64c 100644 --- a/dap-sdk/net/core/include/dap_server.h +++ b/dap-sdk/net/core/include/dap_server.h @@ -1,22 +1,26 @@ /* - Copyright (c) 2017-2018 (c) Project "DeM Labs Inc" https://github.com/demlabsinc - All rights reserved. + * Authors: + * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net> + * DeM Labs Ltd. https://demlabs.net + * Copyright (c) 2017 + * All rights reserved. - This file is part of DAP (Deus Applications Prototypes) the open source project + This file is part of DAP SDK the open source project - DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by + DAP SDK is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - DAP is distributed in the hope that it will be useful, + DAP SDK is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. + GNU General Public License for more details. - You should have received a copy of the GNU Lesser General Public License - along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. + You should have received a copy of the GNU General Public License + along with any DAP SDK based project. If not, see <http://www.gnu.org/licenses/>. */ + #pragma once #ifndef _WIN32 @@ -38,7 +42,7 @@ #include "utlist.h" #include "dap_cpu_monitor.h" -#include "dap_client_remote.h" +#include "dap_events_socket.h" typedef enum dap_server_type {DAP_SERVER_TCP} dap_server_type_t; @@ -49,24 +53,6 @@ typedef enum dap_server_type {DAP_SERVER_TCP} dap_server_type_t; #define DAP_SOCK_SIGNAL_CLOSE BIT( 2 ) #define DAP_SOCK_ACTIVE BIT( 3 ) -typedef struct dap_server_thread_s { - - EPOLL_HANDLE epoll_fd; - - uint32_t thread_num; - uint32_t connections_count; - uint32_t to_kill_count; - - struct epoll_event *epoll_events; - dap_client_remote_t *dap_remote_clients; - dap_client_remote_t *hclients; // Hashmap of clients - dap_client_remote_t *dap_clients_to_kill; - - pthread_mutex_t mutex_dlist_add_remove; - pthread_mutex_t mutex_on_hash; - -} dap_server_thread_t; - struct dap_server; typedef void (*dap_server_callback_t)( struct dap_server *,void * arg ); // Callback for specific server's operations @@ -78,7 +64,7 @@ typedef struct dap_server { char *address; // Listen address int32_t socket_listener; // Socket for listener - EPOLL_HANDLE epoll_fd; // Epoll fd + dap_events_socket_t * es_listener; struct sockaddr_in listener_addr; // Kernel structure for listener's binded address @@ -86,64 +72,14 @@ typedef struct dap_server { dap_cpu_stats_t cpu_stats; - dap_server_callback_t server_delete_callback; - - dap_server_client_callback_t client_new_callback; // Create new client callback - dap_server_client_callback_t client_delete_callback; // Delete client callback - dap_server_client_callback_t client_read_callback; // Read function - dap_server_client_callback_t client_write_callback; // Write function - dap_server_client_callback_t client_error_callback; // Error processing function + dap_server_callback_t delete_callback; + dap_events_socket_callbacks_t client_callbacks; // Callbacks for the new clients } dap_server_t; -int32_t dap_server_init( uint32_t count_threads ); // Init server module -void dap_server_deinit( void ); // Deinit server module - -dap_server_t *dap_server_listen( const char *addr, uint16_t port, dap_server_type_t type ); - -int32_t dap_server_loop( dap_server_t *d_server ); -void dap_server_loop_stop( void ); - -#define DL_LIST_REMOVE_NODE( head, obj, _prev_, _next_, total ) \ - \ - if ( obj->_next_ ) { \ - \ - if ( obj->_prev_ ) \ - obj->_next_->_prev_ = obj->_prev_; \ - else { \ - \ - obj->_next_->_prev_ = NULL; \ - head = obj->_next_; \ - } \ - } \ - \ - if ( obj->_prev_ ) { \ - \ - if ( obj->_next_ ) \ - obj->_prev_->_next_ = obj->_next_; \ - else { \ - \ - obj->_prev_->_next_ = NULL; \ - } \ - } \ - -- total; - -#define DL_LIST_ADD_NODE_HEAD( head, obj, _prev_, _next_, total )\ - \ - if ( !total ) { \ - \ - obj->_prev_ = NULL; \ - obj->_next_ = NULL; \ - \ - head = obj; \ - } \ - else { \ - \ - head->_prev_ = obj; \ - \ - obj->_prev_ = NULL; \ - obj->_next_ = head; \ - \ - head = obj; \ - } \ - ++ total; +int dap_server_init( ); // Init server module +void dap_server_deinit( void ); // Deinit server module + +dap_server_t* dap_server_new(dap_events_t *a_events, const char * a_addr, uint16_t a_port, dap_server_type_t a_type); +dap_events_socket_t * dap_server_events_socket_new(dap_events_t * a_events, int a_sock, + dap_events_socket_callbacks_t * a_callbacks, dap_server_t * a_server); diff --git a/dap-sdk/net/core/include/dap_timerfd.h b/dap-sdk/net/core/include/dap_timerfd.h index a658606e8395a69668ae11d1fa430c35e5e011dd..dccd379588b51eb9b9d3a16ceba014b0c816f43e 100644 --- a/dap-sdk/net/core/include/dap_timerfd.h +++ b/dap-sdk/net/core/include/dap_timerfd.h @@ -1,27 +1,26 @@ /* * Authors: * Alexander Lysikov <alexander.lysikov@demlabs.net> - * DeM Labs Inc. https://demlabs.net - * Kelvin Project https://github.com/kelvinblockchain + * DeM Labs Ltd. https://demlabs.net * Copyright (c) 2020 * All rights reserved. - This file is part of DAP (Deus Applications Prototypes) the open source project + This file is part of DAP SDK the open source project - DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + DAP SDK is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - DAP is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. - */ + DAP SDK is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with any DAP SDK based project. If not, see <http://www.gnu.org/licenses/>. +*/ +#pragma once #include <stdint.h> #include <stdbool.h> #include <errno.h> diff --git a/dap-sdk/net/core/include/dap_traffic_track.h b/dap-sdk/net/core/include/dap_traffic_track.h deleted file mode 100644 index 1cfae9d22689621d0c99a746f96d07a9321543a3..0000000000000000000000000000000000000000 --- a/dap-sdk/net/core/include/dap_traffic_track.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Authors: - * Anatoliy Jurotich <anatoliy.kurotich@demlabs.net> - * DeM Labs Inc. https://demlabs.net - * Kelvin Project https://github.com/kelvinblockchain - * Copyright (c) 2017-2018 - * All rights reserved. - - This file is part of DAP (Deus Applications Prototypes) the open source project - - DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - DAP is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. -*/ - -#pragma once - -#include "dap_client_remote.h" -#include "dap_server.h" - -typedef void (*dap_traffic_callback_t) (dap_server_t *); - -/** - * @brief dap_traffic_track_init - * @param clients - * @param timeout callback - */ -void dap_traffic_track_init( dap_server_t *server, time_t timeout ); - -/** - * @brief dap_traffic_track_deinit - */ -void dap_traffic_track_deinit( void ); - -/** - * @brief dap_traffic_add_callback - */ -void dap_traffic_callback_set( dap_traffic_callback_t ); - -void dap_traffic_callback_stop( void ); - diff --git a/dap-sdk/net/core/include/dap_worker.h b/dap-sdk/net/core/include/dap_worker.h new file mode 100644 index 0000000000000000000000000000000000000000..558cb3ea74f9d498a56bfc50bf68560acd0ae929 --- /dev/null +++ b/dap-sdk/net/core/include/dap_worker.h @@ -0,0 +1,48 @@ +/* + * Authors: + * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net> + * DeM Labs Ltd. https://demlabs.net + * Copyright (c) 2017 + * All rights reserved. + + This file is part of DAP SDK the open source project + + DAP SDK is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + DAP SDK is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with any DAP SDK based project. If not, see <http://www.gnu.org/licenses/>. +*/ +#pragma once +#include <stdint.h> +#include <stdatomic.h> +#include "dap_events_socket.h" + +typedef struct dap_worker +{ + uint32_t id; + atomic_uint event_sockets_count; + + dap_events_socket_t * event_new_es; // Events socket for new socket + dap_events_socket_t * event_delete_es; // Events socket for new socket + EPOLL_HANDLE epoll_fd; + pthread_mutex_t locker_on_count; + dap_events_t *events; +} dap_worker_t; + +int dap_worker_init( size_t a_conn_timeout ); +void dap_worker_deinit(); + +void dap_events_socket_assign_on_worker(dap_events_socket_t * a_es, struct dap_worker * a_worker); +void dap_worker_add_events_socket(dap_events_socket_t * a_events_socket, dap_worker_t * a_worker); +void dap_worker_add_events_socket_auto( dap_events_socket_t * a_events_socket ); + +// Thread function +void *dap_worker_thread(void *arg); diff --git a/dap-sdk/net/server-udp/dap_udp_client.c b/dap-sdk/net/server-udp/dap_udp_client.c index ab13f7de654ba89a6184c4c38eb71a4e7a3c9d28..fd4e86e809fa192a12a492537eeeb2f7cd7e51d8 100644 --- a/dap-sdk/net/server-udp/dap_udp_client.c +++ b/dap-sdk/net/server-udp/dap_udp_client.c @@ -70,7 +70,7 @@ extern bool sb_payload_ready; * @param port Client port * @return Pointer to the new list's node */ -dap_client_remote_t *dap_udp_client_create( dap_server_t *dap_srv, EPOLL_HANDLE efd, unsigned long host, unsigned short port ) +dap_events_socket_t *dap_udp_client_create( dap_server_t *dap_srv, EPOLL_HANDLE efd, unsigned long host, unsigned short port ) { dap_udp_server_t *udp_server = DAP_UDP_SERVER( dap_srv ); log_it( L_DEBUG, "Client structure create with host = %x, port = %d", host, port ); @@ -78,14 +78,10 @@ dap_client_remote_t *dap_udp_client_create( dap_server_t *dap_srv, EPOLL_HANDLE dap_udp_client_t *inh = DAP_NEW_Z( dap_udp_client_t ); inh->host_key = get_key( host, port ); - dap_client_remote_t *ret = DAP_NEW_Z( dap_client_remote_t ); - inh->client = ret; - - ret->pevent.events = EPOLLIN | EPOLLERR; - ret->pevent.data.fd = dap_srv->socket_listener; + dap_events_socket_t *ret = dap_events_socket_wrap_no_add( dap_srv->es_listener->events, dap_srv->socket_listener, &dap_srv->client_callbacks); + inh->esocket = ret; ret->server = dap_srv; - ret->efd = efd; ret->flags = DAP_SOCK_READY_TO_READ; @@ -101,8 +97,8 @@ dap_client_remote_t *dap_udp_client_create( dap_server_t *dap_srv, EPOLL_HANDLE HASH_ADD_INT( udp_server->hclients, host_key, inh ); pthread_mutex_unlock( &udp_server->mutex_on_list ); - if( dap_srv->client_new_callback ) - dap_srv->client_new_callback( ret, NULL ); // Init internal structure + if( dap_srv->client_callbacks.new_callback ) + dap_srv->client_callbacks.new_callback( ret, NULL ); // Init internal structure return ret; } @@ -113,7 +109,7 @@ dap_client_remote_t *dap_udp_client_create( dap_server_t *dap_srv, EPOLL_HANDLE * @param host Variable for host address * @param host Variable for port */ -void dap_udp_client_get_address( dap_client_remote_t *client, unsigned int* host, unsigned short* port ) +void dap_udp_client_get_address( dap_events_socket_t *client, unsigned int* host, unsigned short* port ) { dap_udp_client_t* udp_client = DAP_UDP_CLIENT( client ); *host = udp_client->host_key >> 32; @@ -127,7 +123,7 @@ void dap_udp_client_get_address( dap_client_remote_t *client, unsigned int* host * @param port Source port * @return Pointer to client or NULL if not found */ -dap_client_remote_t *dap_udp_client_find( dap_server_t *dap_srv, unsigned long host, unsigned short port ) +dap_events_socket_t *dap_udp_client_find( dap_server_t *dap_srv, unsigned long host, unsigned short port ) { dap_udp_client_t *inh = NULL; dap_udp_server_t *udp_server = DAP_UDP_SERVER( dap_srv ); @@ -141,78 +137,14 @@ dap_client_remote_t *dap_udp_client_find( dap_server_t *dap_srv, unsigned long h if( inh == NULL ) return NULL; else - return inh->client; -} - -/** - * @brief udp_client_ready_to_read Set ready_to_read flag - * @param dap_rclient Client structure - * @param is_ready Flag value - */ -void dap_udp_client_ready_to_read( dap_client_remote_t *sc, bool is_ready ) -{ - if( is_ready == (bool)(sc->flags & DAP_SOCK_READY_TO_READ) ) - return; - - if ( is_ready ) - sc->flags |= DAP_SOCK_READY_TO_READ; - else - sc->flags ^= DAP_SOCK_READY_TO_READ; - - int events = EPOLLERR; - - if( sc->flags & DAP_SOCK_READY_TO_READ ) - events |= EPOLLIN; - - if( sc->flags & DAP_SOCK_READY_TO_WRITE ) - events |= EPOLLOUT; - - sc->pevent.events = events; - - if( epoll_ctl(sc->efd, EPOLL_CTL_MOD, sc->server->socket_listener, &sc->pevent) != 0 ) { - log_it( L_ERROR, "epoll_ctl failed 002" ); - } -} - -/** - * @brief udp_client_ready_to_write Set ready_to_write flag - * @param dap_rclient Client structure - * @param is_ready Flag value - */ -void dap_udp_client_ready_to_write( dap_client_remote_t *sc, bool is_ready ) -{ - if ( is_ready == (bool)(sc->flags & DAP_SOCK_READY_TO_WRITE) ) - return; - - if ( is_ready ) - sc->flags |= DAP_SOCK_READY_TO_WRITE; - else - sc->flags ^= DAP_SOCK_READY_TO_WRITE; - int events = EPOLLERR; - - if( sc->flags & DAP_SOCK_READY_TO_READ ) - events |= EPOLLIN; - - if( sc->flags & DAP_SOCK_READY_TO_WRITE ) - { - dap_udp_server_t *udp_server = DAP_UDP_SERVER(sc->server); - pthread_mutex_lock(&udp_server->mutex_on_list); - sb_payload_ready = true; - pthread_mutex_unlock(&udp_server->mutex_on_list ); - } - - sc->pevent.events = events; - - if ( epoll_ctl(sc->efd, EPOLL_CTL_MOD, sc->pevent.data.fd, &sc->pevent) != 0 ) { - log_it( L_ERROR, "epoll_ctl failed 003" ); - } + return inh->esocket; } /** * @brief add_waiting_client Add Client to write queue * @param client Client instance */ -void add_waiting_client( dap_client_remote_t *dap_rclient ) +void add_waiting_client( dap_events_socket_t *dap_rclient ) { dap_udp_client_t* udp_cl, *tmp; @@ -231,20 +163,20 @@ void add_waiting_client( dap_client_remote_t *dap_rclient ) pthread_mutex_unlock( &udp_server->mutex_on_list ); } -size_t dap_udp_client_write( dap_client_remote_t *dap_rclient, const void *data, size_t data_size ) +size_t dap_udp_client_write_unsafe( dap_events_socket_t *dap_rclient, const void *data, size_t data_size ) { - size_t size = dap_client_remote_write( dap_rclient, data, data_size ); + size_t size = dap_events_socket_write_unsafe( dap_rclient, data, data_size ); add_waiting_client( dap_rclient ); return size; } -size_t dap_udp_client_write_f( dap_client_remote_t *dap_rclient, const char * a_format, ... ) +size_t dap_udp_client_write_f( dap_events_socket_t *dap_rclient, const char * a_format, ... ) { size_t size = 0; va_list va; va_start( va, a_format ); - size = dap_client_remote_write_f( dap_rclient, a_format, va ); + size = dap_events_socket_write_f_unsafe( dap_rclient, a_format, va ); va_end( va ); add_waiting_client( dap_rclient ); diff --git a/dap-sdk/net/server-udp/dap_udp_server.c b/dap-sdk/net/server-udp/dap_udp_server.c index 12c1c82120c35e0cb5981dc38c1eca371a45f555..48b63ccd16e2ee88e26873c3b5001737a183b553 100644 --- a/dap-sdk/net/server-udp/dap_udp_server.c +++ b/dap-sdk/net/server-udp/dap_udp_server.c @@ -67,7 +67,7 @@ EPOLL_HANDLE efd_read = (EPOLL_HANDLE)-1; //static void write_cb( EPOLL_HANDLE efd, int revents ); -int check_close( dap_client_remote_t *client ); +int check_close( dap_events_socket_t *client ); /** */ @@ -113,8 +113,8 @@ void dap_udp_server_delete( dap_server_t *sh ) // HASH_ITER( hh, udps->hclients, client, tmp ) // dap_client_remote_remove( client ); - if ( sh->server_delete_callback ) - sh->server_delete_callback( sh, NULL ); + if ( sh->delete_callback ) + sh->delete_callback( sh, NULL ); if ( sh->_inheritor ) free( sh->_inheritor ); @@ -179,12 +179,12 @@ static void write_cb( EPOLL_HANDLE efd, int revents, dap_server_t *sh ) //log_it(L_INFO,"write_cb"); //pthread_mutex_lock(&udp_client->mutex_on_client); - dap_client_remote_t *client = udp_client->client; + dap_events_socket_t *client = udp_client->esocket; if( client != NULL && !check_close(client) && (client->flags & DAP_SOCK_READY_TO_WRITE) ) { - if ( sh->client_write_callback ) - sh->client_write_callback( client, NULL ); + if ( sh->client_callbacks.write_callback ) + sh->client_callbacks.write_callback( client, NULL ); if ( client->buf_out_size > 0 ) { @@ -226,25 +226,26 @@ static void write_cb( EPOLL_HANDLE efd, int revents, dap_server_t *sh ) * @param client Client structure * @return 1 if client deleted, 0 if client is no need to delete */ -int check_close( dap_client_remote_t *client ) +int check_close( dap_events_socket_t *client ) { - dap_udp_client_t *client_check, *tmp; + dap_udp_client_t *client_check, *tmp; - if( !(client->flags & DAP_SOCK_SIGNAL_CLOSE) ) return 0; + if( !(client->flags & DAP_SOCK_SIGNAL_CLOSE) ) + return 0; - dap_udp_client_t *udp_client = DAP_UDP_CLIENT( client ); - dap_server_t *sh = client->server; - dap_udp_server_t *udp_server = DAP_UDP_SERVER( sh ); + dap_udp_client_t *udp_client = DAP_UDP_CLIENT( client ); + dap_server_t *sh = client->server; + dap_udp_server_t *udp_server = DAP_UDP_SERVER( sh ); - LL_FOREACH_SAFE( udp_server->waiting_clients, client_check, tmp ) { + LL_FOREACH_SAFE( udp_server->waiting_clients, client_check, tmp ) { if ( client_check->host_key == udp_client->host_key ) - LL_DELETE( udp_server->waiting_clients, client_check ); - } + LL_DELETE( udp_server->waiting_clients, client_check ); + } - dap_client_remote_remove( client ); + dap_events_socket_queue_remove_and_delete( client ); - return 1; + return 1; } /** @@ -263,7 +264,7 @@ static void read_cb( EPOLL_HANDLE efd, int revents, dap_server_t *sh ) int32_t bytes = (int32_t) recvfrom( sh->socket_listener, buf, BUFSIZE, 0,(struct sockaddr *) &clientaddr, &clientlen ); - dap_client_remote_t *client = dap_udp_client_find( sh, clientaddr.sin_addr.s_addr, clientaddr.sin_port ); + dap_events_socket_t *client = dap_udp_client_find( sh, clientaddr.sin_addr.s_addr, clientaddr.sin_port ); if( client != NULL && check_close(client) != 0 ) return; @@ -304,8 +305,8 @@ static void read_cb( EPOLL_HANDLE efd, int revents, dap_server_t *sh ) memcpy( client->buf_in + client->buf_in_size,buf + bytes_processed, bytes_to_transfer ); client->buf_in_size += bytes_to_transfer; - if ( sh->client_read_callback ) - sh->client_read_callback( client, NULL ); + if ( sh->client_callbacks.read_callback ) + sh->client_callbacks.read_callback( client, NULL ); bytes_processed += bytes_to_transfer; bytes_recieved -= bytes_to_transfer; diff --git a/dap-sdk/net/server-udp/include/dap_udp_client.h b/dap-sdk/net/server-udp/include/dap_udp_client.h index 7fc66f14585e359c482b97c201a7fb6bb5beb1ad..f1b3844f5123cae65beb051171dc62c9211e7a1a 100644 --- a/dap-sdk/net/server-udp/include/dap_udp_client.h +++ b/dap-sdk/net/server-udp/include/dap_udp_client.h @@ -27,10 +27,10 @@ #include <sys/queue.h> #endif +#include "dap_events_socket.h" +#include "dap_server.h" #include "uthash.h" -#include "dap_client_remote.h" - typedef struct dap_udp_server dap_udp_server_t; struct dap_udp_client; @@ -38,7 +38,7 @@ struct dap_udp_client; typedef struct dap_udp_client { - dap_client_remote_t *client; + dap_events_socket_t *esocket; uint64_t host_key; //key contains host address in first 4 bytes and port in last 4 bytes UT_hash_handle hh; @@ -52,15 +52,15 @@ typedef struct dap_udp_client { #define DAP_UDP_CLIENT(a) ((dap_udp_client_t *) (a)->_inheritor) -dap_client_remote_t *dap_udp_client_create( dap_server_t *sh, EPOLL_HANDLE efd, unsigned long host, unsigned short port ); // Create new client and add it to the list -dap_client_remote_t *dap_udp_client_find( dap_server_t *sh, unsigned long host, unsigned short port ); // Find client by host and port +dap_events_socket_t *dap_udp_client_create( dap_server_t *sh, EPOLL_HANDLE efd, unsigned long host, unsigned short port ); // Create new client and add it to the list +dap_events_socket_t *dap_udp_client_find( dap_server_t *sh, unsigned long host, unsigned short port ); // Find client by host and port -void dap_udp_client_ready_to_read( dap_client_remote_t *sc, bool is_ready ); -void dap_udp_client_ready_to_write( dap_client_remote_t *sc, bool is_ready ); +void dap_udp_client_ready_to_read( dap_events_socket_t *sc, bool is_ready ); +void dap_udp_client_ready_to_write( dap_events_socket_t *sc, bool is_ready ); -size_t dap_udp_client_write( dap_client_remote_t *sc, const void * data, size_t data_size ); -size_t dap_udp_client_write_f( dap_client_remote_t *a_client, const char * a_format, ... ); +size_t dap_udp_client_write_unsafe( dap_events_socket_t *sc, const void * data, size_t data_size ); +size_t dap_udp_client_write_f( dap_events_socket_t *a_client, const char * a_format, ... ); -void add_waiting_client( dap_client_remote_t *client ); // Add client to writing queue +void add_waiting_client( dap_events_socket_t *client ); // Add client to writing queue -void dap_udp_client_get_address( dap_client_remote_t *client, unsigned int *host, unsigned short *port ); +void dap_udp_client_get_address( dap_events_socket_t *client, unsigned int *host, unsigned short *port ); diff --git a/dap-sdk/net/server-udp/include/dap_udp_server.h b/dap-sdk/net/server-udp/include/dap_udp_server.h index 2ed9465c012118bf5f4edd3761ae1b92f58fa39a..f1725b4d141d6c6704d00d9f3eab397913a48593 100644 --- a/dap-sdk/net/server-udp/include/dap_udp_server.h +++ b/dap-sdk/net/server-udp/include/dap_udp_server.h @@ -36,7 +36,6 @@ #include "dap_udp_client.h" #include "dap_server.h" -#include "dap_client_remote.h" struct dap_udp_server; diff --git a/dap-sdk/net/server/http_server/dap_http.c b/dap-sdk/net/server/http_server/dap_http.c index 51fe57a57e4b8fbc14e776666dd1ffe1012d2d10..5246f0b5fe7183cd6aadc618fff7cd7cf89cd82a 100644 --- a/dap-sdk/net/server/http_server/dap_http.c +++ b/dap-sdk/net/server/http_server/dap_http.c @@ -47,7 +47,7 @@ #include "dap_common.h" #include "dap_server.h" -#include "dap_client_remote.h" +#include "dap_events_socket.h" #include "dap_http.h" #include "dap_http_header.h" #include "dap_http_client.h" @@ -99,11 +99,11 @@ int dap_http_new( dap_server_t *sh, const char * server_name ) shttp->server = sh; strncpy( shttp->server_name, server_name, sizeof(shttp->server_name)-1 ); - sh->client_new_callback = dap_http_client_new; - sh->client_delete_callback = dap_http_client_delete; - sh->client_read_callback = dap_http_client_read; - sh->client_write_callback = dap_http_client_write; - sh->client_error_callback = dap_http_client_error; + sh->client_callbacks.new_callback = dap_http_client_new; + sh->client_callbacks.delete_callback = dap_http_client_delete; + sh->client_callbacks.read_callback = dap_http_client_read; + sh->client_callbacks.write_callback = dap_http_client_write; + sh->client_callbacks.error_callback = dap_http_client_error; return 0; } diff --git a/dap-sdk/net/server/http_server/dap_http_folder.c b/dap-sdk/net/server/http_server/dap_http_folder.c index e3a34342983862540e54aca62b83964213ed4933..fc293a487ca87be1c6564ed24fce89f308494c11 100644 --- a/dap-sdk/net/server/http_server/dap_http_folder.c +++ b/dap-sdk/net/server/http_server/dap_http_folder.c @@ -1,23 +1,25 @@ /* - Copyright (c) 2017-2018 (c) Project "DeM Labs Inc" https://github.com/demlabsinc - All rights reserved. + * Authors: + * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net> + * DeM Labs Ltd. https://demlabs.net + * Copyright (c) 2017 + * All rights reserved. - This file is part of DAP (Deus Applications Prototypes) the open source project + This file is part of DAP SDK the open source project - DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by + DAP SDK is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - DAP is distributed in the hope that it will be useful, + DAP SDK is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. + GNU General Public License for more details. - You should have received a copy of the GNU Lesser General Public License - along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. + You should have received a copy of the GNU General Public License + along with any DAP SDK based project. If not, see <http://www.gnu.org/licenses/>. */ - #include <stdio.h> #include <unistd.h> #include <dirent.h> @@ -38,7 +40,7 @@ #include <magic.h> #include "dap_common.h" -#include "dap_client_remote.h" +#include "dap_events_socket.h" #include "dap_http.h" #include "dap_http_client.h" #include "dap_http_folder.h" @@ -160,8 +162,9 @@ void dap_http_folder_headers_read(dap_http_client_t * cl_ht, void * arg) (void) arg; cl_ht->state_write=DAP_HTTP_CLIENT_STATE_START; cl_ht->state_read=cl_ht->keep_alive?DAP_HTTP_CLIENT_STATE_START:DAP_HTTP_CLIENT_STATE_NONE; - dap_client_remote_ready_to_write(cl_ht->client,true); - dap_client_remote_ready_to_read(cl_ht->client, cl_ht->keep_alive); + + dap_events_socket_set_writable_unsafe(cl_ht->esocket,true); + dap_events_socket_set_readable_unsafe(cl_ht->esocket, cl_ht->keep_alive); } #ifdef _WIN32 @@ -255,7 +258,7 @@ void dap_http_folder_headers_write( dap_http_client_t *cl_ht, void * arg) } else { cl_ht->reply_status_code=Http_Status_NotFound; - cl_ht->client->flags |= DAP_SOCK_SIGNAL_CLOSE; + cl_ht->esocket->flags |= DAP_SOCK_SIGNAL_CLOSE; log_it(L_WARNING,"Can't detect MIME type of %s file: %s",cl_ht_file->local_path,magic_error(up_folder->mime_detector)); } } @@ -280,7 +283,7 @@ void dap_http_folder_data_read(dap_http_client_t * cl_ht, void * arg) { int * bytes_return = (int*) arg; // Return number of read bytes //Do nothing - *bytes_return=cl_ht->client->buf_in_size; + *bytes_return=cl_ht->esocket->buf_in_size; } /** @@ -292,17 +295,17 @@ void dap_http_folder_data_write(dap_http_client_t * cl_ht, void * arg) { (void) arg; dap_http_file_t * cl_ht_file= DAP_HTTP_FILE(cl_ht); - cl_ht->client->buf_out_size=fread(cl_ht->client->buf_out,1,sizeof(cl_ht->client->buf_out),cl_ht_file->fd); - cl_ht_file->position+=cl_ht->client->buf_out_size; + cl_ht->esocket->buf_out_size=fread(cl_ht->esocket->buf_out,1,sizeof(cl_ht->esocket->buf_out),cl_ht_file->fd); + cl_ht_file->position+=cl_ht->esocket->buf_out_size; if(feof(cl_ht_file->fd)!=0){ log_it(L_INFO, "All the file %s is sent out",cl_ht_file->local_path); //strncat(cl_ht->client->buf_out+cl_ht->client->buf_out_size,"\r\n",sizeof(cl_ht->client->buf_out)); fclose(cl_ht_file->fd); - dap_client_remote_ready_to_write(cl_ht->client,false); + dap_events_socket_set_writable_unsafe(cl_ht->esocket,false); if ( !cl_ht->keep_alive ) - cl_ht->client->flags |= DAP_SOCK_SIGNAL_CLOSE; + cl_ht->esocket->flags |= DAP_SOCK_SIGNAL_CLOSE; cl_ht->state_write=DAP_HTTP_CLIENT_STATE_NONE; } diff --git a/dap-sdk/net/server/http_server/dap_http_simple.c b/dap-sdk/net/server/http_server/dap_http_simple.c index b8beddd0981899b1c3e943d9ac55d9ef681a22a5..2f96ea9d69b9947230b203ca1e71ae45db0b27d4 100644 --- a/dap-sdk/net/server/http_server/dap_http_simple.c +++ b/dap-sdk/net/server/http_server/dap_http_simple.c @@ -60,8 +60,8 @@ See more details here <http://www.gnu.org/licenses/>. #define LOG_TAG "dap_http_simple" static void s_headers_read( dap_http_client_t *cl_ht, void *arg ); -static void s_data_write( dap_http_client_t *a_http_client, void *a_arg ); -static void s_data_read( dap_http_client_t * cl_ht, void *arg ); +static void s_http_client_data_write( dap_http_client_t *a_http_client, void *a_arg ); +static void s_es_read( dap_http_client_t * cl_ht, void *arg ); void *dap_http_simple_proc( dap_http_simple_t * cl_sh ); static void *loop_http_simple_proc( void *arg ); @@ -168,7 +168,7 @@ static void *loop_http_simple_proc( void *arg ) for ( uint32_t i = 0; i < s_requestsproc_count; ++ i ) { dap_http_simple_proc( s_requestsproc[i] ); - s_requestsproc[i]->http->client->no_close = false; + s_requestsproc[i]->http->esocket->no_close = false; // free( s_requestsproc[i] ); // ??? } } @@ -205,7 +205,7 @@ void dap_http_simple_proc_add( dap_http_t *a_http, const char *a_url_path, size_ NULL, // Contrustor NULL, // Destructor s_headers_read, NULL, // Headers read, write - s_data_read, s_data_write, // Data read, write + s_es_read, s_http_client_data_write, // Data read, write NULL); // errror } @@ -307,11 +307,11 @@ inline static void _set_only_write_http_client_state(dap_http_client_t* http_cli // log_it(L_DEBUG,"_set_only_write_http_client_state"); // Sleep(300); - dap_client_remote_ready_to_read(http_client->client,false); + dap_events_socket_set_readable_unsafe(http_client->esocket,false); // http_client->state_write=DAP_HTTP_CLIENT_STATE_NONE; http_client->state_write=DAP_HTTP_CLIENT_STATE_START; - dap_client_remote_ready_to_write(http_client->client,true); + dap_events_socket_set_writable_unsafe(http_client->esocket,true); // http_client->state_write=DAP_HTTP_CLIENT_STATE_START; } @@ -429,7 +429,7 @@ static void s_headers_read( dap_http_client_t *a_http_client, void *a_arg ) } } -void s_data_read( dap_http_client_t *a_http_client, void * a_arg ) +void s_es_read( dap_http_client_t *a_http_client, void * a_arg ) { int *ret = (int *)a_arg; @@ -438,8 +438,8 @@ void s_data_read( dap_http_client_t *a_http_client, void * a_arg ) dap_http_simple_t *l_http_simple = DAP_HTTP_SIMPLE(a_http_client); - size_t bytes_to_read = (a_http_client->client->buf_in_size + l_http_simple->request_size) < a_http_client->in_content_length ? - a_http_client->client->buf_in_size : ( a_http_client->in_content_length - l_http_simple->request_size ); + size_t bytes_to_read = (a_http_client->esocket->buf_in_size + l_http_simple->request_size) < a_http_client->in_content_length ? + a_http_client->esocket->buf_in_size : ( a_http_client->in_content_length - l_http_simple->request_size ); if( bytes_to_read ) { // Oops! The client sent more data than write in the CONTENT_LENGTH header @@ -450,7 +450,7 @@ void s_data_read( dap_http_client_t *a_http_client, void * a_arg ) l_http_simple->request = DAP_REALLOC(l_http_simple->request, l_http_simple->request_size_max); } if(l_http_simple->request){// request_byte=request - memcpy( l_http_simple->request_byte + l_http_simple->request_size, a_http_client->client->buf_in, bytes_to_read ); + memcpy( l_http_simple->request_byte + l_http_simple->request_size, a_http_client->esocket->buf_in, bytes_to_read ); l_http_simple->request_size += bytes_to_read; } } @@ -462,7 +462,7 @@ void s_data_read( dap_http_client_t *a_http_client, void * a_arg ) queue_http_request_put( l_http_simple ); } - *ret = (int) a_http_client->client->buf_in_size; + *ret = (int) a_http_client->esocket->buf_in_size; } @@ -471,7 +471,7 @@ void s_data_read( dap_http_client_t *a_http_client, void * a_arg ) * @param a_http_client * @param a_arg */ -static void s_data_write( dap_http_client_t *a_http_client, void *a_arg ) +static void s_http_client_data_write( dap_http_client_t *a_http_client, void *a_arg ) { (void) a_arg; dap_http_simple_t *cl_st = DAP_HTTP_SIMPLE( a_http_client ); @@ -481,20 +481,20 @@ static void s_data_write( dap_http_client_t *a_http_client, void *a_arg ) if ( !cl_st->reply ) { - a_http_client->client->flags |= DAP_SOCK_SIGNAL_CLOSE; + a_http_client->esocket->flags |= DAP_SOCK_SIGNAL_CLOSE; log_it( L_WARNING, "No reply to write, close connection" ); return; } - cl_st->reply_sent += dap_client_remote_write( a_http_client->client, + cl_st->reply_sent += dap_events_socket_write_unsafe( a_http_client->esocket, cl_st->reply_byte + cl_st->reply_sent, a_http_client->out_content_length - cl_st->reply_sent ); if ( cl_st->reply_sent >= a_http_client->out_content_length ) { log_it(L_INFO, "All the reply (%u) is sent out", a_http_client->out_content_length ); //cl_ht->client->signal_close=cl_ht->keep_alive; - a_http_client->client->flags |= DAP_SOCK_SIGNAL_CLOSE; + a_http_client->esocket->flags |= DAP_SOCK_SIGNAL_CLOSE; //dap_client_ready_to_write(cl_ht->client,false); } @@ -554,7 +554,7 @@ inline void queue_http_request_put( dap_http_simple_t *cl_sh ) log_it( L_WARNING, "queue_http_request_put >>> %u", s_requests_count ); s_requests[ s_requests_count ++ ] = cl_sh; - cl_sh->http->client->no_close = true; + cl_sh->http->esocket->no_close = true; pthread_mutex_unlock( &mutex_on_queue_http_response ); } diff --git a/dap-sdk/net/server/http_server/http_client/dap_http_client.c b/dap-sdk/net/server/http_server/http_client/dap_http_client.c index 81cdd8cdfec2f2f98f544a7a50858864cb902ec2..3c48146fd00eb1a16adac0a5623f3b119c3ac6c1 100644 --- a/dap-sdk/net/server/http_server/http_client/dap_http_client.c +++ b/dap-sdk/net/server/http_server/http_client/dap_http_client.c @@ -36,7 +36,7 @@ #include <pthread.h> #include "dap_common.h" -#include "dap_client_remote.h" +#include "dap_events_socket.h" #include "dap_http.h" #include "http_status_code.h" @@ -44,11 +44,7 @@ #include "dap_http_header.h" #include "dap_http_client.h" -#define LOG_TAG "http_client" - -//#define BUF_SIZE 2048 - -void dap_http_client_out_header_generate( dap_http_client_t *cl_ht ); +#define LOG_TAG "dap_http_client" /** * @brief dap_http_client_init Init HTTP client module @@ -73,7 +69,7 @@ void dap_http_client_deinit( ) * @param cl HTTP Client instance * @param arg Additional argument (usualy not used) */ -void dap_http_client_new( dap_client_remote_t *cl, void *arg ) +void dap_http_client_new( dap_events_socket_t *cl, void *arg ) { (void) arg; @@ -82,7 +78,7 @@ void dap_http_client_new( dap_client_remote_t *cl, void *arg ) cl->_inheritor = DAP_NEW_Z( dap_http_client_t ); dap_http_client_t *cl_ht = DAP_HTTP_CLIENT( cl ); - cl_ht->client = cl; + cl_ht->esocket = cl; cl_ht->http = DAP_HTTP( cl->server ); cl_ht->state_read = DAP_HTTP_CLIENT_STATE_START; cl_ht->state_write = DAP_HTTP_CLIENT_STATE_NONE; @@ -95,7 +91,7 @@ void dap_http_client_new( dap_client_remote_t *cl, void *arg ) * @param cl HTTP Client instance * @param arg Additional argument (usualy not used) */ -void dap_http_client_delete( dap_client_remote_t * cl, void *arg ) +void dap_http_client_delete( dap_events_socket_t * cl, void *arg ) { dap_http_client_t *cl_ht = DAP_HTTP_CLIENT( cl ); @@ -212,6 +208,13 @@ int32_t z_rootdirname( char *path, uint32_t len ) return len2; } +/** + * @brief dap_http_request_line_parse + * @param cl_ht + * @param buf + * @param buf_length + * @return + */ bool dap_http_request_line_parse( dap_http_client_t *cl_ht, char *buf, size_t buf_length ) { size_t pos; @@ -293,13 +296,18 @@ bool dap_http_request_line_parse( dap_http_client_t *cl_ht, char *buf, size_t bu return cl_ht->url_path[0] && cl_ht->action[0]; } -static inline void ReportErrorAndRestart( dap_client_remote_t *cl, dap_http_client_t *cl_ht ) +/** + * @brief s_report_error_and_restart + * @param cl + * @param cl_ht + */ +static inline void s_report_error_and_restart( dap_events_socket_t *cl, dap_http_client_t *cl_ht ) { cl->buf_in_size = 0; cl_ht->state_read = DAP_HTTP_CLIENT_STATE_NONE; - dap_client_remote_ready_to_read( cl_ht->client, false ); - dap_client_remote_ready_to_write( cl_ht->client, true ); + dap_events_socket_set_readable_unsafe( cl_ht->esocket, false ); + dap_events_socket_set_writable_unsafe( cl_ht->esocket, true ); cl_ht->reply_status_code = 505; strcpy( cl_ht->reply_reason_phrase, "Error" ); @@ -313,209 +321,207 @@ static inline void ReportErrorAndRestart( dap_client_remote_t *cl, dap_http_clie * @param cl HTTP Client instance * @param arg Additional argument (usualy not used) */ -void dap_http_client_read( dap_client_remote_t *cl, void *arg ) +void dap_http_client_read( dap_events_socket_t *cl, void *arg ) { char buf_line[4096] = {'\0'}; - dap_http_client_t *cl_ht = DAP_HTTP_CLIENT( cl ); + dap_http_client_t *cl_ht = DAP_HTTP_CLIENT( cl ); // log_it( L_DEBUG, "dap_http_client_read..." ); //log_it( L_DEBUG, "HTTP client in state read %d taked bytes in input %lu", cl_ht->state_read, cl->buf_in_size ); - do { - switch( cl_ht->state_read ) { + do { + switch( cl_ht->state_read ) { + case DAP_HTTP_CLIENT_STATE_START: { // Beginning of the session. We try to detect + char *peol; + uint32_t eol; - case DAP_HTTP_CLIENT_STATE_START: { // Beginning of the session. We try to detect + if (!(peol = (char*)memchr(cl->buf_in, 10, cl->buf_in_size))) { /// search LF + peol = (char*)memchr(cl->buf_in, 13, cl->buf_in_size); + } - char *peol; - uint32_t eol; + if (peol) { + eol = peol - cl->buf_in_str; + if (eol <= 0) { + eol = cl->buf_in_size - 2; + } + } else { + log_it( L_WARNING, "Single-line, possibly trash, input detected"); + eol = cl->buf_in_size - 2; + } - if (!(peol = (char*)memchr(cl->buf_in, 10, cl->buf_in_size))) { /// search LF - peol = (char*)memchr(cl->buf_in, 13, cl->buf_in_size); - } + if ( eol + 3 >= sizeof(buf_line) ) { + log_it( L_WARNING,"Too big line in request, more than %llu symbols - thats very strange", sizeof(buf_line) - 3 ); + s_report_error_and_restart( cl, cl_ht ); + break; + } - if (peol) { - eol = peol - cl->buf_in; - if (eol <= 0) { - eol = cl->buf_in_size - 2; - } - } else { - log_it( L_WARNING, "Single-line, possibly trash, input detected"); - eol = cl->buf_in_size - 2; - } + memcpy( buf_line, cl->buf_in, eol + 1 ); // copy with LF - if ( eol + 3 >= sizeof(buf_line) ) { - log_it( L_WARNING,"Too big line in request, more than %llu symbols - thats very strange", sizeof(buf_line) - 3 ); - ReportErrorAndRestart( cl, cl_ht ); - break; - } + dap_events_socket_shrink_buf_in( cl, eol + 1 ); + buf_line[ eol + 2 ] = 0; // null terminate - memcpy( buf_line, cl->buf_in, eol + 1 ); // copy with LF + // parse http_request_line + if ( !dap_http_request_line_parse(cl_ht, buf_line, eol + 1) ) { - dap_client_remote_shrink_buf_in( cl, eol + 1 ); - buf_line[ eol + 2 ] = 0; // null terminate + log_it( L_WARNING, "Input: Wrong request line '%s'", buf_line ); + s_report_error_and_restart( cl, cl_ht ); + break; + } - // parse http_request_line - if ( !dap_http_request_line_parse(cl_ht, buf_line, eol + 1) ) { + // uint32_t action_len; + // uint32_t url_path_len; - log_it( L_WARNING, "Input: Wrong request line '%s'", buf_line ); - ReportErrorAndRestart( cl, cl_ht ); - break; - } + char *query_string; -// uint32_t action_len; -// uint32_t url_path_len; + if( (query_string = strchr(cl_ht->url_path, '?')) != NULL ) { - char *query_string; + size_t len_after = strlen( query_string + 1 ); - if( (query_string = strchr(cl_ht->url_path, '?')) != NULL ) { + if ( len_after ) { + if( len_after > (sizeof(cl_ht->in_query_string) - 1) ) + len_after = sizeof(cl_ht->in_query_string) - 1; - size_t len_after = strlen( query_string + 1 ); + if ( strstr(query_string, "HTTP/1.1") ) + strncpy( cl_ht->in_query_string, query_string + 1, len_after - 11 ); + else + strncpy( cl_ht->in_query_string,query_string + 1, len_after ); - if ( len_after ) { - if( len_after > (sizeof(cl_ht->in_query_string) - 1) ) - len_after = sizeof(cl_ht->in_query_string) - 1; - - if ( strstr(query_string, "HTTP/1.1") ) - strncpy( cl_ht->in_query_string, query_string + 1, len_after - 11 ); - else - strncpy( cl_ht->in_query_string,query_string + 1, len_after ); + if ( cl_ht->in_query_string[strlen(cl_ht->in_query_string) - 1] == ' ' ) + cl_ht->in_query_string[strlen(cl_ht->in_query_string) - 1] = 0; - if ( cl_ht->in_query_string[strlen(cl_ht->in_query_string) - 1] == ' ' ) - cl_ht->in_query_string[strlen(cl_ht->in_query_string) - 1] = 0; + query_string[0] = 0; + } + } - query_string[0] = 0; - } - } + log_it( L_WARNING, "Input: %s request for %s document (query string '%s')", cl_ht->action, cl_ht->url_path, cl_ht->in_query_string[0] ? cl_ht->in_query_string : "" ); - log_it( L_WARNING, "Input: %s request for %s document (query string '%s')", cl_ht->action, cl_ht->url_path, cl_ht->in_query_string ? cl_ht->in_query_string : "" ); + dap_http_url_proc_t *url_proc; + int32_t tpos = z_dirname( cl_ht->url_path, 0 ); + log_it( L_WARNING, "cl_ht->url_path(dir) = %s", cl_ht->url_path ); - dap_http_url_proc_t *url_proc; - int32_t tpos = z_dirname( cl_ht->url_path, 0 ); - log_it( L_WARNING, "cl_ht->url_path(dir) = %s", cl_ht->url_path ); + HASH_FIND_STR( cl_ht->http->url_proc, cl_ht->url_path, url_proc ); // Find URL processor - HASH_FIND_STR( cl_ht->http->url_proc, cl_ht->url_path, url_proc ); // Find URL processor + cl_ht->proc = url_proc; - cl_ht->proc = url_proc; + if ( tpos ) + cl_ht->url_path[ tpos ] = '/'; - if ( tpos ) - cl_ht->url_path[ tpos ] = '/'; + char *ptr = z_basename( cl_ht->url_path, 0 ); + log_it( L_WARNING, "basename = %s", ptr ); - char *ptr = z_basename( cl_ht->url_path, 0 ); - log_it( L_WARNING, "basename = %s", ptr ); + // log_it( L_WARNING, "cl_ht->client->socket = %u efd %u", cl_ht->client->socket, cl_ht->client->efd ); -// log_it( L_WARNING, "cl_ht->client->socket = %u efd %u", cl_ht->client->socket, cl_ht->client->efd ); + memmove( cl_ht->url_path, ptr, strlen(ptr) + 1 ); - memmove( cl_ht->url_path, ptr, strlen(ptr) + 1 ); + log_it( L_WARNING, "cl_ht->url_path = %s", cl_ht->url_path ); - log_it( L_WARNING, "cl_ht->url_path = %s", cl_ht->url_path ); + if ( url_proc ) { + cl_ht->state_read = DAP_HTTP_CLIENT_STATE_HEADERS; + } + else { + log_it( L_WARNING, "Input: unprocessed URL request %s is rejected", cl_ht->url_path ); + s_report_error_and_restart( cl, cl_ht ); + break; + } - if ( url_proc ) { - cl_ht->state_read = DAP_HTTP_CLIENT_STATE_HEADERS; - } - else { - log_it( L_WARNING, "Input: unprocessed URL request %s is rejected", cl_ht->url_path ); - ReportErrorAndRestart( cl, cl_ht ); - break; - } + } + break; - } - break; + case DAP_HTTP_CLIENT_STATE_HEADERS: { // Parse input headers - case DAP_HTTP_CLIENT_STATE_HEADERS: { // Parse input headers + // log_it( L_WARNING, "DAP_HTTP_CLIENT_STATE_HEADERS" ); + char *peol; + uint32_t eol; -// log_it( L_WARNING, "DAP_HTTP_CLIENT_STATE_HEADERS" ); - char *peol; - uint32_t eol; + if ( !(peol = (char *)memchr(cl->buf_in, 10, cl->buf_in_size)) ) { /// search LF + log_it( L_WARNING, "DAP_HTTP_CLIENT_STATE_HEADERS: no LF" ); + s_report_error_and_restart( cl, cl_ht ); + break; + } - if ( !(peol = (char *)memchr(cl->buf_in, 10, cl->buf_in_size)) ) { /// search LF - log_it( L_WARNING, "DAP_HTTP_CLIENT_STATE_HEADERS: no LF" ); - ReportErrorAndRestart( cl, cl_ht ); - break; - } + eol = peol - cl->buf_in_str; - eol = peol - cl->buf_in; + // int eol = detect_end_of_line( cl->buf_in, cl->buf_in_size ); -// int eol = detect_end_of_line( cl->buf_in, cl->buf_in_size ); + // if ( eol < 0 ) { + // log_it( L_WARNING, "DAP_HTTP_CLIENT_STATE_HEADERS: no LF" ); + // return; + // } -// if ( eol < 0 ) { -// log_it( L_WARNING, "DAP_HTTP_CLIENT_STATE_HEADERS: no LF" ); -// return; -// } + int parse_ret; + memcpy( buf_line, cl->buf_in, eol + 1 ); + buf_line[eol-1] = 0; - int parse_ret; - memcpy( buf_line, cl->buf_in, eol + 1 ); - buf_line[eol-1] = 0; + parse_ret = dap_http_header_parse( cl_ht, buf_line ); - parse_ret = dap_http_header_parse( cl_ht, buf_line ); + // log_it( L_WARNING, "cl_ht->client->socket = %u efd %u", cl_ht->client->socket, cl_ht->client->efd ); -// log_it( L_WARNING, "cl_ht->client->socket = %u efd %u", cl_ht->client->socket, cl_ht->client->efd ); + // log_it(L_WARNINGNG, "++ ALL HEADERS TO PARSE [%s]", buf_line); + if( parse_ret < 0 ) + log_it( L_WARNING, "Input: not a valid header '%s'", buf_line ); - // log_it(L_WARNINGNG, "++ ALL HEADERS TO PARSE [%s]", buf_line); - if( parse_ret < 0 ) - log_it( L_WARNING, "Input: not a valid header '%s'", buf_line ); + else if ( parse_ret == 1 ) { - else if ( parse_ret == 1 ) { + log_it( L_INFO, "Input: HTTP headers are over" ); - log_it( L_INFO, "Input: HTTP headers are over" ); + if ( cl_ht->proc->access_callback ) { - if ( cl_ht->proc->access_callback ) { + // log_it( L_WARNING, "access_callback" ); -// log_it( L_WARNING, "access_callback" ); + bool isOk = true; + cl_ht->proc->access_callback( cl_ht, &isOk ); + if ( !isOk ) { + log_it( L_NOTICE, "Access restricted" ); + s_report_error_and_restart( cl, cl_ht ); + } + } - bool isOk = true; - cl_ht->proc->access_callback( cl_ht, &isOk ); - if ( !isOk ) { - log_it( L_NOTICE, "Access restricted" ); - ReportErrorAndRestart( cl, cl_ht ); - } - } + if ( cl_ht->proc->headers_read_callback ) { + log_it( L_WARNING, "headers_read_callback" ); + cl_ht->proc->headers_read_callback( cl_ht, NULL ); + } - if ( cl_ht->proc->headers_read_callback ) { - log_it( L_WARNING, "headers_read_callback" ); - cl_ht->proc->headers_read_callback( cl_ht, NULL ); - } + // If no headers callback we go to the DATA processing + if( cl_ht->in_content_length ) { + log_it( L_WARNING, "headers -> DAP_HTTP_CLIENT_STATE_DATA" ); + cl_ht->state_read = DAP_HTTP_CLIENT_STATE_DATA; + } + else { + //log_it + //cl_ht->state_read=DAP_HTTP_CLIENT_STATE_NONE; + //cl_ht->client->ready_to_read=t; + //cl_ht->client->signal_close=!cl_ht->keep_alive; + } + } // parse_ret == 1 - // If no headers callback we go to the DATA processing - if( cl_ht->in_content_length ) { - log_it( L_WARNING, "headers -> DAP_HTTP_CLIENT_STATE_DATA" ); - cl_ht->state_read = DAP_HTTP_CLIENT_STATE_DATA; - } - else { - //log_it - //cl_ht->state_read=DAP_HTTP_CLIENT_STATE_NONE; - //cl_ht->client->ready_to_read=t; - //cl_ht->client->signal_close=!cl_ht->keep_alive; - } - } // parse_ret == 1 + dap_events_socket_shrink_buf_in( cl, eol + 1 ); + } + break; - dap_client_remote_shrink_buf_in( cl, eol + 1 ); - } - break; + case DAP_HTTP_CLIENT_STATE_DATA: + { + // log_it(L_WARNINGNG, "DBG_#002 [%s] [%s]", cl_ht->in_query_string, cl_ht->url_path); - case DAP_HTTP_CLIENT_STATE_DATA: - { - // log_it(L_WARNINGNG, "DBG_#002 [%s] [%s]", cl_ht->in_query_string, cl_ht->url_path); - - size_t read_bytes = 0; - if ( cl_ht->proc->data_read_callback ) { -// log_it( L_WARNING, "cl_ht->proc->data_read_callback()" ); - - //while(cl_ht->client->buf_in_size){ - cl_ht->proc->data_read_callback( cl_ht, &read_bytes ); - dap_client_remote_shrink_buf_in( cl, read_bytes ); - //} - } - else { - log_it( L_WARNING, "data_read callback is NULL in DAP_HTTP_CLIENT_STATE_DATA" ); - cl->buf_in_size = 0; - } - } - break; + size_t read_bytes = 0; + if ( cl_ht->proc->data_read_callback ) { + // log_it( L_WARNING, "cl_ht->proc->data_read_callback()" ); - case DAP_HTTP_CLIENT_STATE_NONE: { - cl->buf_in_size = 0; - } - break; + //while(cl_ht->client->buf_in_size){ + cl_ht->proc->data_read_callback( cl_ht, &read_bytes ); + dap_events_socket_shrink_buf_in( cl, read_bytes ); + //} + } + else { + log_it( L_WARNING, "data_read callback is NULL in DAP_HTTP_CLIENT_STATE_DATA" ); + cl->buf_in_size = 0; + } + } + break; + + case DAP_HTTP_CLIENT_STATE_NONE: { + cl->buf_in_size = 0; + } + break; } // switch @@ -530,58 +536,51 @@ void dap_http_client_read( dap_client_remote_t *cl, void *arg ) * @param cl HTTP Client instance * @param arg Additional argument (usualy not used) */ -void dap_http_client_write( dap_client_remote_t * cl, void *arg ) +void dap_http_client_write( dap_events_socket_t * cl, void *arg ) { -// log_it( L_DEBUG, "dap_http_client_write..." ); - - (void) arg; - dap_http_client_t *cl_ht = DAP_HTTP_CLIENT( cl ); - - // log_it(L_WARNING,"HTTP client write callback in state %d",cl_ht->state_write); - - switch( cl_ht->state_write ) { - case DAP_HTTP_CLIENT_STATE_NONE: - return; - case DAP_HTTP_CLIENT_STATE_START: - { - if ( cl_ht->proc ) - if ( cl_ht->proc->headers_write_callback ) - cl_ht->proc->headers_write_callback( cl_ht, NULL ); - - log_it( L_DEBUG,"Output: HTTP response with %u status code", cl_ht->reply_status_code ); - - dap_client_remote_write_f( cl,"HTTP/1.1 %u %s\r\n",cl_ht->reply_status_code, cl_ht->reply_reason_phrase[0] ? - cl_ht->reply_reason_phrase : http_status_reason_phrase(cl_ht->reply_status_code) ); - - dap_http_client_out_header_generate( cl_ht ); - cl_ht->state_write = DAP_HTTP_CLIENT_STATE_HEADERS; - } - break; - - case DAP_HTTP_CLIENT_STATE_HEADERS: - { - dap_http_header_t *hdr = cl_ht->out_headers; - if ( hdr == NULL ) { - log_it(L_DEBUG, "Output: headers are over (reply status code %u)",cl_ht->reply_status_code); - dap_client_remote_write_f( cl,"\r\n" ); - if ( cl_ht->out_content_length || cl_ht->out_content_ready ) { - cl_ht->state_write=DAP_HTTP_CLIENT_STATE_DATA; - } - else { - log_it( L_DEBUG, "Nothing to output" ); - cl_ht->state_write = DAP_HTTP_CLIENT_STATE_NONE; - dap_client_remote_ready_to_write( cl, false ); - cl->flags |= DAP_SOCK_SIGNAL_CLOSE; - } - dap_client_remote_ready_to_read( cl, true ); - } - else { - //log_it(L_WARNING,"Output: header %s: %s",hdr->name,hdr->value); - dap_client_remote_write_f( cl, "%s: %s\r\n", hdr->name,hdr->value ); - dap_http_header_remove( &cl_ht->out_headers, hdr ); - } - } - break; + // log_it( L_DEBUG, "dap_http_client_write..." ); + + (void) arg; + dap_http_client_t *cl_ht = DAP_HTTP_CLIENT( cl ); + + // log_it(L_WARNING,"HTTP client write callback in state %d",cl_ht->state_write); + + switch( cl_ht->state_write ) { + case DAP_HTTP_CLIENT_STATE_NONE: + return; + case DAP_HTTP_CLIENT_STATE_START:{ + if ( cl_ht->proc ) + if ( cl_ht->proc->headers_write_callback ) + cl_ht->proc->headers_write_callback( cl_ht, NULL ); + + log_it( L_INFO," HTTP response with %u status code", cl_ht->reply_status_code ); + dap_events_socket_write_f_unsafe( cl,"HTTP/1.1 %u %s\r\n",cl_ht->reply_status_code, cl_ht->reply_reason_phrase[0] ? + cl_ht->reply_reason_phrase : http_status_reason_phrase(cl_ht->reply_status_code) ); + + dap_http_client_out_header_generate( cl_ht ); + cl_ht->state_write = DAP_HTTP_CLIENT_STATE_HEADERS; + } break; + + case DAP_HTTP_CLIENT_STATE_HEADERS: { + dap_http_header_t *hdr = cl_ht->out_headers; + if ( hdr == NULL ) { + log_it(L_DEBUG, "Output: headers are over (reply status code %u)",cl_ht->reply_status_code); + dap_events_socket_write_f_unsafe( cl,"\r\n" ); + if ( cl_ht->out_content_length || cl_ht->out_content_ready ) { + cl_ht->state_write=DAP_HTTP_CLIENT_STATE_DATA; + } else { + log_it( L_DEBUG, "Nothing to output" ); + cl_ht->state_write = DAP_HTTP_CLIENT_STATE_NONE; + dap_events_socket_set_writable_unsafe( cl, false ); + cl->flags |= DAP_SOCK_SIGNAL_CLOSE; + } + dap_events_socket_set_readable_unsafe( cl, true ); + } else { + //log_it(L_WARNING,"Output: header %s: %s",hdr->name,hdr->value); + dap_events_socket_write_f_unsafe( cl, "%s: %s\r\n", hdr->name,hdr->value ); + dap_http_header_remove( &cl_ht->out_headers, hdr ); + } + } break; case DAP_HTTP_CLIENT_STATE_DATA: { if ( cl_ht->proc ) @@ -634,7 +633,7 @@ void dap_http_client_out_header_generate(dap_http_client_t *cl_ht) * @param cl HTTP Client instance * @param arg Additional argument (usualy not used) */ -void dap_http_client_error( struct dap_client_remote *cl, void *arg ) +void dap_http_client_error( dap_events_socket_t *cl, void *arg ) { (void) arg; diff --git a/dap-sdk/net/server/http_server/http_client/dap_http_header.c b/dap-sdk/net/server/http_server/http_client/dap_http_header.c index 68b964040fdd2a223754772ef25229ed35e461f0..e2458cadeff4b56331854ff6b474db6f4a0a7d03 100644 --- a/dap-sdk/net/server/http_server/http_client/dap_http_header.c +++ b/dap-sdk/net/server/http_server/http_client/dap_http_header.c @@ -34,7 +34,7 @@ #include <pthread.h> #include "dap_common.h" -#include "dap_client_remote.h" +#include "dap_events_socket.h" #include "dap_http_client.h" #include "dap_http_header.h" diff --git a/dap-sdk/net/server/http_server/http_client/include/dap_http_client.h b/dap-sdk/net/server/http_server/http_client/include/dap_http_client.h index f90569be39404776caee3d90c15bc566a834d1ca..f0e42c77b068588b9986951a0650923c96b54860 100644 --- a/dap-sdk/net/server/http_server/http_client/include/dap_http_client.h +++ b/dap-sdk/net/server/http_server/http_client/include/dap_http_client.h @@ -17,15 +17,11 @@ You should have received a copy of the GNU Lesser General Public License along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. */ - - -#ifndef _DAP_HTTP_CLIENT_H_ -#define _DAP_HTTP_CLIENT_H_ - +#pragma once #include <stdint.h> #include <time.h> #include <stdbool.h> -#include "dap_client_remote.h" +#include "dap_events_socket.h" struct dap_http_client; struct dap_http; @@ -66,7 +62,7 @@ typedef struct dap_http_client time_t out_last_modified; bool out_connection_close; - dap_client_remote_t *client; + dap_events_socket_t *esocket; struct dap_http * http; uint16_t reply_status_code; @@ -87,16 +83,15 @@ extern "C" { int dap_http_client_init( ); void dap_http_client_deinit( ); +void dap_http_client_new( dap_events_socket_t * cl,void *arg ); // Creates HTTP client's internal structure +void dap_http_client_delete( dap_events_socket_t * cl,void *arg ); // Free memory for HTTP client's internal structure -void dap_http_client_new( dap_client_remote_t * cl,void *arg ); // Creates HTTP client's internal structure -void dap_http_client_delete( dap_client_remote_t * cl,void *arg ); // Free memory for HTTP client's internal structure - -void dap_http_client_read( dap_client_remote_t * cl,void *arg ); // Process read event -void dap_http_client_write( dap_client_remote_t * cl,void *arg ); // Process write event -void dap_http_client_error( dap_client_remote_t * cl,void *arg ); // Process error event +void dap_http_client_read( dap_events_socket_t * cl,void *arg ); // Process read event +void dap_http_client_write( dap_events_socket_t * cl,void *arg ); // Process write event +void dap_http_client_error( dap_events_socket_t * cl,void *arg ); // Process error event +void dap_http_client_out_header_generate( dap_http_client_t *cl_ht ); #ifdef __cplusplus } #endif -#endif diff --git a/dap-sdk/net/server/http_server/include/dap_http.h b/dap-sdk/net/server/http_server/include/dap_http.h index 646811940151ee8b8d46f158e90fa6b48165d153..0dd9e5bd0e6ae227513db9a14e3e77478e9a5cc6 100644 --- a/dap-sdk/net/server/http_server/include/dap_http.h +++ b/dap-sdk/net/server/http_server/include/dap_http.h @@ -23,7 +23,7 @@ See more details here <http://www.gnu.org/licenses/>. #pragma once #include "dap_server.h" -#include "dap_client_remote.h" +#include "dap_events_socket.h" #include "dap_http_header.h" #include "dap_http_client.h" #include "uthash.h" diff --git a/dap-sdk/net/server/http_server/include/dap_http_folder.h b/dap-sdk/net/server/http_server/include/dap_http_folder.h index 3dec0498a19076fff6cf71e8b4eed3f10ce7c3bc..43a10f29ff52a4eca1e7ebc81f970547ee8ca5f5 100644 --- a/dap-sdk/net/server/http_server/include/dap_http_folder.h +++ b/dap-sdk/net/server/http_server/include/dap_http_folder.h @@ -1,26 +1,26 @@ /* - Copyright (c) 2017-2018 (c) Project "DeM Labs Inc" https://github.com/demlabsinc - All rights reserved. + * Authors: + * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net> + * DeM Labs Ltd. https://demlabs.net + * Copyright (c) 2017 + * All rights reserved. - This file is part of DAP (Deus Applications Prototypes) the open source project + This file is part of DAP SDK the open source project - DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by + DAP SDK is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - DAP is distributed in the hope that it will be useful, + DAP SDK is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. + GNU General Public License for more details. - You should have received a copy of the GNU Lesser General Public License - along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. + You should have received a copy of the GNU General Public License + along with any DAP SDK based project. If not, see <http://www.gnu.org/licenses/>. */ - -#ifndef _DAP_HTTP_FOLDER_H_ -#define _DAP_HTTP_FOLDER_H_ - +#pragma once struct dap_http; extern int dap_http_folder_init(); @@ -28,4 +28,3 @@ extern void dap_http_folder_deinit(); extern int dap_http_folder_add(struct dap_http *sh, const char * url_path, const char * local_path); // Add folder for reading to the HTTP server -#endif diff --git a/dap-sdk/net/stream/ch/dap_stream_ch.c b/dap-sdk/net/stream/ch/dap_stream_ch.c index fe9ca033f1a839e9eeed4764bc6d77b8def74841..be801c0e52de91b876650daac7fac4a7b08543eb 100644 --- a/dap-sdk/net/stream/ch/dap_stream_ch.c +++ b/dap-sdk/net/stream/ch/dap_stream_ch.c @@ -36,7 +36,7 @@ #include <pthread.h> #include "dap_common.h" -#include "dap_client_remote.h" +#include "dap_events_socket.h" #include "dap_http_client.h" #include "dap_stream.h" #include "dap_stream_ch.h" @@ -178,14 +178,7 @@ void dap_stream_ch_set_ready_to_read(dap_stream_ch_t * a_ch,bool a_is_ready) if( a_ch->ready_to_read != a_is_ready){ //log_it(L_DEBUG,"Change channel '%c' to %s", (char) ch->proc->id, is_ready?"true":"false"); a_ch->ready_to_read=a_is_ready; - if(a_ch->stream->conn_udp) - dap_udp_client_ready_to_read(a_ch->stream->conn,a_is_ready); - // for stream server - else if(a_ch->stream->conn) - dap_client_remote_ready_to_read( a_ch->stream->conn,a_is_ready); - // for stream client - else if(a_ch->stream->events_socket) - dap_events_socket_set_readable_unsafe( a_ch->stream->events_socket, a_is_ready); + dap_events_socket_set_readable_unsafe( a_ch->stream->esocket,a_is_ready); } pthread_mutex_unlock(&a_ch->mutex); } @@ -205,14 +198,7 @@ void dap_stream_ch_set_ready_to_write(dap_stream_ch_t * ch,bool is_ready) ch->ready_to_write=is_ready; if(is_ready && ch->stream->conn_http) ch->stream->conn_http->state_write=DAP_HTTP_CLIENT_STATE_DATA; - if(ch->stream->conn_udp) - dap_udp_client_ready_to_write(ch->stream->conn,is_ready); - // for stream server - else if(ch->stream->conn) - dap_client_remote_ready_to_write(ch->stream->conn,is_ready); - // for stream client - else if(ch->stream->events_socket) - dap_events_socket_set_writable_unsafe(ch->stream->events_socket, is_ready); + dap_events_socket_set_writable_unsafe(ch->stream->esocket,is_ready); } pthread_mutex_unlock(&ch->mutex); } diff --git a/dap-sdk/net/stream/ch/dap_stream_ch_pkt.c b/dap-sdk/net/stream/ch/dap_stream_ch_pkt.c index db22f60fae5d208182e50fefebc60077ada7869d..2fe22ceab386464f9ddaf8d21841e651a85c3984 100644 --- a/dap-sdk/net/stream/ch/dap_stream_ch_pkt.c +++ b/dap-sdk/net/stream/ch/dap_stream_ch_pkt.c @@ -41,7 +41,7 @@ #include "dap_enc.h" #include "dap_enc_key.h" -#include "dap_client_remote.h" +#include "dap_events_socket.h" #include "dap_stream.h" #include "dap_stream_ch.h" #include "dap_stream_ch_pkt.h" diff --git a/dap-sdk/net/stream/stream/dap_stream.c b/dap-sdk/net/stream/stream/dap_stream.c index 502a0e8a35f08e370c5142db8f57b805c3d6212a..0c1dd3c1ec4e3068bfc6756f1b667452cb1e5e59 100644 --- a/dap-sdk/net/stream/stream/dap_stream.c +++ b/dap-sdk/net/stream/stream/dap_stream.c @@ -45,7 +45,6 @@ #include "dap_stream_session.h" #include "dap_events_socket.h" -#include "dap_client_remote.h" #include "dap_http.h" #include "dap_http_client.h" #include "dap_http_header.h" @@ -60,14 +59,14 @@ void stream_proc_pkt_in(dap_stream_t * sid); // Callbacks for HTTP client void stream_headers_read(dap_http_client_t * sh, void * arg); // Prepare stream when all headers are read -void s_headers_write(dap_http_client_t * sh, void * arg); // Output headers -void s_data_write(dap_http_client_t * sh, void * arg); // Write the data +void s_http_client_headers_write(dap_http_client_t * sh, void * arg); // Output headers +void s_http_client_data_write(dap_http_client_t * sh, void * arg); // Write the data void stream_data_read(dap_http_client_t * sh, void * arg); // Read the data -void s_data_read(dap_client_remote_t* sh, void * arg); -void stream_dap_data_write(dap_client_remote_t* sh, void * arg); -void stream_dap_delete(dap_client_remote_t* sh, void * arg); -void stream_dap_new(dap_client_remote_t* sh,void * arg); +void s_es_read(dap_events_socket_t* sh, void * arg); +void stream_dap_data_write(dap_events_socket_t* sh, void * arg); +void s_es_callback_delete(dap_events_socket_t* sh, void * arg); +void stream_dap_udp_new(dap_events_socket_t* sh,void * arg); // Internal functions dap_stream_t * stream_new(dap_http_client_t * a_sh); // Create new stream @@ -153,7 +152,7 @@ void dap_stream_deinit() */ void dap_stream_add_proc_http(struct dap_http * sh, const char * url) { - dap_http_add_proc(sh,url,NULL,NULL,stream_delete,stream_headers_read,s_headers_write,stream_data_read,s_data_write,NULL); + dap_http_add_proc(sh,url,NULL,NULL,stream_delete,stream_headers_read,s_http_client_headers_write,stream_data_read,s_http_client_data_write,NULL); } /** @@ -163,10 +162,10 @@ void dap_stream_add_proc_http(struct dap_http * sh, const char * url) void dap_stream_add_proc_udp(dap_udp_server_t * sh) { dap_server_t* server = sh->dap_server; - server->client_read_callback = s_data_read; - server->client_write_callback = stream_dap_data_write; - server->client_delete_callback = stream_dap_delete; - server->client_new_callback = stream_dap_new; + server->client_callbacks.read_callback = s_es_read; + server->client_callbacks.write_callback = stream_dap_data_write; + server->client_callbacks.delete_callback = s_es_callback_delete; + server->client_callbacks.new_callback = stream_dap_udp_new; } /** @@ -181,10 +180,7 @@ void stream_states_update(struct dap_stream *sid) bool ready_to_write=false; for(i=0;i<sid->channel_count; i++) ready_to_write|=sid->channel[i]->ready_to_write; - if(sid->conn_udp) - dap_udp_client_ready_to_write(sid->conn_udp->client,ready_to_write); - else - dap_client_remote_ready_to_write(sid->conn,ready_to_write); + dap_events_socket_set_writable_unsafe(sid->esocket,ready_to_write); if(sid->conn_http) sid->conn_http->out_content_ready=true; } @@ -231,7 +227,7 @@ void stream_headers_read(dap_http_client_t * cl_ht, void * arg) cl_ht->reply_status_code=200; strcpy(cl_ht->reply_reason_phrase,"OK"); cl_ht->state_read=DAP_HTTP_CLIENT_STATE_DATA; - dap_client_remote_ready_to_read(cl_ht->client,true); + dap_events_socket_set_readable_unsafe(cl_ht->esocket,true); stream_states_update(sid); }else{ @@ -250,15 +246,14 @@ void stream_headers_read(dap_http_client_t * cl_ht, void * arg) * @brief stream_new_udp Create new stream instance for UDP client * @param sh DAP client structure */ -dap_stream_t * stream_new_udp(dap_client_remote_t * sh) +dap_stream_t * stream_new_udp(dap_events_socket_t * a_esocket) { dap_stream_t * ret=(dap_stream_t*) calloc(1,sizeof(dap_stream_t)); - ret->conn = sh; - ret->conn_udp=sh->_inheritor; + ret->esocket = a_esocket; ret->buf_defrag_size = 0; - sh->_internal=ret; + a_esocket->_inheritor = ret; log_it(L_NOTICE,"New stream instance udp"); return ret; @@ -269,7 +264,7 @@ dap_stream_t * stream_new_udp(dap_client_remote_t * sh) * @param id session id * @param cl DAP client structure */ -void check_session( unsigned int a_id, dap_client_remote_t *a_client_remote ) +void check_session( unsigned int a_id, dap_events_socket_t *a_client_remote ) { dap_stream_session_t *l_session = NULL; @@ -309,10 +304,7 @@ void check_session( unsigned int a_id, dap_client_remote_t *a_client_remote ) stream_states_update( l_stream ); - if ( DAP_STREAM(a_client_remote)->conn_udp ) - dap_udp_client_ready_to_read( a_client_remote, true ); - else - dap_client_remote_ready_to_read( a_client_remote, true ); + dap_events_socket_set_readable_unsafe( a_client_remote, true ); start_keepalive( l_stream ); } @@ -323,21 +315,25 @@ void check_session( unsigned int a_id, dap_client_remote_t *a_client_remote ) */ dap_stream_t * stream_new(dap_http_client_t * a_sh) { - dap_stream_t * ret=(dap_stream_t*) calloc(1,sizeof(dap_stream_t)); + dap_stream_t * ret= DAP_NEW_Z(dap_stream_t); pthread_rwlock_init( &ret->rwlock, NULL); - ret->conn = a_sh->client; + ret->esocket = a_sh->esocket; ret->conn_http=a_sh; ret->buf_defrag_size = 0; ret->seq_id = 0; ret->client_last_seq_id_packet = (size_t)-1; - ret->conn->_internal=ret; + ret->esocket->_inheritor=ret; log_it(L_NOTICE,"New stream instance"); return ret; } +/** + * @brief dap_stream_delete + * @param a_stream + */ void dap_stream_delete(dap_stream_t *a_stream) { if(a_stream == NULL) { @@ -348,9 +344,7 @@ void dap_stream_delete(dap_stream_t *a_stream) if(s_stream_keepalive_list){ DL_DELETE(s_stream_keepalive_list, a_stream); } - a_stream->conn_udp = NULL; - a_stream->conn = NULL; - a_stream->events_socket = NULL; + a_stream->esocket = NULL; pthread_mutex_unlock(&s_mutex_keepalive_list); while (a_stream->channel_count) { @@ -372,7 +366,7 @@ void dap_stream_delete(dap_stream_t *a_stream) * @param sh DAP client instance * @param arg Not used */ -void stream_dap_delete(dap_client_remote_t* sh, void * arg) +void s_es_callback_delete(dap_events_socket_t* sh, void * arg) { UNUSED(arg); if (!sh) @@ -391,7 +385,7 @@ dap_stream_t* dap_stream_new_es(dap_events_socket_t * a_es) { dap_stream_t * ret= DAP_NEW_Z(dap_stream_t); pthread_rwlock_init( &ret->rwlock, NULL); - ret->events_socket = a_es; + ret->esocket = a_es; ret->buf_defrag_size=0; ret->is_client_to_uplink = true; @@ -400,16 +394,16 @@ dap_stream_t* dap_stream_new_es(dap_events_socket_t * a_es) } /** - * @brief s_headers_write Prepare headers for output. Creates stream structure + * @brief s_http_client_headers_write Prepare headers for output. Creates stream structure * @param sh HTTP client instance * @param arg Not used */ -void s_headers_write(dap_http_client_t * sh, void *arg) +void s_http_client_headers_write(dap_http_client_t * sh, void *arg) { (void) arg; if(sh->reply_status_code==200){ - dap_stream_t *sid=DAP_STREAM(sh->client); + dap_stream_t *sid=DAP_STREAM(sh->esocket); dap_http_out_header_add(sh,"Content-Type","application/octet-stream"); dap_http_out_header_add(sh,"Connnection","keep-alive"); @@ -419,7 +413,7 @@ void s_headers_write(dap_http_client_t * sh, void *arg) dap_http_out_header_add_f(sh,"Content-Length","%u", (unsigned int) sid->stream_size ); sh->state_read=DAP_HTTP_CLIENT_STATE_DATA; - dap_client_remote_ready_to_read(sh->client,true); + dap_events_socket_set_readable_unsafe(sh->esocket,true); } } @@ -455,7 +449,7 @@ static void keepalive_cb( void ) else { log_it( L_INFO, "Client disconnected" ); DL_DELETE( s_stream_keepalive_list, l_stream ); - stream_dap_delete( l_stream->conn, NULL ); + s_es_callback_delete( l_stream->esocket, NULL ); } } @@ -485,12 +479,12 @@ void start_keepalive( dap_stream_t *sid ) { * @param sh HTTP client instance * @param arg Not used */ -void s_data_write(dap_http_client_t * sh, void * arg) +void s_http_client_data_write(dap_http_client_t * sh, void * arg) { (void) arg; if(sh->reply_status_code==200){ - stream_dap_data_write(sh->client,arg); + stream_dap_data_write(sh->esocket,arg); }else{ log_it(L_WARNING, "Wrong request, reply status code is %u",sh->reply_status_code); } @@ -501,7 +495,7 @@ void s_data_write(dap_http_client_t * sh, void * arg) * @param sh * @param arg */ -void s_data_read(dap_client_remote_t* a_client, void * arg) +void s_es_read(dap_events_socket_t* a_client, void * arg) { dap_stream_t * l_stream =DAP_STREAM(a_client); int * ret = (int *) arg; @@ -523,8 +517,8 @@ size_t dap_stream_data_proc_read (dap_stream_t *a_stream) bool found_sig=false; dap_stream_pkt_t * pkt=NULL; - char *buf_in = (a_stream->conn) ? (char*)a_stream->conn->buf_in : (char*)a_stream->events_socket->buf_in; - size_t buf_in_size = (a_stream->conn) ? a_stream->conn->buf_in_size : a_stream->events_socket->buf_in_size; + char *buf_in = (a_stream->esocket) ? (char*)a_stream->esocket->buf_in : (char*)a_stream->esocket->buf_in; + size_t buf_in_size = (a_stream->esocket) ? a_stream->esocket->buf_in_size : a_stream->esocket->buf_in_size; uint8_t *proc_data = (uint8_t *)buf_in;//a_stream->conn->buf_in; bool proc_data_defrag=false; // We are or not in defrag buffer size_t read_bytes_to=0; @@ -681,7 +675,7 @@ size_t dap_stream_data_proc_read (dap_stream_t *a_stream) * @param sh DAP client instance * @param arg Not used */ -void stream_dap_data_write(dap_client_remote_t* a_client , void * arg){ +void stream_dap_data_write(dap_events_socket_t* a_client , void * arg){ size_t i; (void) arg; bool ready_to_write=false; @@ -700,12 +694,6 @@ void stream_dap_data_write(dap_client_remote_t* a_client , void * arg){ ready_to_write?"true":"false", a_client->buf_out_size ); } - /* if(STREAM(sh)->conn_udp) - dap_udp_client_ready_to_write(STREAM(sh)->conn,ready_to_write); - else - dap_client_ready_to_write(sh,ready_to_write);*/ - //log_it(L_ERROR,"No stream_data_write_callback is defined"); - //log_it(L_DEBUG,"stream_dap_data_write ok"); } @@ -714,7 +702,7 @@ void stream_dap_data_write(dap_client_remote_t* a_client , void * arg){ * @param sh DAP client instance * @param arg Not used */ -void stream_dap_new(dap_client_remote_t* sh, void * arg){ +void stream_dap_udp_new(dap_events_socket_t* sh, void * arg){ // dap_stream_t *sid = stream_new_udp(sh); stream_new_udp(sh); } @@ -806,7 +794,7 @@ void stream_proc_pkt_in(dap_stream_t * a_stream) stream_srv_pkt_t * srv_pkt = DAP_NEW(stream_srv_pkt_t); memcpy(srv_pkt, l_pkt->data,sizeof(stream_srv_pkt_t)); uint32_t session_id = srv_pkt->session_id; - check_session(session_id,a_stream->conn); + check_session(session_id,a_stream->esocket); DAP_DELETE(srv_pkt); } else { log_it(L_WARNING, "Unknown header type"); @@ -825,7 +813,7 @@ void stream_proc_pkt_in(dap_stream_t * a_stream) */ void stream_data_read(dap_http_client_t * sh, void * arg) { - s_data_read(sh->client,arg); + s_es_read(sh->esocket,arg); } @@ -836,7 +824,7 @@ void stream_data_read(dap_http_client_t * sh, void * arg) */ void stream_delete(dap_http_client_t * sh, void * arg) { - stream_dap_delete(sh->client,arg); + s_es_callback_delete(sh->esocket,arg); } /** @@ -848,12 +836,5 @@ void dap_stream_set_ready_to_write(dap_stream_t * a_stream,bool a_is_ready) { if(a_is_ready && a_stream->conn_http) a_stream->conn_http->state_write=DAP_HTTP_CLIENT_STATE_DATA; - if(a_stream->conn_udp) - dap_udp_client_ready_to_write(a_stream->conn,a_is_ready); - // for stream server - else if(a_stream->conn) - dap_client_remote_ready_to_write(a_stream->conn,a_is_ready); - // for stream client - else if(a_stream->events_socket) - dap_events_socket_set_writable_unsafe(a_stream->events_socket, a_is_ready); + dap_events_socket_set_writable_unsafe(a_stream->esocket,a_is_ready); } diff --git a/dap-sdk/net/stream/stream/dap_stream_ctl.c b/dap-sdk/net/stream/stream/dap_stream_ctl.c index 21bd39eb99423262c6199bc573df54b2b48036e8..868a4a594e97acf9c4f661319f8f53045eb2dad6 100644 --- a/dap-sdk/net/stream/stream/dap_stream_ctl.c +++ b/dap-sdk/net/stream/stream/dap_stream_ctl.c @@ -44,7 +44,7 @@ #include "dap_http.h" #include "dap_http_client.h" -#include "dap_client_remote.h" +#include "dap_events_socket.h" #include "dap_http_simple.h" #include "dap_stream_session.h" diff --git a/dap-sdk/net/stream/stream/dap_stream_pkt.c b/dap-sdk/net/stream/stream/dap_stream_pkt.c index 9f8586bc3d6ed679ffdeca90ee135209fe0790de..a40860b2d71248076bfe33e78aad5d14017598f2 100644 --- a/dap-sdk/net/stream/stream/dap_stream_pkt.c +++ b/dap-sdk/net/stream/stream/dap_stream_pkt.c @@ -39,7 +39,7 @@ //#include "config.h" -#include "dap_client_remote.h" +#include "dap_events_socket.h" #include "dap_http_client.h" #include "dap_enc.h" @@ -145,21 +145,9 @@ size_t dap_stream_pkt_write(dap_stream_t * a_stream, const void * a_data, size_t // printf("*[dap_stream_pkt_write] size=%d key=0x%x _inheritor_size=%d\n", pkt_hdr.size, sid->session->key, // sid->session->key->_inheritor_size); - if(a_stream->conn_udp){ - ret+=dap_udp_client_write(a_stream->conn,&pkt_hdr,sizeof(pkt_hdr)); - ret+=dap_udp_client_write(a_stream->conn,a_stream->buf,pkt_hdr.size); - dap_client_remote_ready_to_write(a_stream->conn, true); - } - else if(a_stream->conn){ - ret+=dap_client_remote_write(a_stream->conn,&pkt_hdr,sizeof(pkt_hdr)); - ret+=dap_client_remote_write(a_stream->conn,a_stream->buf,pkt_hdr.size); - dap_client_remote_ready_to_write(a_stream->conn, true); - } - else if(a_stream->events_socket) { - ret += dap_events_socket_write_unsafe(a_stream->events_socket, &pkt_hdr, sizeof(pkt_hdr)); - ret += dap_events_socket_write_unsafe(a_stream->events_socket, a_stream->buf, pkt_hdr.size); - dap_events_socket_set_writable_unsafe(a_stream->events_socket, true); - } + ret+=dap_events_socket_write_unsafe(a_stream->esocket,&pkt_hdr,sizeof(pkt_hdr)); + ret+=dap_events_socket_write_unsafe(a_stream->esocket,a_stream->buf,pkt_hdr.size); + dap_events_socket_set_writable_unsafe(a_stream->esocket, true); return ret; } diff --git a/dap-sdk/net/stream/stream/include/dap_stream.h b/dap-sdk/net/stream/stream/include/dap_stream.h index 2e3aa9c2853cebbf29d7573f369ed3530b0d9d31..9f953ff0980b803ee45cfca9d61970200aacd3f8 100644 --- a/dap-sdk/net/stream/stream/include/dap_stream.h +++ b/dap-sdk/net/stream/stream/include/dap_stream.h @@ -54,13 +54,10 @@ typedef struct dap_stream { int id; pthread_rwlock_t rwlock; dap_stream_session_t * session; - struct dap_client_remote * conn; // Connection + dap_events_socket_t * esocket; // Connection struct dap_http_client * conn_http; // HTTP-specific - struct dap_udp_client * conn_udp; // UDP-client - dap_events_socket_t * events_socket; - char * service_key; bool is_live; @@ -93,7 +90,7 @@ typedef struct dap_stream { } dap_stream_t; -#define DAP_STREAM(a) ((dap_stream_t *) (a)->_internal ) +#define DAP_STREAM(a) ((dap_stream_t *) (a)->_inheritor ) int dap_stream_init(bool a_dump_packet_headers); diff --git a/dap-sdk/net/stream/stream/include/dap_stream_ctl.h b/dap-sdk/net/stream/stream/include/dap_stream_ctl.h index 94a5d62ee2dcc1b644db7c8e657c44a46fade8df..56fe6e995554b46dbe186ffb0906712194979452 100644 --- a/dap-sdk/net/stream/stream/include/dap_stream_ctl.h +++ b/dap-sdk/net/stream/stream/include/dap_stream_ctl.h @@ -19,10 +19,12 @@ */ #pragma once -typedef struct dap_http dap_http_t; +#include "dap_enc.h" +typedef struct dap_http dap_http_t; #define KEX_KEY_STR_SIZE 128 + int dap_stream_ctl_init(dap_enc_key_type_t socket_forward_key_type, size_t socket_forward_key_size); void dap_stream_ctl_deinit(); 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 f7d092aefa65c653a8b1b5dc40d25b810a2fe958..a8aa8b985cdc21539c5c0306d04cd7b9d8e199aa 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 @@ -175,8 +175,13 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg) randombytes(l_request_out->data, l_request_out->data_size); l_request_out->err_code = l_err_code; dap_hash_fast(l_request_out->data, l_request_out->data_size, &l_request_out->data_hash); - memcpy(l_request_out->ip_send, a_ch->stream->conn->s_ip, sizeof(l_request_out->ip_send)); - gettimeofday(&l_request_out->send_time2, NULL); + strncpy(l_request_out->ip_send,a_ch->stream->esocket->hostaddr , sizeof(l_request_out->ip_send)-1); + + // Thats to prevent unaligned pointer + struct timeval l_tval; + gettimeofday(&l_tval, NULL); + l_request_out->send_time2.tv_sec = l_tval.tv_sec; + l_request_out->send_time2.tv_usec = l_tval.tv_usec; // send response if(dap_stream_ch_pkt_write(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_CHECK_RESPONSE, l_request_out, l_request_out->data_size + sizeof(dap_stream_ch_chain_net_srv_pkt_test_t))) { diff --git a/modules/net/dap_dns_server.c b/modules/net/dap_dns_server.c index 1f000b8a45d37d92528cba78e1f2f4ca0f9e62f3..8c6907d31e1d1cfe2dfce67005a5db4309669fc7 100644 --- a/modules/net/dap_dns_server.c +++ b/modules/net/dap_dns_server.c @@ -26,7 +26,7 @@ #include "dap_dns_server.h" #include "dap_udp_server.h" #include "dap_udp_client.h" -#include "dap_client_remote.h" +#include "dap_events_socket.h" #include "dap_common.h" #include "dap_chain_net.h" #include "dap_chain_node.h" @@ -191,7 +191,7 @@ dap_dns_zone_callback_t dap_dns_zone_find(char *hostname) { * @param arg Unused * @return none */ -void dap_dns_client_read(dap_client_remote_t *client, void * arg) { +void dap_dns_client_read(dap_events_socket_t *client, void * arg) { UNUSED(arg); if (client->buf_in_size < DNS_HEADER_SIZE) { // Bad request return; @@ -200,7 +200,7 @@ void dap_dns_client_read(dap_client_remote_t *client, void * arg) { dap_dns_buf_t *dns_reply = DAP_NEW(dap_dns_buf_t); dns_message->data = DAP_NEW_SIZE(char, client->buf_in_size + 1); dns_message->data[client->buf_in_size] = 0; - dap_client_remote_read(client, dns_message->data, client->buf_in_size); + dap_events_socket_pop_from_buf_in(client, dns_message->data, client->buf_in_size); dns_message->ptr = 0; // Parse incoming DNS message @@ -332,8 +332,8 @@ void dap_dns_client_read(dap_client_remote_t *client, void * arg) { dns_reply->data[2] = msg_flags.val >> 8; dns_reply->data[3] = msg_flags.val; // Send DNS reply - dap_udp_client_write(client, dns_reply->data, dns_reply->ptr); - dap_udp_client_ready_to_write(client, true); + dap_events_socket_write_unsafe( client, dns_reply->data, dns_reply->ptr); + dap_events_socket_set_writable_unsafe( client, true); dap_string_free(dns_hostname, true); cleanup: DAP_DELETE(dns_reply->data); @@ -351,10 +351,10 @@ void dap_dns_server_start() { log_it(L_ERROR, "Can't start DNS server"); return; } - s_dns_server->instance->client_read_callback = dap_dns_client_read; - s_dns_server->instance->client_write_callback = NULL; - s_dns_server->instance->client_new_callback = NULL; - s_dns_server->instance->client_delete_callback = NULL; + s_dns_server->instance->client_callbacks.read_callback = dap_dns_client_read; + s_dns_server->instance->client_callbacks.write_callback = NULL; + s_dns_server->instance->client_callbacks.new_callback = NULL; + s_dns_server->instance->client_callbacks.delete_callback = NULL; dap_dns_zone_register(&s_root_alias[0], dap_dns_resolve_hostname); // root resolver pthread_create(&s_dns_server->udp_thread, NULL, (void *)dap_udp_server_loop, s_dns_server->instance); } 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 d45ace6791a839ce7019b8b642c7de519b4fc737..d4141c574611305fc4eab2795fd847ef890c03f1 100755 --- a/modules/net/srv/include/dap_chain_net_srv_common.h +++ b/modules/net/srv/include/dap_chain_net_srv_common.h @@ -73,7 +73,7 @@ typedef struct dap_chain_net_srv_abstract char decription[128]; }DAP_ALIGN_PACKED dap_chain_net_srv_abstract_t; -typedef void (*dap_chain_callback_trafic_t)(dap_client_remote_t *, dap_stream_ch_t *); +typedef void (*dap_chain_callback_trafic_t)(dap_events_socket_t *, dap_stream_ch_t *); typedef struct dap_chain_net_srv_price { diff --git a/modules/service/stake/dap_chain_net_srv_stake.c b/modules/service/stake/dap_chain_net_srv_stake.c index 77f964178c05dce2c2c742a98c8022ee838aab86..58405ee7720603a91d3c5f580eb47eed537d7ed8 100644 --- a/modules/service/stake/dap_chain_net_srv_stake.c +++ b/modules/service/stake/dap_chain_net_srv_stake.c @@ -24,6 +24,7 @@ #include <math.h> #include "dap_string.h" +#include "dap_enc_base58.h" #include "dap_chain_common.h" #include "dap_chain_node_cli.h" #include "dap_chain_mempool.h" diff --git a/modules/service/vpn/dap_chain_net_srv_vpn.c b/modules/service/vpn/dap_chain_net_srv_vpn.c index 83aad5e542b183bbd30e5a9ed4c1cc7ca38ce16a..93dee5bad4f1deca8ca38d31811345a683439ad3 100644 --- a/modules/service/vpn/dap_chain_net_srv_vpn.c +++ b/modules/service/vpn/dap_chain_net_srv_vpn.c @@ -53,7 +53,7 @@ #include "dap_strfuncs.h" #include "dap_config.h" -#include "dap_client_remote.h" +#include "dap_events_socket.h" #include "dap_http_client.h" #include "dap_stream.h" @@ -233,7 +233,7 @@ static int s_callback_client_success(dap_chain_net_srv_t * a_srv, uint32_t a_usa 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->sock = l_ch->stream->esocket->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); @@ -302,7 +302,7 @@ static int callback_client_sign_request(dap_chain_net_srv_t * a_srv, uint32_t a_ /* * Client VPN init (after dap_chain_net_srv_vpn_init!) */ -int dap_chain_net_srv_client_vpn_init(dap_config_t * g_config) { +int dap_chain_net_srv_client_vpn_init(dap_config_t * l_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; @@ -359,7 +359,7 @@ int s_tun_deattach_queue(int fd) dap_events_socket_t * s_tun_es_create(dap_worker_t * a_worker, int a_tun_fd) { assert(a_worker); - static dap_events_socket_callbacks_t l_s_callbacks = { 0 }; + static dap_events_socket_callbacks_t l_s_callbacks = {{ 0 }}; l_s_callbacks.new_callback = s_es_tun_new; l_s_callbacks.read_callback = s_es_tun_read; l_s_callbacks.error_callback = s_es_tun_error; @@ -399,7 +399,7 @@ int s_vpn_tun_create(dap_config_t * g_config) int err = -1; for( uint8_t i =0; i< l_cpu_count; i++){ - dap_worker_t * l_worker = dap_worker_get_index(i); + dap_worker_t * l_worker = dap_events_worker_get_index(i); assert( l_worker ); int l_tun_fd; if( (l_tun_fd = open("/dev/net/tun", O_RDWR| O_NONBLOCK)) < 0 ) { @@ -817,7 +817,7 @@ void s_new(dap_stream_ch_t* a_stream_ch, void* a_arg) */ void srv_ch_vpn_delete(dap_stream_ch_t* ch, void* arg) { - log_it(L_DEBUG, "ch_sf_delete() for %s", ch->stream->conn->s_ip); + log_it(L_DEBUG, "ch_sf_delete() for %s", ch->stream->esocket->hostaddr); dap_chain_net_srv_ch_vpn_t * l_ch_vpn = CH_VPN(ch); dap_chain_net_srv_vpn_t * l_srv_vpn =(dap_chain_net_srv_vpn_t *) l_ch_vpn->net_srv->_inhertor; pthread_mutex_lock(&(l_ch_vpn->mutex)); @@ -1069,11 +1069,11 @@ void s_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) 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); + a_ch->stream->esocket->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); + a_ch->stream->esocket->last_ping_request = time(NULL); break; // for client case VPN_PACKET_OP_CODE_VPN_ADDR_REPLY: { // Assigned address for peer @@ -1191,7 +1191,7 @@ void s_ch_packet_in(dap_stream_ch_t* a_ch, void* a_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 ;-) + a_ch->stream->esocket->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; diff --git a/modules/service/vpn/dap_chain_net_srv_vpn_cmd.c b/modules/service/vpn/dap_chain_net_srv_vpn_cmd.c index ce9f46417292427b0b42e8359cd9dbe1e8dddc0f..d676903d06a3d87c6d0dbd4f3930ba43bb5feee3 100644 --- a/modules/service/vpn/dap_chain_net_srv_vpn_cmd.c +++ b/modules/service/vpn/dap_chain_net_srv_vpn_cmd.c @@ -230,6 +230,5 @@ int com_vpn_client(int a_argc, char ** a_argv, void *arg_func, char **a_str_repl int dap_chain_net_srv_vpn_cmd_init() { - - + return 0; } 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 82c2f5edf29e2e644d4bb1b05af022aca92081d4..958efcf8bd76c7e1ec50ac94646323922eac9ffa 100644 --- a/modules/service/vpn/dap_chain_net_vpn_client_tun.c +++ b/modules/service/vpn/dap_chain_net_vpn_client_tun.c @@ -663,7 +663,7 @@ static void ch_sf_pkt_send(dap_stream_ch_t * a_ch, void * a_data, size_t a_data_ } l_pkt_out = DAP_NEW_Z_SIZE(ch_vpn_pkt_t, l_pkt_out_size); l_pkt_out->header.op_code = VPN_PACKET_OP_CODE_VPN_RECV; - l_pkt_out->header.sock_id = a_ch->stream->events_socket->socket; + l_pkt_out->header.sock_id = a_ch->stream->esocket->socket; l_pkt_out->header.op_data.data_size = a_data_size; memcpy(l_pkt_out->data, a_data, a_data_size); dap_stream_ch_pkt_write(a_ch, 'd', l_pkt_out, l_pkt_out_size);