diff --git a/.gitmodules b/.gitmodules index a0aeab5e95f45044e0bb8a22d28834e064e77dd2..eb0b9c6d2dbce279b64269e4fc93f3cbc46e015a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "dapclient"] - path = dapclient - url = https://github.com/kelvinblockchain/dapclient +[submodule "libdap"] + path = libdap + url = https://github.com/kelvinblockchain/libdap diff --git a/CMakeLists.txt b/CMakeLists.txt index 1c905a9ff8c9b0cf6d8719d822fa61492b9745a8..93be40b3f779b964ae3045fe372488c32e8959e5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,24 +1,11 @@ cmake_minimum_required(VERSION 3.0) -project (dap_core_server C) +project (libdap-server-core C) -set(DAP_CORE_SERVER_SRCS - dap_server.c - dap_client/dap_client.c - dap_client/dap_client_internal.c - dap_client/dap_client_remote.c - dap_client/sxmlc/sxmlc.c dap_client/sxmlc/sxmlsearch.c) +add_subdirectory(libdap) -set(DAP_CORE_SERVER_HEADERS - dap_server.h - dap_client/dap_client.h - dap_client/dap_client_internal.h - dap_client/dap_client_remote.h - dap_client/sxmlc/sxmlc.h dap_client/sxmlc/sxmlsearch.h) +file(GLOB SOURCES *.c) +file(GLOB HEADERS *.h) -include_directories(dap_client) +add_library(${PROJECT_NAME} STATIC ${SOURCES} ${HEADERS}) -add_library(${PROJECT_NAME} STATIC ${DAP_CORE_SERVER_SRCS} ${DAP_CORE_SERVER_HEADERS}) - -target_include_directories(dap_core_server INTERFACE . dap_client) - -target_link_libraries(dap_core_server ev curl dap_core dap_crypto dap_common) +target_link_libraries(${PROJECT_NAME} ev curl dap_core dap_crypto) diff --git a/dap_server.h b/dap_server.h index a9e5cad2bf6fff3d52a2d59937451b8e2b5283af..50231b0ecd82476be3da37450024c5dfae4f3432 100644 --- a/dap_server.h +++ b/dap_server.h @@ -27,7 +27,7 @@ #include <pthread.h> #include "uthash.h" -#include "dap_client_remote.h" +#include "dap_server_client.h" typedef enum dap_server_type {DAP_SERVER_TCP} dap_server_type_t; diff --git a/dap_server_client.c b/dap_server_client.c new file mode 100644 index 0000000000000000000000000000000000000000..e6c224710eba98c4d758aa80c99852395af5043c --- /dev/null +++ b/dap_server_client.c @@ -0,0 +1,247 @@ +/* + Copyright (c) 2017-2018 (c) Project "DeM Labs Inc" https://github.com/demlabsinc + 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 Lesser 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 Lesser 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/>. +*/ + +#include <sys/epoll.h> +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <unistd.h> +#include <string.h> + +#include <ev.h> + +#include "dap_common.h" +#include "dap_server_client.h" +#include "dap_server.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() +{ + +} + +/** + * @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_create(dap_server_t * sh, int s, ev_io* w_client) +{ + pthread_mutex_lock(&sh->mutex_on_hash); + log_it(L_DEBUG, "Client structure create"); + + dap_client_remote_t * ret = DAP_NEW_Z(dap_client_remote_t); + ret->socket = s; + ret->server = sh; + ret->watcher_client = w_client; + ret->_ready_to_read = true; + + HASH_ADD_INT(sh->clients, socket, ret); + if(sh->client_new_callback) + sh->client_new_callback(ret,NULL); // Init internal structure + + pthread_mutex_unlock(&sh->mutex_on_hash); + return ret; +} + +/** + * @brief dap_client_find + * @param sock + * @param sh + * @return + */ +dap_client_remote_t * dap_client_find(int sock, struct dap_server * sh) +{ + dap_client_remote_t * ret = NULL; + pthread_mutex_lock(&sh->mutex_on_hash); + HASH_FIND_INT(sh->clients, &sock, ret); + pthread_mutex_unlock(&sh->mutex_on_hash); + return ret; +} + +/** + * @brief dap_client_ready_to_read + * @param sc + * @param isReady + */ +void dap_client_ready_to_read(dap_client_remote_t * sc,bool is_ready) +{ + if(is_ready != sc->_ready_to_read) { + + uint32_t events = 0; + sc->_ready_to_read=is_ready; + + if(sc->_ready_to_read) + events |= EV_READ; + + if(sc->_ready_to_write) + events |= EV_WRITE; + + ev_io_set(sc->watcher_client, sc->socket, events ); + } +} + +/** + * @brief dap_client_ready_to_write + * @param sc + * @param isReady + */ +void dap_client_ready_to_write(dap_client_remote_t * sc,bool is_ready) +{ + if(is_ready != sc->_ready_to_write) { + + uint32_t events = 0; + sc->_ready_to_write=is_ready; + + if(sc->_ready_to_read) + events |= EV_READ; + + if(sc->_ready_to_write) + events |= EV_WRITE; + + ev_io_set(sc->watcher_client, sc->socket, events ); + } +} + + +/** + * @brief safe_client_remove Removes the client from the list + * @param sc Client instance + */ +void dap_client_remove(dap_client_remote_t *sc, struct dap_server * sh) +{ + pthread_mutex_lock(&sh->mutex_on_hash); + + log_it(L_DEBUG, "Client structure remove"); + HASH_DEL(sc->server->clients,sc); + + 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) + close(sc->socket); + free(sc); + pthread_mutex_unlock(&sh->mutex_on_hash); +} + +/** + * @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_write(dap_client_remote_t *sc, const void * data, size_t data_size) +{ + data_size = ((sc->buf_out_size+data_size)<(sizeof(sc->buf_out)))?data_size:(sizeof(sc->buf_out)-sc->buf_out_size ); + 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_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=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 sc Client instasnce + * @param data Pointer to memory where to store the data + * @param data_size Size of data to read + * @return Actual bytes number that were read + */ +size_t dap_client_read(dap_client_remote_t *sc, void * data, size_t data_size) +{ + + //log_it(L_DEBUG, "Size of package: %d\n", (int)data_size); + // + // hexdump(data, data_size); packet dump + + if (data_size < sc->buf_in_size) { + memcpy(data, sc->buf_in, data_size); + memmove(data, sc->buf_in + data_size, sc->buf_in_size - data_size); + } else { + if (data_size > sc->buf_in_size) { + data_size = sc->buf_in_size; + } + memcpy(data, sc->buf_in, data_size); + } + sc->buf_in_size -= data_size; + return data_size; +} + + +/** + * @brief shrink_client_buf_in Shrink input buffer (shift it left) + * @param cl Client instance + * @param shrink_size Size on wich we shrink the buffer with shifting it left + */ +void dap_client_shrink_buf_in(dap_client_remote_t * cl, size_t shrink_size) +{ + if((shrink_size==0)||(cl->buf_in_size==0) ){ + return; + }else if(cl->buf_in_size>shrink_size){ + size_t buf_size=cl->buf_in_size-shrink_size; + void * buf = malloc(buf_size); + memcpy(buf,cl->buf_in+ shrink_size,buf_size ); + memcpy(cl->buf_in,buf,buf_size); + cl->buf_in_size=buf_size; + free(buf); + }else { + cl->buf_in_size=0; + } + +} diff --git a/dap_server_client.h b/dap_server_client.h new file mode 100644 index 0000000000000000000000000000000000000000..f857572bafb259558d5231273a81b39d0bc4bdb7 --- /dev/null +++ b/dap_server_client.h @@ -0,0 +1,87 @@ +/* + Copyright (c) 2017-2018 (c) Project "DeM Labs Inc" https://github.com/demlabsinc + 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 Lesser 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 Lesser 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/>. +*/ +#pragma once +#ifndef _DAP_SERVER_CLIENT_H +#define _DAP_SERVER_CLIENT_H + +#include <stdint.h> +#include <stddef.h> +#include <stdbool.h> +#include "uthash.h" +#include <ev.h> + + +typedef struct dap_server dap_server_t; +struct dap_client_remote; + +typedef void (*dap_client_remote_callback_t) (struct dap_client_remote *,void * arg); // Callback for specific client operations + +#define DAP_CLIENT_REMOTE_BUF 100000 + +typedef struct dap_client_remote{ + int socket; + bool signal_close; + + bool _ready_to_write; + bool _ready_to_read; + + uint32_t buf_out_zero_count; + char buf_in[DAP_CLIENT_REMOTE_BUF+1]; // Internal buffer for input data + size_t buf_in_size; // size of data that is in the input buffer + + char buf_out[DAP_CLIENT_REMOTE_BUF+1]; // Internal buffer for output data + + char hostaddr[1024]; // Address + char service[128]; + + size_t buf_out_size; // size of data that is in the output buffer + + ev_io* watcher_client; + + struct dap_server * server; + + UT_hash_handle hh; + + 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_create(struct dap_server * sh, int s, ev_io* w_client); // Create new client and add it to the list +dap_client_remote_t * dap_client_find(int sock, struct dap_server * sh); // Find client by socket + +bool dap_client_is_ready_to_read(dap_client_remote_t * sc); +bool dap_client_is_ready_to_write(dap_client_remote_t * sc); +void dap_client_ready_to_read(dap_client_remote_t * sc,bool is_ready); +void dap_client_ready_to_write(dap_client_remote_t * sc,bool is_ready); + +size_t dap_client_write(dap_client_remote_t *sc, const void * data, size_t data_size); +size_t dap_client_write_f(dap_client_remote_t *a_client, const char * a_format,...); +size_t dap_client_read(dap_client_remote_t *sc, void * data, size_t data_size); + +void dap_client_remove(dap_client_remote_t *sc, struct dap_server * sh); // Removes the client from the list + +void dap_client_shrink_buf_in(dap_client_remote_t * cl, size_t shrink_size); + +#endif diff --git a/dapclient b/dapclient deleted file mode 160000 index fffbbcc127c627beee655696670f1f364d983c52..0000000000000000000000000000000000000000 --- a/dapclient +++ /dev/null @@ -1 +0,0 @@ -Subproject commit fffbbcc127c627beee655696670f1f364d983c52 diff --git a/libdap b/libdap new file mode 160000 index 0000000000000000000000000000000000000000..6db8f2be03aed9128919f979fc1e3f8391a6914d --- /dev/null +++ b/libdap @@ -0,0 +1 @@ +Subproject commit 6db8f2be03aed9128919f979fc1e3f8391a6914d