diff --git a/CMakeLists.txt b/CMakeLists.txt index f9f98287..7e106e6e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,6 +35,7 @@ option(INCLUDE_TCP_LISTENER "link TcpListener staticly to the core" TRUE) option(INCLUDE_LOGGER_TUNNEL "link LoggerTunnel staticly to the core" TRUE) option(INCLUDE_CONNECTOR "link Connector staticly to the core" TRUE) option(INCLUDE_TCPCONNECTOR "link TcpConnector staticly to the core" TRUE) +option(INCLUDE_UDPCONNECTOR "link UdpConnector staticly to the core" TRUE) option(INCLUDE_BRIDGE "link Bridge staticly to the core" TRUE) option(INCLUDE_OPENSSL_SERVER "link OpenSSlServer staticly to the core" TRUE) @@ -96,8 +97,8 @@ target_link_libraries(Waterwall ww) #tcp listener if (INCLUDE_TCP_LISTENER) target_compile_definitions(Waterwall PUBLIC INCLUDE_TCP_LISTENER=1) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tunnels/adapters/tcp_listener) -target_link_directories(Waterwall PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/tunnels/adapters/tcp_listener) +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tunnels/adapters/listener/tcp) +target_link_directories(Waterwall PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/tunnels/adapters/listener/tcp) target_link_libraries(Waterwall TcpListener) endif() @@ -112,17 +113,25 @@ endif() #tcp connector if (INCLUDE_TCPCONNECTOR) target_compile_definitions(Waterwall PUBLIC INCLUDE_TCPCONNECTOR=1) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tunnels/adapters/bridge) -target_link_directories(Waterwall PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/tunnels/adapters/bridge) -target_link_libraries(Waterwall Bridge) +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tunnels/adapters/connector/tcp) +target_link_directories(Waterwall PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/tunnels/adapters/connector/tcp) +target_link_libraries(Waterwall TcpConnector) +endif() + +#udp connector +if (INCLUDE_UDPCONNECTOR) +target_compile_definitions(Waterwall PUBLIC INCLUDE_UDPCONNECTOR=1) +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tunnels/adapters/connector/udp) +target_link_directories(Waterwall PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/tunnels/adapters/connector/udp) +target_link_libraries(Waterwall UdpConnector) endif() #bridge if (INCLUDE_BRIDGE) target_compile_definitions(Waterwall PUBLIC INCLUDE_BRIDGE=1) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tunnels/adapters/tcp_connector) -target_link_directories(Waterwall PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/tunnels/adapters/tcp_connector) -target_link_libraries(Waterwall TcpConnector) +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tunnels/adapters/bridge) +target_link_directories(Waterwall PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/tunnels/adapters/bridge) +target_link_libraries(Waterwall Bridge) endif() #http2 server diff --git a/core/core_settings.c b/core/core_settings.c index 51349632..c74ec4b9 100644 --- a/core/core_settings.c +++ b/core/core_settings.c @@ -23,45 +23,7 @@ static struct core_settings_s *settings = NULL; -#ifdef OS_UNIX -#include -void increaseFileLimit() -{ - struct rlimit rlim; - // Get the current limit - if (getrlimit(RLIMIT_NOFILE, &rlim) == -1) - { - LOGF("Core: getrlimit failed"); - exit(EXIT_FAILURE); - } - if ((unsigned long) rlim.rlim_max < 8192) - { - LOGW( - "Core: Maximum allowed open files limit is %lu which is below 8192 !\n if you are running as a server then \ - you might experince time-outs if this limits gets reached, depends on how many clients are connected to the server simultaneously\ - ", - (unsigned long) rlim.rlim_max); - } - else - { - LOGD("Core: File limit %lu -> %lu", (unsigned long) rlim.rlim_cur, (unsigned long) rlim.rlim_max); - } - // Set the hard limit to the maximum allowed value - rlim.rlim_cur = rlim.rlim_max; - // Apply the new limit - if (setrlimit(RLIMIT_NOFILE, &rlim) == -1) - { - LOGF("Core: setrlimit failed"); - exit(EXIT_FAILURE); - } -} -#else -void increaseFileLimit() -{ - (void) (0); -} -#endif static void parseLogPartOfJsonNoCheck(const cJSON *log_obj) { @@ -129,8 +91,6 @@ static void parseLogPartOfJsonNoCheck(const cJSON *log_obj) } } - - static void parseLogPartOfJson(cJSON *log_obj) { if (cJSON_IsObject(log_obj) && (log_obj->child != NULL)) @@ -229,11 +189,17 @@ void parseCoreSettings(char *data_json) parseConfigPartOfJson(cJSON_GetObjectItemCaseSensitive(json, "configs")); parseMiscPartOfJson(cJSON_GetObjectItemCaseSensitive(json, "misc")); - if ((settings->workers_count < 0) || (settings->workers_count > 200)) + if (settings->workers_count <= 0) { - LOGF("CoreSettings: the workers count is invalid"); + fprintf(stderr, "CoreSettings: the workers count is invalid"); exit(1); } + + if (settings->workers_count > 255) + { + fprintf(stderr, "CoreSettings: workers count is shrinked to maximum supported value -> 255"); + settings->workers_count = 255; + } cJSON_Delete(json); // TODO (DNS) Implement dns settings and backend } diff --git a/core/core_settings.h b/core/core_settings.h index 825f4c42..221af36d 100644 --- a/core/core_settings.h +++ b/core/core_settings.h @@ -28,7 +28,6 @@ struct core_settings_s }; void parseCoreSettings(char *data_json); -void increaseFileLimit(); char *getCoreLoggerFullPath(); char *getNetworkLoggerFullPath(); diff --git a/core/main.c b/core/main.c index 7f5adf21..5b7d07be 100644 --- a/core/main.c +++ b/core/main.c @@ -5,8 +5,13 @@ #include "loggers/network_logger.h" #include "managers/node_manager.h" #include "managers/socket_manager.h" +#include "os_helpers.h" #include "static_tunnels.h" #include "utils/fileutils.h" +#include "utils/stringutils.h" + +#undef hlog +#define hlog getCoreLogger() // NOLINT #define CORE_FILE "core.json" @@ -38,14 +43,14 @@ int main(void) ww_construction_data_t runtime_data = { .workers_count = getCoreSettings()->workers_count, .core_logger_data = (logger_construction_data_t){.log_file_path = getCoreLoggerFullPath(), - .log_level = getCoreSettings()->core_log_level, - .log_console = getCoreSettings()->core_log_console}, + .log_level = getCoreSettings()->core_log_level, + .log_console = getCoreSettings()->core_log_console}, .network_logger_data = (logger_construction_data_t){.log_file_path = getNetworkLoggerFullPath(), .log_level = getCoreSettings()->network_log_level, .log_console = getCoreSettings()->network_log_level}, .dns_logger_data = (logger_construction_data_t){.log_file_path = getDnsLoggerFullPath(), - .log_level = getCoreSettings()->dns_log_level, - .log_console = getCoreSettings()->dns_log_console}, + .log_level = getCoreSettings()->dns_log_level, + .log_console = getCoreSettings()->dns_log_console}, }; createWW(runtime_data); diff --git a/core/os_helpers.h b/core/os_helpers.h new file mode 100644 index 00000000..4c060877 --- /dev/null +++ b/core/os_helpers.h @@ -0,0 +1,43 @@ +#pragma once + +#include "loggers/core_logger.h" + +#ifdef OS_UNIX +#include +static void increaseFileLimit() +{ + + struct rlimit rlim; + // Get the current limit + if (getrlimit(RLIMIT_NOFILE, &rlim) == -1) + { + LOGF("Core: getrlimit failed"); + exit(EXIT_FAILURE); + } + if ((unsigned long) rlim.rlim_max < 8192) + { + LOGW( + "Core: Maximum allowed open files limit is %lu which is below 8192 !\n if you are running as a server then \ + you might experince time-outs if this limits gets reached, depends on how many clients are connected to the server simultaneously\ + ", + (unsigned long) rlim.rlim_max); + } + else + { + LOGD("Core: File limit %lu -> %lu", (unsigned long) rlim.rlim_cur, (unsigned long) rlim.rlim_max); + } + // Set the hard limit to the maximum allowed value + rlim.rlim_cur = rlim.rlim_max; + // Apply the new limit + if (setrlimit(RLIMIT_NOFILE, &rlim) == -1) + { + LOGF("Core: setrlimit failed"); + exit(EXIT_FAILURE); + } +} +#else +static void increaseFileLimit() +{ + (void) (0); +} +#endif \ No newline at end of file diff --git a/core/static_tunnels.c b/core/static_tunnels.c index 74fb7a7d..02dceafc 100644 --- a/core/static_tunnels.c +++ b/core/static_tunnels.c @@ -12,7 +12,7 @@ } while (0) #ifdef INCLUDE_TCP_LISTENER -#include "tunnels/adapters/tcp_listener/tcp_listener.h" +#include "tunnels/adapters/listener/tcp/tcp_listener.h" #endif #ifdef INCLUDE_OPENSSL_SERVER @@ -40,7 +40,7 @@ #endif #ifdef INCLUDE_TCPCONNECTOR -#include "tunnels/adapters/tcp_connector/tcp_connector.h" +#include "tunnels/adapters/connector/tcp/tcp_connector.h" #endif #ifdef INCLUDE_BRIDGE diff --git a/tunnels/adapters/bridge/bridge.c b/tunnels/adapters/bridge/bridge.c index 043425fa..f045c8ac 100644 --- a/tunnels/adapters/bridge/bridge.c +++ b/tunnels/adapters/bridge/bridge.c @@ -1,18 +1,11 @@ #include "bridge.h" -#include "managers/node_manager.h" #include "loggers/network_logger.h" - - -#define STATE(x) ((bridge_state_t *)((x)->state)) -#define CSTATE(x) ((bridge_con_state_t *)((((x)->line->chains_state)[self->chain_index]))) -#define CSTATE_MUT(x) ((x)->line->chains_state)[self->chain_index] -#define ISALIVE(x) (CSTATE(x) != NULL) +#include "managers/node_manager.h" typedef struct bridge_state_s { - bool initialized; - bool mode_upside; // this node is last node of upstream - node_t *pair_node; + bool mode_upside; // this node is last node of upstream + node_t * pair_node; tunnel_t *pair; } bridge_state_t; @@ -22,66 +15,33 @@ typedef struct bridge_con_state_s } bridge_con_state_t; -static void secondary_init(tunnel_t *self, bridge_state_t *state) -{ - if (state->pair_node->instance == NULL) - { - LOGF("Bridge: the pair node is not running"); - exit(1); - } - if (!state->mode_upside && self->dw != NULL) - { - LOGF("Bridge: misconfiguration, bridge only exists at the start or end of a chain"); - exit(1); - } - state->pair = state->pair_node->instance; - state->initialized = true; -} static void upStream(tunnel_t *self, context_t *c) { bridge_state_t *state = STATE(self); - if (!state->initialized) - secondary_init(self,state); if (state->mode_upside) - state->pair->downStream(state->pair, c); - else - self->up->upStream(self->up, c); + { + self->dw->upStream = state->pair->dw->downStream; + state->pair->dw->downStream(state->pair, c); + } } static inline void downStream(tunnel_t *self, context_t *c) { bridge_state_t *state = STATE(self); - if (!state->initialized) - secondary_init(self,state); - if (state->mode_upside) - self->dw->downStream(self->dw, c); - else - state->pair->upStream(state->pair, c); -} -static void BridgeUpStream(tunnel_t *self, context_t *c) -{ - upStream(self, c); -} -static void BridgePacketUpStream(tunnel_t *self, context_t *c) -{ - upStream(self, c); -} -static void BridgeDownStream(tunnel_t *self, context_t *c) -{ - downStream(self, c); -} -static void BridgePacketDownStream(tunnel_t *self, context_t *c) -{ - downStream(self, c); + if (! state->mode_upside) + { + self->up->downStream = state->pair->up->upStream; + state->pair->up->upStream(state->pair, c); + } } tunnel_t *newBridge(node_instance_context_t *instance_info) { - const cJSON *settings = instance_info->node_settings_json; - char *pair_node_name = NULL; - if (!getStringFromJsonObject(&pair_node_name, settings, "pair")) + const cJSON *settings = instance_info->node_settings_json; + char * pair_node_name = NULL; + if (! getStringFromJsonObject(&pair_node_name, settings, "pair")) { LOGF("Bridge: \"pair\" is not provided in json"); exit(1); @@ -90,38 +50,46 @@ tunnel_t *newBridge(node_instance_context_t *instance_info) bridge_state_t *state = malloc(sizeof(bridge_state_t)); memset(state, 0, sizeof(bridge_state_t)); - hash_t hash_pairname = CALC_HASH_BYTES(pair_node_name, strlen(pair_node_name)); - node_t *pair_node = getNode(hash_pairname); + hash_t hash_pairname = CALC_HASH_BYTES(pair_node_name, strlen(pair_node_name)); + node_t *pair_node = getNode(hash_pairname); if (pair_node == NULL) { LOGF("Bridge: pair node \"%s\" not found", pair_node_name); exit(1); } free(pair_node_name); - state->pair_node = pair_node; - state->mode_upside = instance_info->self_node_handle->next == NULL; + state->pair_node = pair_node; + state->mode_upside = instance_info->node->next == NULL; + tunnel_t *t = newTunnel(); + if (pair_node->instance) + { + state->pair = pair_node->instance; + bridge_state_t *pair_state = STATE(pair_node->instance); + pair_state->pair = t; + } - tunnel_t *t = newTunnel(); - t->state = state; - t->upStream = &BridgeUpStream; - t->packetUpStream = &BridgePacketUpStream; - t->downStream = &BridgeDownStream; - t->packetDownStream = &BridgePacketDownStream; + t->state = state; + t->upStream = &upStream; + t->downStream = &downStream; return t; } -api_result_t apiBridge(tunnel_t *self, char *msg) +api_result_t apiBridge(tunnel_t *self, const char *msg) { - (void)(self); (void)(msg); return (api_result_t){0}; // TODO + (void) (self); + (void) (msg); + return (api_result_t){0}; } tunnel_t *destroyBridge(tunnel_t *self) { + (void) (self); + return NULL; } tunnel_metadata_t getMetadataBridge() { - return (tunnel_metadata_t){.version = 0001, .flags = TFLAG_ROUTE_STARTER}; + return (tunnel_metadata_t){.version = 0001, .flags = kNodeFlagChainHead}; } \ No newline at end of file diff --git a/tunnels/adapters/bridge/bridge.h b/tunnels/adapters/bridge/bridge.h index aecc0c10..ce437648 100644 --- a/tunnels/adapters/bridge/bridge.h +++ b/tunnels/adapters/bridge/bridge.h @@ -1,12 +1,9 @@ #pragma once #include "api.h" - // con <------> Bridge(pair 1) <------> Bridge(pair 2) <------> con - - -tunnel_t *newBridge(node_instance_context_t *instance_info); -api_result_t apiBridge(tunnel_t *self, char *msg); -tunnel_t *destroyBridge(tunnel_t *self); +tunnel_t * newBridge(node_instance_context_t *instance_info); +api_result_t apiBridge(tunnel_t *self, const char *msg); +tunnel_t * destroyBridge(tunnel_t *self); tunnel_metadata_t getMetadataBridge(); diff --git a/tunnels/adapters/connector/CMakeLists.txt b/tunnels/adapters/connector/CMakeLists.txt index f8bff61b..f10b3785 100644 --- a/tunnels/adapters/connector/CMakeLists.txt +++ b/tunnels/adapters/connector/CMakeLists.txt @@ -2,28 +2,17 @@ add_library(Connector STATIC connector.c - tcp.c - udp.c - resolve.c - + ) # target_include_directories(Connector PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) - #ww api target_include_directories(Connector PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../ww) target_link_libraries(Connector ww) - - # add dependencies include(${CMAKE_BINARY_DIR}/cmake/CPM.cmake) - - - target_compile_definitions(Connector PRIVATE Connector_VERSION=0.1) - if(CMAKE_BUILD_TYPE STREQUAL "Debug") target_compile_definitions(Connector PRIVATE DEBUG=1) - endif() diff --git a/tunnels/adapters/connector/connector.c b/tunnels/adapters/connector/connector.c index 88b31949..7481fb2c 100644 --- a/tunnels/adapters/connector/connector.c +++ b/tunnels/adapters/connector/connector.c @@ -1,39 +1,80 @@ #include "connector.h" #include "loggers/network_logger.h" -#include "types.h" -#include "utils/sockutils.h" +#include "managers/node_manager.h" +#include "utils/stringutils.h" -static void tcpUpStream(tunnel_t *self, context_t *c) +typedef struct connector_state_s { -} -static void tcpDownStream(tunnel_t *self, context_t *c) -{ -} -static void udpUpStream(tunnel_t *self, context_t *c) -{ -} -static void udpDownStream(tunnel_t *self, context_t *c) + tunnel_t *tcp_connector; + tunnel_t *udp_connector; + +} connector_state_t; + +typedef struct connector_con_state_s { -} + +} connector_con_state_t; static void upStream(tunnel_t *self, context_t *c) { + connector_state_t *state = STATE(self); + + switch ((c->line->dest_ctx.address_protocol)) + { + default: + case kSapTcp: + state->tcp_connector->upStream(state->tcp_connector, c); + + break; + case kSapUdp: + state->udp_connector->upStream(state->udp_connector, c); + break; + } } static void downStream(tunnel_t *self, context_t *c) { + connector_state_t *state = STATE(self); + switch ((c->line->dest_ctx.address_protocol)) + { + + default: + case kSapTcp: + state->tcp_connector->downStream(state->tcp_connector, c); + break; + + case kSapUdp: + state->udp_connector->downStream(state->udp_connector, c); + break; + } } tunnel_t *newConnector(node_instance_context_t *instance_info) { connector_state_t *state = malloc(sizeof(connector_state_t)); memset(state, 0, sizeof(connector_state_t)); - const cJSON *settings = instance_info->node_settings_json; + cJSON *settings = instance_info->node_settings_json; if (! (cJSON_IsObject(settings) && settings->child != NULL)) { LOGF("JSON Error: Connector->settings (object field) : The object was empty or invalid"); return NULL; } + node_t *tcp_outbound_node = malloc(sizeof(node_t)); + node_t *udp_outbound_node = malloc(sizeof(node_t)); + memset(tcp_outbound_node, 0, sizeof(node_t)); + memset(udp_outbound_node, 0, sizeof(node_t)); + tcp_outbound_node->name = concat(instance_info->node->name, "_tcp_outbound"); + tcp_outbound_node->type = "TcpConnector"; + tcp_outbound_node->version = instance_info->node->version; + udp_outbound_node->name = concat(instance_info->node->name, "_udp_outbound"); + udp_outbound_node->type = "UdpConnector"; + udp_outbound_node->version = instance_info->node->version; + registerNode(tcp_outbound_node, settings); + registerNode(udp_outbound_node, settings); + runNode(tcp_outbound_node, instance_info->chain_index + 1); + runNode(udp_outbound_node, instance_info->chain_index + 1); + state->tcp_connector = tcp_outbound_node->instance; + state->udp_connector = udp_outbound_node->instance; tunnel_t *t = newTunnel(); t->state = state; @@ -42,7 +83,7 @@ tunnel_t *newConnector(node_instance_context_t *instance_info) atomic_thread_fence(memory_order_release); return t; } -api_result_t apiConnector(tunnel_t *self,const char *msg) +api_result_t apiConnector(tunnel_t *self, const char *msg) { (void) (self); (void) (msg); diff --git a/tunnels/adapters/connector/tcp/CMakeLists.txt b/tunnels/adapters/connector/tcp/CMakeLists.txt index 6157ae30..549769de 100644 --- a/tunnels/adapters/connector/tcp/CMakeLists.txt +++ b/tunnels/adapters/connector/tcp/CMakeLists.txt @@ -1,26 +1,19 @@ add_library(TcpConnector STATIC - resolve.c tcp_connector.c ) -# target_include_directories(TcpConnector PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) #ww api target_include_directories(TcpConnector PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../ww) target_link_libraries(TcpConnector ww) - # add dependencies include(${CMAKE_BINARY_DIR}/cmake/CPM.cmake) - - target_compile_definitions(TcpConnector PRIVATE TcpConnector_VERSION=0.1) - if(CMAKE_BUILD_TYPE STREQUAL "Debug") target_compile_definitions(TcpConnector PRIVATE DEBUG=1) - endif() diff --git a/tunnels/adapters/connector/tcp/tcp_connector.c b/tunnels/adapters/connector/tcp/tcp_connector.c index 5d20d86b..7800c6fb 100644 --- a/tunnels/adapters/connector/tcp/tcp_connector.c +++ b/tunnels/adapters/connector/tcp/tcp_connector.c @@ -2,6 +2,7 @@ #include "loggers/network_logger.h" #include "types.h" #include "utils/sockutils.h" +#include "sync_dns.h" static void cleanup(tcp_connector_con_state_t *cstate, bool write_queue) { @@ -242,7 +243,7 @@ void upStream(tunnel_t *self, context_t *c) gettimeofday(&(cstate->__profile_conenct), NULL); #endif - cstate->buffer_pool = buffer_pools[c->line->tid]; + cstate->buffer_pool = getContextBufferPool(c); cstate->tunnel = self; cstate->line = c->line; cstate->data_queue = newContextQueue(cstate->buffer_pool); @@ -254,10 +255,10 @@ void upStream(tunnel_t *self, context_t *c) switch (state->dest_addr_selected.status) { case kCdvsFromSource: - copySocketContextAddr(&dest_ctx, &src_ctx); + copySocketContextAddr(dest_ctx, src_ctx); break; case kCdvsConstant: - copySocketContextAddr(&dest_ctx, &(state->constant_dest_addr)); + copySocketContextAddr(dest_ctx, &(state->constant_dest_addr)); break; default: case kCdvsFromDest: @@ -266,10 +267,10 @@ void upStream(tunnel_t *self, context_t *c) switch (state->dest_port_selected.status) { case kCdvsFromSource: - copySocketContextPort(&dest_ctx, &src_ctx); + copySocketContextPort(dest_ctx, src_ctx); break; case kCdvsConstant: - copySocketContextPort(&dest_ctx, &(state->constant_dest_addr)); + copySocketContextPort(dest_ctx, &(state->constant_dest_addr)); break; default: case kCdvsFromDest: @@ -428,7 +429,7 @@ tunnel_t *newTcpConnector(node_instance_context_t *instance_info) } if (state->dest_port_selected.status == kDvsConstant) { - sockaddr_set_port(&(state->constant_dest_addr), state->dest_port_selected.value); + setSocketContextPort(&(state->constant_dest_addr), state->dest_port_selected.value); } tunnel_t *t = newTunnel(); diff --git a/tunnels/adapters/connector/tcp/tcp_connector.h b/tunnels/adapters/connector/tcp/tcp_connector.h index d0c41c6e..d7e0a1f6 100644 --- a/tunnels/adapters/connector/tcp/tcp_connector.h +++ b/tunnels/adapters/connector/tcp/tcp_connector.h @@ -1,14 +1,12 @@ #pragma once #include "api.h" - // con <-----\ /-----> Resolve=> TCP Connect // con <------> TcpConnector <------> Resolve=> TCP Connect // con <-----/ \-----> Resolve=> TCP Connect // - -tunnel_t *newTcpConnector(node_instance_context_t *instance_info); -api_result_t apiTcpConnector(tunnel_t *self,const char *msg); -tunnel_t *destroyTcpConnector(tunnel_t *self); +tunnel_t * newTcpConnector(node_instance_context_t *instance_info); +api_result_t apiTcpConnector(tunnel_t *self, const char *msg); +tunnel_t * destroyTcpConnector(tunnel_t *self); tunnel_metadata_t getMetadataTcpConnector(); diff --git a/tunnels/adapters/connector/tcp/types.h b/tunnels/adapters/connector/tcp/types.h index 3f6eea5f..3053be9f 100644 --- a/tunnels/adapters/connector/tcp/types.h +++ b/tunnels/adapters/connector/tcp/types.h @@ -15,13 +15,13 @@ enum tcp_connector_dynamic_value_status typedef struct tcp_connector_state_s { // settings - bool tcp_no_delay; - bool tcp_fast_open; - bool reuse_addr; - enum domain_strategy domain_strategy; - dynamic_value_t dest_addr_selected; - dynamic_value_t dest_port_selected; - socket_context_t constant_dest_addr; + bool tcp_no_delay; + bool tcp_fast_open; + bool reuse_addr; + int domain_strategy; + dynamic_value_t dest_addr_selected; + dynamic_value_t dest_port_selected; + socket_context_t constant_dest_addr; } tcp_connector_state_t; diff --git a/tunnels/adapters/connector/types.h b/tunnels/adapters/connector/types.h deleted file mode 100644 index 442b0765..00000000 --- a/tunnels/adapters/connector/types.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once -#include "api.h" - - - -typedef struct connector_state_s -{ - tunnel_t *tcp_connector; - tunnel_t *udp_connector; - -} connector_state_t; - -typedef struct connector_con_state_s -{ - -} connector_con_state_t; - - - diff --git a/tunnels/adapters/connector/udp/CMakeLists.txt b/tunnels/adapters/connector/udp/CMakeLists.txt index f8bff61b..c50eb8b9 100644 --- a/tunnels/adapters/connector/udp/CMakeLists.txt +++ b/tunnels/adapters/connector/udp/CMakeLists.txt @@ -1,29 +1,21 @@ -add_library(Connector STATIC - connector.c - tcp.c - udp.c - resolve.c +add_library(UdpConnector STATIC + udp_connector.c ) -# target_include_directories(Connector PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) #ww api -target_include_directories(Connector PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../ww) -target_link_libraries(Connector ww) +target_include_directories(UdpConnector PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../ww) +target_link_libraries(UdpConnector ww) # add dependencies include(${CMAKE_BINARY_DIR}/cmake/CPM.cmake) - - -target_compile_definitions(Connector PRIVATE Connector_VERSION=0.1) - +target_compile_definitions(UdpConnector PRIVATE UdpConnector_VERSION=0.1) if(CMAKE_BUILD_TYPE STREQUAL "Debug") -target_compile_definitions(Connector PRIVATE DEBUG=1) - +target_compile_definitions(UdpConnector PRIVATE DEBUG=1) endif() diff --git a/tunnels/adapters/connector/udp/types.h b/tunnels/adapters/connector/udp/types.h index f63ced70..365d0365 100644 --- a/tunnels/adapters/connector/udp/types.h +++ b/tunnels/adapters/connector/udp/types.h @@ -15,11 +15,11 @@ enum udp_connector_dynamic_value_status typedef struct udp_connector_state_s { // settings - bool reuse_addr; - enum domain_strategy domain_strategy; - dynamic_value_t dest_addr_selected; - dynamic_value_t dest_port_selected; - socket_context_t constant_dest_addr; + bool reuse_addr; + int domain_strategy; + dynamic_value_t dest_addr_selected; + dynamic_value_t dest_port_selected; + socket_context_t constant_dest_addr; } udp_connector_state_t; @@ -29,10 +29,10 @@ typedef struct udp_connector_con_state_s struct timeval __profile_conenct; #endif - tunnel_t *tunnel; - line_t * line; - hio_t * io; - buffer_pool_t * buffer_pool; + tunnel_t * tunnel; + line_t * line; + hio_t * io; + buffer_pool_t *buffer_pool; bool established; } udp_connector_con_state_t; diff --git a/tunnels/adapters/connector/udp/udp_connector.c b/tunnels/adapters/connector/udp/udp_connector.c index 99ccbb4e..db45942e 100644 --- a/tunnels/adapters/connector/udp/udp_connector.c +++ b/tunnels/adapters/connector/udp/udp_connector.c @@ -1,5 +1,6 @@ #include "loggers/network_logger.h" #include "types.h" +#include "sync_dns.h" #include "utils/sockutils.h" static void cleanup(udp_connector_con_state_t *cstate) @@ -37,7 +38,7 @@ static void onRecv(hio_t *io, void *buf, int readbytes) context_t *est_context = newContext(line); est_context->est = true; est_context->src_io = io; - self->packetDownStream(self, est_context); + self->downStream(self, est_context); if (hevent_userdata(io) == NULL) { return; @@ -48,7 +49,7 @@ static void onRecv(hio_t *io, void *buf, int readbytes) context->src_io = io; context->payload = payload; - self->packetDownStream(self, context); + self->downStream(self, context); } void upStream(tunnel_t *self, context_t *c) @@ -86,7 +87,7 @@ void upStream(tunnel_t *self, context_t *c) memset(CSTATE(c), 0, sizeof(udp_connector_con_state_t)); udp_connector_con_state_t *cstate = CSTATE(c); - cstate->buffer_pool = buffer_pools[c->line->tid]; + cstate->buffer_pool = getContextBufferPool(c); cstate->tunnel = self; cstate->line = c->line; // sockaddr_set_ipport(&(dest->addr),"www.gstatic.com",80); @@ -130,10 +131,10 @@ void upStream(tunnel_t *self, context_t *c) switch (state->dest_addr_selected.status) { case kCdvsFromSource: - copySocketContextAddr(&dest_ctx, &src_ctx); + copySocketContextAddr(dest_ctx, src_ctx); break; case kCdvsConstant: - copySocketContextAddr(&dest_ctx, &(state->constant_dest_addr)); + copySocketContextAddr(dest_ctx, &(state->constant_dest_addr)); break; default: case kCdvsFromDest: @@ -142,10 +143,10 @@ void upStream(tunnel_t *self, context_t *c) switch (state->dest_port_selected.status) { case kCdvsFromSource: - copySocketContextPort(&dest_ctx, &src_ctx); + copySocketContextPort(dest_ctx, src_ctx); break; case kCdvsConstant: - copySocketContextPort(&dest_ctx, &(state->constant_dest_addr)); + copySocketContextPort(dest_ctx, &(state->constant_dest_addr)); break; default: case kCdvsFromDest: @@ -235,7 +236,7 @@ tunnel_t *newUdpConnector(node_instance_context_t *instance_info) } if (state->dest_port_selected.status == kDvsConstant) { - sockaddr_set_port(&(state->constant_dest_addr), state->dest_port_selected.value); + setSocketContextPort(&(state->constant_dest_addr), state->dest_port_selected.value); } tunnel_t *t = newTunnel(); t->state = state; diff --git a/tunnels/adapters/listener/tcp/tcp_listener.c b/tunnels/adapters/listener/tcp/tcp_listener.c index 9f895c97..fc566e76 100644 --- a/tunnels/adapters/listener/tcp/tcp_listener.c +++ b/tunnels/adapters/listener/tcp/tcp_listener.c @@ -540,5 +540,5 @@ tunnel_t *destroyTcpListener(tunnel_t *self) } tunnel_metadata_t getMetadataTcpListener() { - return (tunnel_metadata_t){.version = 0001, .flags = TFLAG_ROUTE_STARTER}; + return (tunnel_metadata_t){.version = 0001, .flags = kNodeFlagChainHead}; } \ No newline at end of file diff --git a/tunnels/client/header/header_client.c b/tunnels/client/header/header_client.c index 1dfbc21c..36b4b4fc 100644 --- a/tunnels/client/header/header_client.c +++ b/tunnels/client/header/header_client.c @@ -3,13 +3,6 @@ #include "hv/hsocket.h" #include "loggers/network_logger.h" -#define MAX_PACKET_SIZE 65535 - -#define STATE(x) ((header_client_state_t *)((x)->state)) -#define CSTATE(x) ((header_client_con_state_t *)((((x)->line->chains_state)[self->chain_index]))) -#define CSTATE_MUT(x) ((x)->line->chains_state)[self->chain_index] -#define ISALIVE(x) (CSTATE(x) != NULL) - enum header_dynamic_value_status { kHdvsEmpty = 0x0, @@ -35,7 +28,7 @@ static void upStream(tunnel_t *self, context_t *c) if (c->payload != NULL && c->first) { - switch ((enum header_dynamic_value_status)state->data.status) + switch ((enum header_dynamic_value_status) state->data.status) { case kHdvsSourcePort: shiftl(c->payload, sizeof(uint16_t)); @@ -56,20 +49,17 @@ static inline void downStream(tunnel_t *self, context_t *c) self->dw->downStream(self->dw, c); } - - tunnel_t *newHeaderClient(node_instance_context_t *instance_info) { header_client_state_t *state = malloc(sizeof(header_client_state_t)); memset(state, 0, sizeof(header_client_state_t)); const cJSON *settings = instance_info->node_settings_json; - state->data = parseDynamicNumericValueFromJsonObject(settings, "data", 1, - "src_context->port"); - tunnel_t *t = newTunnel(); - t->state = state; - t->upStream = &upStream; - t->downStream = &downStream; + state->data = parseDynamicNumericValueFromJsonObject(settings, "data", 1, "src_context->port"); + tunnel_t *t = newTunnel(); + t->state = state; + t->upStream = &upStream; + t->downStream = &downStream; atomic_thread_fence(memory_order_release); return t; @@ -77,11 +67,14 @@ tunnel_t *newHeaderClient(node_instance_context_t *instance_info) api_result_t apiHeaderClient(tunnel_t *self, const char *msg) { - (void)(self); (void)(msg); return (api_result_t){0}; // TODO(root): + (void) (self); + (void) (msg); + return (api_result_t){0}; // TODO(root): } tunnel_t *destroyHeaderClient(tunnel_t *self) { + (void) (self); return NULL; } tunnel_metadata_t getMetadataHeaderClient() diff --git a/tunnels/client/http2/helpers.h b/tunnels/client/http2/helpers.h index 3a6089fa..ce66a488 100644 --- a/tunnels/client/http2/helpers.h +++ b/tunnels/client/http2/helpers.h @@ -3,59 +3,51 @@ #include "types.h" #define MAX_CONCURRENT_STREAMS 0xffffffffu -#define PING_INTERVAL 5000 +#define PING_INTERVAL 5000 -#define STATE(x) ((http2_client_state_t *)((x)->state)) -#define CSTATE(x) ((void *)((((x)->line->chains_state)[self->chain_index]))) -#define CSTATE_MUT(x) ((x)->line->chains_state)[self->chain_index] -#define ISALIVE(x) (CSTATE(x) != NULL) +static void onPingTimer(htimer_t *timer); -static void on_ping_timer(htimer_t *timer); - -static nghttp2_nv make_nv(const char *name, const char *value) +static nghttp2_nv makeNV(const char *name, const char *value) { nghttp2_nv nv; - nv.name = (uint8_t *)name; - nv.value = (uint8_t *)value; - nv.namelen = strlen(name); + nv.name = (uint8_t *) name; + nv.value = (uint8_t *) value; + nv.namelen = strlen(name); nv.valuelen = strlen(value); - nv.flags = NGHTTP2_NV_FLAG_NONE; + nv.flags = NGHTTP2_NV_FLAG_NONE; return nv; } -static nghttp2_nv make_nv2(const char *name, const char *value, - int namelen, int valuelen) +static nghttp2_nv makeNV2(const char *name, const char *value, int namelen, int valuelen) { nghttp2_nv nv; - nv.name = (uint8_t *)name; - nv.value = (uint8_t *)value; - nv.namelen = namelen; + nv.name = (uint8_t *) name; + nv.value = (uint8_t *) value; + nv.namelen = namelen; nv.valuelen = valuelen; - nv.flags = NGHTTP2_NV_FLAG_NONE; + nv.flags = NGHTTP2_NV_FLAG_NONE; return nv; } -static void print_frame_hd(const nghttp2_frame_hd *hd) +static void printFrameHd(const nghttp2_frame_hd *hd) { - printd("[frame] length=%d type=%x flags=%x stream_id=%d\n", - (int)hd->length, (int)hd->type, (int)hd->flags, hd->stream_id); + LOGD("[frame] length=%d type=%x flags=%x stream_id=%d\n", (int) hd->length, (int) hd->type, (int) hd->flags, + hd->stream_id); } -static void add_stream(http2_client_con_state_t *con, - http2_client_child_con_state_t *stream) +static void addStraem(http2_client_con_state_t *con, http2_client_child_con_state_t *stream) { - stream->next = con->root.next; + stream->next = con->root.next; con->root.next = stream; - stream->prev = &con->root; + stream->prev = &con->root; if (stream->next) { stream->next->prev = stream; } } -static void remove_stream(http2_client_con_state_t *con, - http2_client_child_con_state_t *stream) +static void removeStream(http2_client_con_state_t *con, http2_client_child_con_state_t *stream) { - + (void) con; stream->prev->next = stream->next; if (stream->next) { @@ -63,63 +55,62 @@ static void remove_stream(http2_client_con_state_t *con, } } -static http2_client_child_con_state_t * -create_http2_stream(http2_client_con_state_t *con, line_t *child_line, hio_t *io) +static http2_client_child_con_state_t *createHttp2Stream(http2_client_con_state_t *con, line_t *child_line, hio_t *io) { - char authority_addr[320]; + char authority_addr[320]; nghttp2_nv nvs[15]; - int nvlen = 0; + int nvlen = 0; - nvs[nvlen++] = make_nv(":method", http_method_str(con->method)); - nvs[nvlen++] = make_nv(":path", con->path); - nvs[nvlen++] = make_nv(":scheme", con->scheme); + nvs[nvlen++] = makeNV(":method", httpMethodStr(con->method)); + nvs[nvlen++] = makeNV(":path", con->path); + nvs[nvlen++] = makeNV(":scheme", con->scheme); - if (con->host_port == 0 || - con->host_port == DEFAULT_kHTTP_PORT || - con->host_port == DEFAULT_HTTPS_PORT) + if (con->host_port == 0 || con->host_port == DEFAULT_HTTP_PORT || con->host_port == DEFAULT_HTTPS_PORT) { - nvs[nvlen++] = (make_nv(":authority", con->host)); + nvs[nvlen++] = (makeNV(":authority", con->host)); } else { snprintf(authority_addr, sizeof(authority_addr), "%s:%d", con->host, con->host_port); - nvs[nvlen++] = (make_nv(":authority", authority_addr)); + nvs[nvlen++] = (makeNV(":authority", authority_addr)); } // HTTP2_FLAG_END_STREAM; int flags = NGHTTP2_FLAG_END_HEADERS; - if (con->content_type == APPLICATION_GRPC) + if (con->content_type == kApplicationGrpc) { // flags = HTTP2_FLAG_NONE; - nvs[nvlen++] = (make_nv("content-type", "application/grpc+proto")); + nvs[nvlen++] = (makeNV("content-type", "application/grpc+proto")); } - // nvs[nvlen++] = make_nv("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7"); - // nvs[nvlen++] = make_nv("Accept-Language", "en,fa;q=0.9,zh-CN;q=0.8,zh;q=0.7"); - // nvs[nvlen++] = make_nv("Cache-Control", "no-cache"); - // nvs[nvlen++] = make_nv("Pragma", "no-cache"); - // nvs[nvlen++] = make_nv("Sec-Ch-Ua", "Chromium\";v=\"122\", Not(A:Brand\";v=\"24\", \"Google Chrome\";v=\"122\""); - nvs[nvlen++] = make_nv("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36"); - // nvs[nvlen++] = make_nv("Sec-Ch-Ua-Platform", "\"Windows\""); - - con->state = H2_SEND_HEADERS; + // nvs[nvlen++] = makeNV("Accept", + // "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7"); + // nvs[nvlen++] = makeNV("Accept-Language", "en,fa;q=0.9,zh-CN;q=0.8,zh;q=0.7"); + // nvs[nvlen++] = makeNV("Cache-Control", "no-cache"); + // nvs[nvlen++] = makeNV("Pragma", "no-cache"); + // nvs[nvlen++] = makeNV("Sec-Ch-Ua", "Chromium\";v=\"122\", Not(A:Brand\";v=\"24\", \"Google Chrome\";v=\"122\""); + nvs[nvlen++] = makeNV("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like " + "Gecko) Chrome/122.0.0.0 Safari/537.36"); + // nvs[nvlen++] = makeNV("Sec-Ch-Ua-Platform", "\"Windows\""); + + con->state = kH2SendHeaders; http2_client_child_con_state_t *stream = malloc(sizeof(http2_client_child_con_state_t)); memset(stream, 0, sizeof(http2_client_child_con_state_t)); // stream->stream_id = nghttp2_submit_request2(con->session, NULL, &nvs[0], nvlen, NULL,stream); stream->stream_id = nghttp2_submit_headers(con->session, flags, -1, NULL, &nvs[0], nvlen, stream); - stream->chunkbs = newBufferStream(buffer_pools[con->line->tid]); - stream->parent = con->line; - stream->line = child_line; - stream->io = io; - stream->tunnel = con->tunnel->dw; + stream->chunkbs = newBufferStream(getLineBufferPool(con->line)); + stream->parent = con->line; + stream->line = child_line; + stream->io = io; + stream->tunnel = con->tunnel->dw; stream->line->chains_state[stream->tunnel->chain_index + 1] = stream; - add_stream(con, stream); + addStraem(con, stream); // nghttp2_session_set_stream_user_data(con->session, stream->stream_id, stream); return stream; } -static void delete_http2_stream(http2_client_child_con_state_t *stream) +static void deleteHttp2Stream(http2_client_child_con_state_t *stream) { destroyBufferStream(stream->chunkbs); @@ -127,58 +118,60 @@ static void delete_http2_stream(http2_client_child_con_state_t *stream) free(stream); } -static http2_client_con_state_t *create_http2_connection(tunnel_t *self, int tid, hio_t *io) +static http2_client_con_state_t *createHttp2Connection(tunnel_t *self, int tid, hio_t *io) { - http2_client_state_t *state = STATE(self); - http2_client_con_state_t *con = malloc(sizeof(http2_client_con_state_t)); + http2_client_state_t * state = STATE(self); + http2_client_con_state_t *con = malloc(sizeof(http2_client_con_state_t)); memset(con, 0, sizeof(http2_client_con_state_t)); - con->queue = newContextQueue(buffer_pools[tid]); - con->content_type = state->content_type; - con->path = state->path; - con->host = state->host; - con->host_port = state->host_port; - con->scheme = state->scheme; - con->method = kHTTP_GET; - con->line = newLine(tid); - con->ping_timer = htimer_add(con->line->loop, on_ping_timer, PING_INTERVAL, INFINITE); - con->tunnel = self; - con->io = io; + con->queue = newContextQueue(buffer_pools[tid]); + con->content_type = state->content_type; + con->path = state->path; + con->host = state->host; + con->host_port = state->host_port; + con->scheme = state->scheme; + con->method = kHttpGet; + con->line = newLine(tid); + con->ping_timer = htimer_add(con->line->loop, onPingTimer, PING_INTERVAL, INFINITE); + con->tunnel = self; + con->io = io; con->line->chains_state[self->chain_index] = con; hevent_set_userdata(con->ping_timer, con); nghttp2_session_client_new2(&con->session, state->cbs, con, state->ngoptions); - nghttp2_settings_entry settings[] = { - {NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, MAX_CONCURRENT_STREAMS}}; + nghttp2_settings_entry settings[] = {{NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, MAX_CONCURRENT_STREAMS}}; nghttp2_submit_settings(con->session, NGHTTP2_FLAG_NONE, settings, ARRAY_SIZE(settings)); - con->state = H2_SEND_MAGIC; + con->state = kH2SendMagic; - if (state->content_type == APPLICATION_GRPC) + if (state->content_type == kApplicationGrpc) { - con->method = kHTTP_POST; + con->method = kHttpPost; } return con; } -static void delete_http2_connection(http2_client_con_state_t *con) +static void deleteHttp2Connection(http2_client_con_state_t *con) { - tunnel_t *self = con->tunnel; + tunnel_t * self = con->tunnel; + http2_client_state_t *state = STATE(self); - vec_cons *vector = &(STATE(self)->thread_cpool[con->line->tid].cons); - vec_cons_iter it = vec_cons_find(vector, con); + vec_cons * vector = &(state->thread_cpool[con->line->tid].cons); + vec_cons_iter it = vec_cons_find(vector, con); if (it.ref != vec_cons_end(vector).ref) + { vec_cons_erase_at(vector, it); + } http2_client_child_con_state_t *stream_i; for (stream_i = con->root.next; stream_i;) { - http2_client_child_con_state_t *next = stream_i->next; - context_t *fin_ctx = newFinContext(stream_i->line); - tunnel_t *dest = stream_i->tunnel; - delete_http2_stream(stream_i); + http2_client_child_con_state_t *next = stream_i->next; + context_t * fin_ctx = newFinContext(stream_i->line); + tunnel_t * dest = stream_i->tunnel; + deleteHttp2Stream(stream_i); CSTATE_MUT(fin_ctx) = NULL; dest->downStream(dest, fin_ctx); stream_i = next; @@ -191,11 +184,11 @@ static void delete_http2_connection(http2_client_con_state_t *con) free(con); } -static http2_client_con_state_t *take_http2_connection(tunnel_t *self, int tid, hio_t *io) +static http2_client_con_state_t *takeHttp2Connection(tunnel_t *self, int tid, hio_t *io) { http2_client_state_t *state = STATE(self); - // return create_http2_connection(self, tid, io); + // return createHttp2Connection(self, tid, io); vec_cons *vector = &(state->thread_cpool[tid].cons); if (vec_cons_size(vector) > 0) @@ -214,54 +207,54 @@ static http2_client_con_state_t *take_http2_connection(tunnel_t *self, int tid, if (con) { if (con->childs_added >= state->concurrency) + { vec_cons_pop(vector); + } return con; } - con = create_http2_connection(self, tid, io); - vec_cons_push(vector, con); - return con; - } - else - { - http2_client_con_state_t *con = create_http2_connection(self, tid, io); + con = createHttp2Connection(self, tid, io); vec_cons_push(vector, con); return con; } + + http2_client_con_state_t *con = createHttp2Connection(self, tid, io); + vec_cons_push(vector, con); + return con; } -static void on_ping_timer(htimer_t *timer) +static void onPingTimer(htimer_t *timer) { http2_client_con_state_t *con = hevent_userdata(timer); if (con->no_ping_ack) { LOGW("Http2Client: closing a session due to no ping reply"); - context_t *con_fc = newFinContext(con->line); - tunnel_t *con_dest = con->tunnel->up; - delete_http2_connection(con); + context_t *con_fc = newFinContext(con->line); + tunnel_t * con_dest = con->tunnel->up; + deleteHttp2Connection(con); con_dest->upStream(con_dest, con_fc); } else { con->no_ping_ack = true; - nghttp2_submit_ping(con->session,0,NULL); - char *data = NULL; + nghttp2_submit_ping(con->session, 0, NULL); + char * data = NULL; size_t len; - len = nghttp2_session_mem_send(con->session, (const uint8_t **)&data); + len = nghttp2_session_mem_send(con->session, (const uint8_t **) &data); if (len > 0) { - shift_buffer_t *send_buf = popBuffer(buffer_pools[con->line->tid]); + shift_buffer_t *send_buf = popBuffer(getLineBufferPool(con->line)); setLen(send_buf, len); writeRaw(send_buf, data, len); context_t *req = newContext(con->line); - req->payload = send_buf; - req->src_io = NULL; - if (!con->first_sent) + req->payload = send_buf; + req->src_io = NULL; + if (! con->first_sent) { con->first_sent = true; - req->first = true; + req->first = true; } - con->tunnel->up->upStream(con->tunnel->up, req); + con->tunnel->up->upStream(con->tunnel->up, req); } } } diff --git a/tunnels/client/http2/http2_client.c b/tunnels/client/http2/http2_client.c index fea5d553..f2162b95 100644 --- a/tunnels/client/http2/http2_client.c +++ b/tunnels/client/http2/http2_client.c @@ -1,48 +1,51 @@ #include "http2_client.h" -#include "types.h" #include "helpers.h" +#include "types.h" #define DEFAULT_CONCURRENCY 50 // 50 cons will be muxed into 1 static void sendGrpcFinalData(tunnel_t *self, line_t *line, size_t stream_id) { - http2_frame_hd framehd; + http2_frame_hd framehd; shift_buffer_t *buf = popBuffer(buffer_pools[line->tid]); setLen(buf, HTTP2_FRAME_HDLEN); - framehd.length = 0; - framehd.type = HTTP2_DATA; - framehd.flags = HTTP2_FLAG_END_STREAM; + framehd.length = 0; + framehd.type = kHttP2Data; + framehd.flags = kHttP2FlagEndStream; framehd.stream_id = stream_id; - http2_frame_hd_pack(&framehd, rawBufMut(buf)); + http2FrameHdPack(&framehd, rawBufMut(buf)); context_t *endstream_ctx = newContext(line); - endstream_ctx->payload = buf; + endstream_ctx->payload = buf; self->up->upStream(self->up, endstream_ctx); } -static bool trySendRequest(tunnel_t *self, http2_client_con_state_t *con, size_t stream_id, hio_t *stream_io, shift_buffer_t *buf) +static bool trySendRequest(tunnel_t *self, http2_client_con_state_t *con, size_t stream_id, hio_t *stream_io, + shift_buffer_t *buf) { line_t *line = con->line; if (con == NULL) + { return false; + } - char *data = NULL; + char * data = NULL; size_t len; - len = nghttp2_session_mem_send(con->session, (const uint8_t **)&data); + len = nghttp2_session_mem_send(con->session, (const uint8_t **) &data); // LOGD("nghttp2_session_mem_send %d\n", len); if (len > 0) { shift_buffer_t *send_buf = popBuffer(buffer_pools[line->tid]); - shiftl(send_buf, lCap(send_buf) / 1.25); // use some unused space + shiftl(send_buf, lCap(send_buf) / 2); // use some unused space setLen(send_buf, len); writeRaw(send_buf, data, len); context_t *req = newContext(line); - req->payload = send_buf; - req->src_io = stream_io; - if (!con->first_sent) + req->payload = send_buf; + req->src_io = stream_io; + if (! con->first_sent) { con->first_sent = true; - req->first = true; + req->first = true; } self->up->upStream(self->up, req); @@ -51,72 +54,73 @@ static bool trySendRequest(tunnel_t *self, http2_client_con_state_t *con, size_t assert(len >= 0); if (buf == NULL || bufLen(buf) <= 0) + { return false; - + } // HTTP2_DATA - if (con->state == H2_SEND_HEADERS) + if (con->state == kH2SendHeaders) { // http2_flag flags = HTTP2_FLAG_END_STREAM; - http2_flag flags = HTTP2_FLAG_NONE; + http2_flag flags = kHttP2FlagNone; // HTTP2 DATA framehd - con->state = H2_SEND_DATA; + con->state = kH2SendData; // LOGD("HTTP2 SEND_DATA_FRAME_HD...\n"); - if (con->content_type == APPLICATION_GRPC) + if (con->content_type == kApplicationGrpc) { grpc_message_hd msghd; - msghd.flags = 0; + msghd.flags = 0; msghd.length = bufLen(buf); // LOGD("grpc_message_hd: flags=%d length=%d\n", msghd.flags, msghd.length); // grpc server send grpc-status in HTTP2 header frame - flags = HTTP2_FLAG_NONE; + flags = kHttP2FlagNone; shiftl(buf, GRPC_MESSAGE_HDLEN); - grpc_message_hd_pack(&msghd, rawBufMut(buf)); + grpcMessageHdUnpack(&msghd, rawBufMut(buf)); } http2_frame_hd framehd; - framehd.length = bufLen(buf); - framehd.type = HTTP2_DATA; - framehd.flags = flags; + framehd.length = bufLen(buf); + framehd.type = kHttP2Data; + framehd.flags = flags; framehd.stream_id = stream_id; shiftl(buf, HTTP2_FRAME_HDLEN); - http2_frame_hd_pack(&framehd, rawBufMut(buf)); + http2FrameHdPack(&framehd, rawBufMut(buf)); context_t *req = newContext(line); - req->payload = buf; - req->src_io = stream_io; + req->payload = buf; + req->src_io = stream_io; self->up->upStream(self->up, req); goto send_done; } - else if (con->state == H2_SEND_DATA) + else if (con->state == kH2SendData) { - send_done: - con->state = H2_SEND_DONE; + send_done:; + con->state = kH2SendDone; } // LOGD("GetSendData %d\n", len); return false; } -static void flush_write_queue(http2_client_con_state_t *con) +static void flushWriteQueue(http2_client_con_state_t *con) { - tunnel_t *self = con->tunnel; - context_t *g = newContext(con->line); // keep the line alive + tunnel_t * self = con->tunnel; + context_t *g = newContext(con->line); // keep the line alive while (contextQueueLen(con->queue) > 0) { - context_t *stream_context = contextQueuePop(con->queue); - http2_client_child_con_state_t *stream = CSTATE(stream_context); - stream->io = stream_context->src_io; - con->state = H2_SEND_HEADERS; + context_t * stream_context = contextQueuePop(con->queue); + http2_client_child_con_state_t *stream = CSTATE(stream_context); + stream->io = stream_context->src_io; + con->state = kH2SendHeaders; // consumes payload while (trySendRequest(self, con, stream->stream_id, stream->io, stream_context->payload)) { - if (!ISALIVE(g)) + if (! isAlive(g->line)) { destroyContext(g); return; @@ -126,69 +130,76 @@ static void flush_write_queue(http2_client_con_state_t *con) destroyContext(g); } -static int on_header_callback(nghttp2_session *session, - const nghttp2_frame *frame, - const uint8_t *_name, size_t namelen, - const uint8_t *_value, size_t valuelen, - uint8_t flags, void *userdata) +static int onHeaderCallback(nghttp2_session *session, const nghttp2_frame *frame, const uint8_t *_name, size_t namelen, + const uint8_t *_value, size_t valuelen, uint8_t flags, void *userdata) { + (void) session; + (void) namelen; + (void) valuelen; + (void) flags; if (userdata == NULL) + { return 0; + } - // LOGD("on_header_callback\n"); - print_frame_hd(&frame->hd); - const char *name = (const char *)_name; - const char *value = (const char *)_value; + // LOGD("onHeaderCallback\n"); + printFrameHd(&frame->hd); + const char *name = (const char *) _name; + const char *value = (const char *) _value; // LOGD("%s: %s\n", name, value); - http2_client_con_state_t *con = (http2_client_con_state_t *)userdata; - tunnel_t *self = con->tunnel; - - if (*name == ':') - { - if (strcmp(name, ":method") == 0) - { - // req->method = http_method_enum(value); - } - else if (strcmp(name, ":path") == 0) - { - // req->url = value; - } - else if (strcmp(name, ":scheme") == 0) - { - // req->headers["Scheme"] = value; - } - else if (strcmp(name, ":authority") == 0) - { - // req->headers["Host"] = value; - } - } + http2_client_con_state_t *con = (http2_client_con_state_t *) userdata; + tunnel_t * self = con->tunnel; + + // Todo (http headers) should be saved somewhere + // if (*name == ':') + // { + // if (strcmp(name, ":method") == 0) + // { + // // req->method = http_method_enum(value); + // } + // else if (strcmp(name, ":path") == 0) + // { + // // req->url = value; + // } + // else if (strcmp(name, ":scheme") == 0) + // { + // // req->headers["Scheme"] = value; + // } + // else if (strcmp(name, ":authority") == 0) + // { + // // req->headers["Host"] = value; + // } + // } return 0; } -static int on_data_chunk_recv_callback(nghttp2_session *session, - uint8_t flags, int32_t stream_id, const uint8_t *data, - size_t len, void *userdata) +static int onDataChunkRecvCallback(nghttp2_session *session, uint8_t flags, int32_t stream_id, const uint8_t *data, + size_t len, void *userdata) { + (void) flags; if (userdata == NULL || len <= 0) + { return 0; - http2_client_con_state_t *con = (http2_client_con_state_t *)userdata; - tunnel_t *self = con->tunnel; + } + http2_client_con_state_t *con = (http2_client_con_state_t *) userdata; + tunnel_t * self = con->tunnel; - http2_client_child_con_state_t *stream = - nghttp2_session_get_stream_user_data(session, stream_id); - if (!stream) + http2_client_child_con_state_t *stream = nghttp2_session_get_stream_user_data(session, stream_id); + if (! stream) + { return 0; - // LOGD("on_data_chunk_recv_callback\n"); + } + // LOGD("onDataChunkRecvCallback\n"); // LOGD("stream_id=%d length=%d\n", stream_id, (int)len); // LOGD("down: %d\n", (int)len); - if (con->content_type == APPLICATION_GRPC) + if (con->content_type == kApplicationGrpc) { - shift_buffer_t *buf = popBuffer(buffer_pools[con->line->tid]); - shiftl(buf, lCap(buf) / 1.25); // use some unused space + shift_buffer_t *buf = popBuffer(getLineBufferPool(con->line)); + shiftl(buf, lCap(buf) / 2); // use some unused space setLen(buf, len); writeRaw(buf, data, len); bufferStreamPush(stream->chunkbs, buf); @@ -199,66 +210,69 @@ static int on_data_chunk_recv_callback(nghttp2_session *session, { shift_buffer_t *gheader_buf = bufferStreamRead(stream->chunkbs, GRPC_MESSAGE_HDLEN); grpc_message_hd msghd; - grpc_message_hd_unpack(&msghd, rawBuf(gheader_buf)); + grpcMessageHdUnpack(&msghd, rawBuf(gheader_buf)); stream->bytes_needed = msghd.length; - reuseBuffer(buffer_pools[con->line->tid], gheader_buf); + reuseBuffer(getLineBufferPool(con->line), gheader_buf); } if (stream->bytes_needed > 0 && bufferStreamLen(stream->chunkbs) >= stream->bytes_needed) { shift_buffer_t *gdata_buf = bufferStreamRead(stream->chunkbs, stream->bytes_needed); - stream->bytes_needed = 0; - context_t *stream_data = newContext(stream->line); - stream_data->payload = gdata_buf; - stream_data->src_io = con->io; + stream->bytes_needed = 0; + context_t *stream_data = newContext(stream->line); + stream_data->payload = gdata_buf; + stream_data->src_io = con->io; stream->tunnel->downStream(stream->tunnel, stream_data); if (nghttp2_session_get_stream_user_data(session, stream_id)) + { continue; + } } break; } } else { - shift_buffer_t *buf = popBuffer(buffer_pools[con->line->tid]); - shiftl(buf, lCap(buf) / 1.25); // use some unused space + shift_buffer_t *buf = popBuffer(getLineBufferPool(con->line)); + shiftl(buf, lCap(buf) / 2); // use some unused space setLen(buf, len); writeRaw(buf, data, len); context_t *stream_data = newContext(stream->line); - stream_data->payload = buf; - stream_data->src_io = con->io; + stream_data->payload = buf; + stream_data->src_io = con->io; stream->tunnel->downStream(stream->tunnel, stream_data); } return 0; } -static int on_frame_recv_callback(nghttp2_session *session, - const nghttp2_frame *frame, void *userdata) +static int onFrameRecvCallback(nghttp2_session *session, const nghttp2_frame *frame, void *userdata) { if (userdata == NULL) + { return 0; + } - // LOGD("on_frame_recv_callback\n"); - print_frame_hd(&frame->hd); - http2_client_con_state_t *con = (http2_client_con_state_t *)userdata; - tunnel_t *self = con->tunnel; + // LOGD("onFrameRecvCallback\n"); + printFrameHd(&frame->hd); + http2_client_con_state_t *con = (http2_client_con_state_t *) userdata; + tunnel_t * self = con->tunnel; switch (frame->hd.type) { case NGHTTP2_DATA: - con->state = H2_RECV_DATA; + con->state = kH2RecvData; break; case NGHTTP2_HEADERS: - con->state = H2_RECV_HEADERS; + con->state = kH2RecvHeaders; break; case NGHTTP2_SETTINGS: - con->state = H2_RECV_SETTINGS; + con->state = kH2RecvSettings; break; case NGHTTP2_PING: // LOGW("Http2Client: GOT PING"); con->no_ping_ack = false; - con->state = H2_RECV_PING; + con->state = kH2RecvPing; break; case NGHTTP2_RST_STREAM: case NGHTTP2_WINDOW_UPDATE: @@ -267,17 +281,18 @@ static int on_frame_recv_callback(nghttp2_session *session, default: break; } - if ((frame->hd.flags & HTTP2_FLAG_END_STREAM) == HTTP2_FLAG_END_STREAM) + if (frame->hd.flags & kHttP2FlagEndStream) { - http2_client_child_con_state_t *stream = - nghttp2_session_get_stream_user_data(session, frame->hd.stream_id); - if (!stream) + http2_client_child_con_state_t *stream = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id); + if (! stream) + { return 0; + } nghttp2_session_set_stream_user_data(con->session, stream->stream_id, NULL); - context_t *fc = newFinContext(stream->line); - tunnel_t *dest = stream->tunnel; - remove_stream(con, stream); - delete_http2_stream(stream); + context_t *fc = newFinContext(stream->line); + tunnel_t * dest = stream->tunnel; + removeStream(con, stream); + deleteHttp2Stream(stream); CSTATE_MUT(fc) = NULL; dest->downStream(dest, fc); @@ -289,9 +304,10 @@ static int on_frame_recv_callback(nghttp2_session *session, { if (frame->headers.cat == NGHTTP2_HCAT_RESPONSE) { - http2_client_child_con_state_t *stream = nghttp2_session_get_stream_user_data(con->session, frame->hd.stream_id); + http2_client_child_con_state_t *stream = + nghttp2_session_get_stream_user_data(con->session, frame->hd.stream_id); con->handshake_completed = true; - flush_write_queue(con); + flushWriteQueue(con); stream->tunnel->downStream(stream->tunnel, newEstContext(stream->line)); } } @@ -306,23 +322,25 @@ static inline void upStream(tunnel_t *self, context_t *c) if (c->payload != NULL) { http2_client_child_con_state_t *stream = CSTATE(c); - http2_client_con_state_t *con = stream->parent->chains_state[self->chain_index]; - stream->io = c->src_io; + http2_client_con_state_t * con = stream->parent->chains_state[self->chain_index]; + stream->io = c->src_io; - if (!con->handshake_completed) + if (! con->handshake_completed) { contextQueuePush(con->queue, c); return; } - con->state = H2_SEND_HEADERS; + con->state = kH2SendHeaders; // consumes payload while (trySendRequest(self, con, stream->stream_id, stream->io, c->payload)) - if (!isAlive(c->line)) + { + if (! isAlive(c->line)) { destroyContext(c); return; } + } c->payload = NULL; destroyContext(c); } @@ -330,16 +348,16 @@ static inline void upStream(tunnel_t *self, context_t *c) { if (c->init) { - http2_client_con_state_t *con = take_http2_connection(self, c->line->tid, NULL); - http2_client_child_con_state_t *stream = create_http2_stream(con, c->line, c->src_io); - CSTATE_MUT(c) = stream; + http2_client_con_state_t * con = takeHttp2Connection(self, c->line->tid, NULL); + http2_client_child_con_state_t *stream = createHttp2Stream(con, c->line, c->src_io); + CSTATE_MUT(c) = stream; nghttp2_session_set_stream_user_data(con->session, stream->stream_id, stream); - if (!con->init_sent) + if (! con->init_sent) { con->init_sent = true; self->up->upStream(self->up, newInitContext(con->line)); - if (!isAlive(c->line)) + if (! isAlive(c->line)) { destroyContext(c); return; @@ -347,33 +365,33 @@ static inline void upStream(tunnel_t *self, context_t *c) } while (trySendRequest(self, con, 0, NULL, NULL)) - if (!isAlive(c->line)) + { if (! isAlive(c->line)) { destroyContext(c); return; } - +} destroyContext(c); } else if (c->fin) { http2_client_child_con_state_t *stream = CSTATE(c); - http2_client_con_state_t *con = stream->parent->chains_state[self->chain_index]; - if (con->content_type == APPLICATION_GRPC) + http2_client_con_state_t * con = stream->parent->chains_state[self->chain_index]; + if (con->content_type == kApplicationGrpc) { sendGrpcFinalData(self, con->line, stream->stream_id); } nghttp2_session_set_stream_user_data(con->session, stream->stream_id, NULL); - remove_stream(con, stream); + removeStream(con, stream); if (con->root.next == NULL && con->childs_added >= state->concurrency && isAlive(c->line)) { - context_t *con_fc = newFinContext(con->line); - tunnel_t *con_dest = con->tunnel->up; - delete_http2_connection(con); + context_t *con_fc = newFinContext(con->line); + tunnel_t * con_dest = con->tunnel->up; + deleteHttp2Connection(con); con_dest->upStream(con_dest, con_fc); } - delete_http2_stream(stream); + deleteHttp2Stream(stream); CSTATE_MUT(c) = NULL; destroyContext(c); @@ -384,20 +402,20 @@ static inline void upStream(tunnel_t *self, context_t *c) static inline void downStream(tunnel_t *self, context_t *c) { - http2_client_state_t *state = STATE(self); - http2_client_con_state_t *con = CSTATE(c); - con->io = c->src_io; + http2_client_state_t * state = STATE(self); + http2_client_con_state_t *con = CSTATE(c); + con->io = c->src_io; if (c->payload != NULL) { - con->state = H2_WANT_RECV; + con->state = kH2WantRecv; size_t len = bufLen(c->payload); - size_t ret = nghttp2_session_mem_recv2(con->session, (const uint8_t *)rawBuf(c->payload), len); + size_t ret = nghttp2_session_mem_recv2(con->session, (const uint8_t *) rawBuf(c->payload), len); assert(ret == len); reuseContextBuffer(c); - if (!isAlive(c->line)) + if (! isAlive(c->line)) { destroyContext(c); return; @@ -405,24 +423,26 @@ static inline void downStream(tunnel_t *self, context_t *c) if (ret != len) { - delete_http2_connection(con); + deleteHttp2Connection(con); self->dw->downStream(self->dw, newFinContext(c->line)); destroyContext(c); return; } while (trySendRequest(self, con, 0, NULL, NULL)) - if (!isAlive(c->line)) + { + if (! isAlive(c->line)) { destroyContext(c); return; } + } if (con->root.next == NULL && con->childs_added >= state->concurrency && isAlive(c->line)) { - context_t *con_fc = newFinContext(con->line); - tunnel_t *con_dest = con->tunnel->up; - delete_http2_connection(con); + context_t *con_fc = newFinContext(con->line); + tunnel_t * con_dest = con->tunnel->up; + deleteHttp2Connection(con); con_dest->upStream(con_dest, con_fc); } @@ -433,37 +453,38 @@ static inline void downStream(tunnel_t *self, context_t *c) if (c->fin) { - delete_http2_connection(con); + deleteHttp2Connection(con); } destroyContext(c); } } - + tunnel_t *newHttp2Client(node_instance_context_t *instance_info) { - http2_client_state_t *state = malloc(sizeof(http2_client_state_t) + (workers_count * sizeof(thread_connection_pool_t))); + http2_client_state_t *state = + malloc(sizeof(http2_client_state_t) + (workers_count * sizeof(thread_connection_pool_t))); memset(state, 0, sizeof(http2_client_state_t)); cJSON *settings = instance_info->node_settings_json; nghttp2_session_callbacks_new(&(state->cbs)); - nghttp2_session_callbacks_set_on_header_callback(state->cbs, on_header_callback); - nghttp2_session_callbacks_set_on_data_chunk_recv_callback(state->cbs, on_data_chunk_recv_callback); - nghttp2_session_callbacks_set_on_frame_recv_callback(state->cbs, on_frame_recv_callback); + nghttp2_session_callbacks_set_on_header_callback(state->cbs, onHeaderCallback); + nghttp2_session_callbacks_set_on_data_chunk_recv_callback(state->cbs, onDataChunkRecvCallback); + nghttp2_session_callbacks_set_on_frame_recv_callback(state->cbs, onFrameRecvCallback); for (size_t i = 0; i < workers_count; i++) { state->thread_cpool[i] = (thread_connection_pool_t){.round_index = 0, .cons = vec_cons_with_capacity(8)}; } - if (!getStringFromJsonObject(&(state->host), settings, "host")) + if (! getStringFromJsonObject(&(state->host), settings, "host")) { LOGF("JSON Error: Http2Client->settings->host (string field) : The data was empty or invalid"); return NULL; } getStringFromJsonObjectOrDefault(&(state->path), settings, "path", "/"); - if (!getIntFromJsonObject(&(state->host_port), settings, "port")) + if (! getIntFromJsonObject(&(state->host_port), settings, "port")) { LOGF("JSON Error: Http2Client->settings->port (number field) : The data was empty or invalid"); return NULL; @@ -474,33 +495,36 @@ tunnel_t *newHttp2Client(node_instance_context_t *instance_info) char *content_type_buf = NULL; if (getStringFromJsonObject(&content_type_buf, settings, "content-type")) { - state->content_type = http_content_type_enum(content_type_buf); + state->content_type = httpContentTypeEnum(content_type_buf); free(content_type_buf); } getIntFromJsonObjectOrDefault(&(state->concurrency), settings, "concurrency", DEFAULT_CONCURRENCY); nghttp2_option_new(&(state->ngoptions)); - nghttp2_option_set_peer_max_concurrent_streams(state->ngoptions, 0xffffffffu); + nghttp2_option_set_peer_max_concurrent_streams(state->ngoptions, 0xffffffffU); nghttp2_option_set_no_closed_streams(state->ngoptions, 1); nghttp2_option_set_no_http_messaging(state->ngoptions, 1); // nghttp2_option_set_no_http_messaging use this with grpc? - tunnel_t *t = newTunnel(); - t->state = state; - t->upStream = &upStream; - t->downStream = &downStream; + tunnel_t *t = newTunnel(); + t->state = state; + t->upStream = &upStream; + t->downStream = &downStream; atomic_thread_fence(memory_order_release); return t; } -api_result_t apiHttp2Client(tunnel_t *self, char *msg) +api_result_t apiHttp2Client(tunnel_t *self, const char *msg) { - (void)(self); (void)(msg); return (api_result_t){0}; + (void) (self); + (void) (msg); + return (api_result_t){0}; } tunnel_t *destroyHttp2Client(tunnel_t *self) { + (void) (self); return NULL; } diff --git a/tunnels/client/http2/http2_client.h b/tunnels/client/http2/http2_client.h index 76f0a1d0..45b236e6 100644 --- a/tunnels/client/http2/http2_client.h +++ b/tunnels/client/http2/http2_client.h @@ -1,15 +1,11 @@ #pragma once #include "api.h" -// +// // con <------> http2-client <------> http2 stream (con) -// // -tunnel_t *newHttp2Client(node_instance_context_t *instance_info); -api_result_t apiHttp2Client(tunnel_t *self, char *msg); -tunnel_t *destroyHttp2Client(tunnel_t *self); +tunnel_t * newHttp2Client(node_instance_context_t *instance_info); +api_result_t apiHttp2Client(tunnel_t *self,const char *msg); +tunnel_t * destroyHttp2Client(tunnel_t *self); tunnel_metadata_t getMetadataHttp2Client(); - - - diff --git a/tunnels/client/http2/types.h b/tunnels/client/http2/types.h index 2a2457a3..b0212182 100644 --- a/tunnels/client/http2/types.h +++ b/tunnels/client/http2/types.h @@ -1,11 +1,11 @@ #pragma once #include "api.h" -#include "nghttp2/nghttp2.h" #include "buffer_stream.h" -#include "http_def.h" -#include "http2_def.h" #include "grpc_def.h" +#include "http2_def.h" +#include "http_def.h" #include "loggers/network_logger.h" +#include "nghttp2/nghttp2.h" typedef enum { @@ -16,10 +16,8 @@ typedef enum kH2SendDataFrameHd, kH2SendData, kH2SendDone, - kH2WantSend, kH2WantRecv, - kH2RecvSettings, kH2RecvPing, kH2RecvHeaders, @@ -29,68 +27,65 @@ typedef enum typedef struct http2_client_child_con_state_s { struct http2_client_child_con_state_s *prev, *next; - int32_t stream_id; - nghttp2_stream *ng_stream; - - buffer_stream_t *chunkbs; //used for grpc - size_t bytes_needed; - - tunnel_t *tunnel; - line_t *parent; - line_t *line; - hio_t *io; + int32_t stream_id; + nghttp2_stream * ng_stream; + buffer_stream_t * chunkbs; // used for grpc + size_t bytes_needed; + tunnel_t * tunnel; + line_t * parent; + line_t * line; + hio_t * io; } http2_client_child_con_state_t; typedef struct http2_client_con_state_s { - nghttp2_session *session; - http2_session_state state; - context_queue_t *queue; - size_t childs_added; - int error; - int frame_type_when_stream_closed; - bool handshake_completed; - - enum http_method method; - enum http_content_type content_type; - const char *path; - const char *host; // authority - int host_port; - const char *scheme; - bool init_sent; - bool first_sent; - bool no_ping_ack; - htimer_t* ping_timer; - tunnel_t *tunnel; - line_t *line; - hio_t *io; + nghttp2_session * session; + http2_session_state state; + context_queue_t * queue; + size_t childs_added; + int error; + int frame_type_when_stream_closed; + bool handshake_completed; + enum http_method method; + enum http_content_type content_type; + const char * path; + const char * host; // authority + int host_port; + const char * scheme; + bool init_sent; + bool first_sent; + bool no_ping_ack; + htimer_t * ping_timer; + tunnel_t * tunnel; + line_t * line; + hio_t * io; http2_client_child_con_state_t root; } http2_client_con_state_t; -#define i_type vec_cons //NOLINT -#define i_key http2_client_con_state_t * //NOLINT -#define i_use_cmp //NOLINT +#define i_type vec_cons // NOLINT +#define i_key http2_client_con_state_t * // NOLINT +#define i_use_cmp // NOLINT #include "stc/vec.h" typedef struct thread_connection_pool_s { - size_t round_index; + size_t round_index; vec_cons cons; } thread_connection_pool_t; typedef struct http2_client_state_s { nghttp2_session_callbacks *cbs; - enum http_content_type content_type; - int concurrency; - char *path; - char *host; // authority - int host_port; - char *scheme; - int last_iid; - nghttp2_option *ngoptions; - thread_connection_pool_t thread_cpool[]; + enum http_content_type content_type; + int concurrency; + char * path; + char * host; // authority + int host_port; + char * scheme; + int last_iid; + nghttp2_option * ngoptions; + thread_connection_pool_t thread_cpool[]; } http2_client_state_t; diff --git a/tunnels/client/openssl/openssl_client.c b/tunnels/client/openssl/openssl_client.c index 9e4760aa..5ef60e4d 100644 --- a/tunnels/client/openssl/openssl_client.c +++ b/tunnels/client/openssl/openssl_client.c @@ -1,20 +1,15 @@ #include "openssl_client.h" #include "buffer_pool.h" #include "buffer_stream.h" -#include "managers/node_manager.h" #include "loggers/network_logger.h" -#include "utils/jsonutils.h" +#include "managers/node_manager.h" #include "openssl_globals.h" +#include "utils/jsonutils.h" #include #include #include #include -#define STATE(x) ((oss_client_state_t *)((x)->state)) -#define CSTATE(x) ((oss_client_con_state_t *)((((x)->line->chains_state)[self->chain_index]))) -#define CSTATE_MUT(x) ((x)->line->chains_state)[self->chain_index] -#define ISALIVE(x) (CSTATE(x) != NULL) - typedef struct oss_client_state_s { @@ -22,40 +17,39 @@ typedef struct oss_client_state_s // settings char *alpn; char *sni; - bool verify; + bool verify; } oss_client_state_t; typedef struct oss_client_con_state_s { - bool handshake_completed; - SSL *ssl; - BIO *rbio; - BIO *wbio; + bool handshake_completed; + SSL * ssl; + BIO * rbio; + BIO * wbio; context_queue_t *queue; } oss_client_con_state_t; enum sslstatus { - SSLSTATUS_OK, - SSLSTATUS_WANT_IO, - SSLSTATUS_FAIL + kSslstatusOk, + kSslstatusWantIo, + kSslstatusFail }; - -static enum sslstatus get_sslstatus(SSL *ssl, int n) +static enum sslstatus getSslStatus(SSL *ssl, int n) { switch (SSL_get_error(ssl, n)) { case SSL_ERROR_NONE: - return SSLSTATUS_OK; + return kSslstatusOk; case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_READ: - return SSLSTATUS_WANT_IO; + return kSslstatusWantIo; case SSL_ERROR_ZERO_RETURN: case SSL_ERROR_SYSCALL: default: - return SSLSTATUS_FAIL; + return kSslstatusFail; } } @@ -72,7 +66,7 @@ static void cleanup(tunnel_t *self, context_t *c) } } -static void flush_write_queue(tunnel_t *self, context_t *c) +static void flushWriteQueue(tunnel_t *self, context_t *c) { oss_client_con_state_t *cstate = CSTATE(c); @@ -80,8 +74,10 @@ static void flush_write_queue(tunnel_t *self, context_t *c) { self->upStream(self, contextQueuePop(cstate->queue)); - if (!isAlive(c->line)) + if (! isAlive(c->line)) + { return; + } } } @@ -93,19 +89,19 @@ static inline void upStream(tunnel_t *self, context_t *c) { oss_client_con_state_t *cstate = CSTATE(c); - if (!cstate->handshake_completed) + if (! cstate->handshake_completed) { contextQueuePush(cstate->queue, c); return; } enum sslstatus status; - size_t len = bufLen(c->payload); + size_t len = bufLen(c->payload); while (len > 0) { - int n = SSL_write(cstate->ssl, rawBuf(c->payload), len); - status = get_sslstatus(cstate->ssl, n); + int n = SSL_write(cstate->ssl, rawBuf(c->payload), len); + status = getSslStatus(cstate->ssl, n); if (n > 0) { @@ -115,44 +111,46 @@ static inline void upStream(tunnel_t *self, context_t *c) /* take the output of the SSL object and queue it for socket write */ do { - shift_buffer_t *buf = popBuffer(buffer_pools[c->line->tid]); - size_t avail = rCap(buf); - n = BIO_read(cstate->wbio, rawBufMut(buf), avail); + shift_buffer_t *buf = popBuffer(getContextBufferPool(c)); + size_t avail = rCap(buf); + n = BIO_read(cstate->wbio, rawBufMut(buf), avail); if (n > 0) { setLen(buf, n); context_t *send_context = newContextFrom(c); - send_context->payload = buf; + send_context->payload = buf; self->up->upStream(self->up, send_context); - if (!isAlive(c->line)) + if (! isAlive(c->line)) { reuseContextBuffer(c); destroyContext(c); return; } } - else if (!BIO_should_retry(cstate->wbio)) + else if (! BIO_should_retry(cstate->wbio)) { // If BIO_should_retry() is false then the cause is an error condition. - reuseBuffer(buffer_pools[c->line->tid], buf); + reuseBuffer(getContextBufferPool(c), buf); reuseContextBuffer(c); goto failed; } else { - reuseBuffer(buffer_pools[c->line->tid], buf); + reuseBuffer(getContextBufferPool(c), buf); } } while (n > 0); } - if (status == SSLSTATUS_FAIL) + if (status == kSslstatusFail) { reuseContextBuffer(c); goto failed; } if (n == 0) + { break; + } } assert(bufLen(c->payload) == 0); reuseContextBuffer(c); @@ -166,52 +164,53 @@ static inline void upStream(tunnel_t *self, context_t *c) CSTATE_MUT(c) = malloc(sizeof(oss_client_con_state_t)); memset(CSTATE(c), 0, sizeof(oss_client_con_state_t)); oss_client_con_state_t *cstate = CSTATE(c); - cstate->rbio = BIO_new(BIO_s_mem()); - cstate->wbio = BIO_new(BIO_s_mem()); - cstate->ssl = SSL_new(state->ssl_context); - cstate->queue = newContextQueue(buffer_pools[c->line->tid]); + cstate->rbio = BIO_new(BIO_s_mem()); + cstate->wbio = BIO_new(BIO_s_mem()); + cstate->ssl = SSL_new(state->ssl_context); + cstate->queue = newContextQueue(getContextBufferPool(c)); SSL_set_connect_state(cstate->ssl); /* sets ssl to work in client mode. */ SSL_set_bio(cstate->ssl, cstate->rbio, cstate->wbio); SSL_set_tlsext_host_name(cstate->ssl, state->sni); - context_t *clienthello_ctx = newContextFrom(c); + context_t *client_hello_ctx = newContextFrom(c); self->up->upStream(self->up, c); - if (!ISALIVE(clienthello_ctx)) + if (! isAlive(client_hello_ctx->line)) { - destroyContext(clienthello_ctx); + destroyContext(client_hello_ctx); return; } // printSSLState(cstate->ssl); int n = SSL_connect(cstate->ssl); // printSSLState(cstate->ssl); - enum sslstatus status = get_sslstatus(cstate->ssl, n); + enum sslstatus status = getSslStatus(cstate->ssl, n); /* Did SSL request to write bytes? */ - if (status == SSLSTATUS_WANT_IO) + if (status == kSslstatusWantIo) { - shift_buffer_t *buf = popBuffer(buffer_pools[clienthello_ctx->line->tid]); - size_t avail = rCap(buf); - n = BIO_read(cstate->wbio, rawBufMut(buf), avail); + shift_buffer_t *buf = popBuffer(getContextBufferPool(client_hello_ctx)); + size_t avail = rCap(buf); + n = BIO_read(cstate->wbio, rawBufMut(buf), avail); if (n > 0) { setLen(buf, n); - clienthello_ctx->payload = buf; - clienthello_ctx->first = true; - self->up->upStream(self->up, clienthello_ctx); - + client_hello_ctx->payload = buf; + client_hello_ctx->first = true; + self->up->upStream(self->up, client_hello_ctx); } - else if (!BIO_should_retry(cstate->rbio)) + else if (! BIO_should_retry(cstate->rbio)) { // If BIO_should_retry() is false then the cause is an error condition. - reuseBuffer(buffer_pools[clienthello_ctx->line->tid], buf); + reuseBuffer(getContextBufferPool(client_hello_ctx), buf); goto failed; } else { - reuseBuffer(buffer_pools[clienthello_ctx->line->tid], buf); + reuseBuffer(getContextBufferPool(client_hello_ctx), buf); } } - if (status == SSLSTATUS_FAIL) + if (status == kSslstatusFail) + { goto failed; + } } else if (c->fin) { @@ -225,14 +224,13 @@ static inline void upStream(tunnel_t *self, context_t *c) failed:; context_t *fail_context_up = newFinContext(c->line); - fail_context_up->src_io = c->src_io; + fail_context_up->src_io = c->src_io; self->up->upStream(self->up, fail_context_up); context_t *fail_context = newFinContext(c->line); cleanup(self, c); destroyContext(c); self->dw->downStream(self->dw, fail_context); - return; } static inline void downStream(tunnel_t *self, context_t *c) @@ -241,7 +239,7 @@ static inline void downStream(tunnel_t *self, context_t *c) if (c->payload != NULL) { - int n; + int n; enum sslstatus status; // if (!cstate->handshake_completed) @@ -260,72 +258,73 @@ static inline void downStream(tunnel_t *self, context_t *c) shiftr(c->payload, n); len -= n; - if (!cstate->handshake_completed) + if (! cstate->handshake_completed) { // printSSLState(cstate->ssl); n = SSL_connect(cstate->ssl); // printSSLState(cstate->ssl); - status = get_sslstatus(cstate->ssl, n); + status = getSslStatus(cstate->ssl, n); /* Did SSL request to write bytes? */ - if (status == SSLSTATUS_WANT_IO) + if (status == kSslstatusWantIo) + { do { - shift_buffer_t *buf = popBuffer(buffer_pools[c->line->tid]); - size_t avail = rCap(buf); - n = BIO_read(cstate->wbio, rawBufMut(buf), avail); + shift_buffer_t *buf = popBuffer(getContextBufferPool(c)); + size_t avail = rCap(buf); + n = BIO_read(cstate->wbio, rawBufMut(buf), avail); if (n > 0) { setLen(buf, n); context_t *req_cont = newContextFrom(c); - req_cont->payload = buf; + req_cont->payload = buf; self->up->upStream(self->up, req_cont); - if (!isAlive(c->line)) + if (! isAlive(c->line)) { reuseContextBuffer(c); destroyContext(c); return; } } - else if (!BIO_should_retry(cstate->rbio)) + else if (! BIO_should_retry(cstate->rbio)) { // If BIO_should_retry() is false then the cause is an error condition. reuseContextBuffer(c); - reuseBuffer(buffer_pools[c->line->tid], buf); + reuseBuffer(getContextBufferPool(c), buf); goto failed; } else { - reuseBuffer(buffer_pools[c->line->tid], buf); + reuseBuffer(getContextBufferPool(c), buf); } } while (n > 0); - - if (status == SSLSTATUS_FAIL) + } + if (status == kSslstatusFail) { - int x = SSL_get_verify_result(cstate->ssl); + SSL_get_verify_result(cstate->ssl); printSSLError(); reuseContextBuffer(c); goto failed; } /* Did SSL request to write bytes? */ - shift_buffer_t *buf = popBuffer(buffer_pools[c->line->tid]); - size_t avail = rCap(buf); - n = BIO_read(cstate->wbio, rawBufMut(buf), avail); + shift_buffer_t *buf = popBuffer(getContextBufferPool(c)); + size_t avail = rCap(buf); + n = BIO_read(cstate->wbio, rawBufMut(buf), avail); if (n > 0) { setLen(buf, n); context_t *data_ctx = newContext(c->line); - data_ctx->payload = buf; + data_ctx->payload = buf; self->up->upStream(self->up, data_ctx); } else { - reuseBuffer(buffer_pools[c->line->tid], buf); + reuseBuffer(getContextBufferPool(c), buf); } - if (!SSL_is_init_finished(cstate->ssl)) + if (! SSL_is_init_finished(cstate->ssl)) { // reuseContextBuffer(c); // destroyContext(c); @@ -335,17 +334,17 @@ static inline void downStream(tunnel_t *self, context_t *c) { LOGD("OpensslClient: Tls handshake complete"); cstate->handshake_completed = true; - context_t *dw_est_ctx = newContextFrom(c); - dw_est_ctx->est = true; + context_t *dw_est_ctx = newContextFrom(c); + dw_est_ctx->est = true; self->dw->downStream(self->dw, dw_est_ctx); - if (!isAlive(c->line)) + if (! isAlive(c->line)) { LOGW("OpensslClient: prev node instantly closed the est with fin"); reuseContextBuffer(c); destroyContext(c); return; } - flush_write_queue(self, c); + flushWriteQueue(self, c); // queue is flushed and we are done // reuseContextBuffer(c); // destroyContext(c); @@ -359,25 +358,25 @@ static inline void downStream(tunnel_t *self, context_t *c) /* The encrypted data is now in the input bio so now we can perform actual * read of unencrypted data. */ - // shift_buffer_t *buf = popBuffer(buffer_pools[c->line->tid]); + // shift_buffer_t *buf = popBuffer(getContextBufferPool(c)); // shiftl(buf, 8192 / 2); // setLen(buf, 0); do { - shift_buffer_t *buf = popBuffer(buffer_pools[c->line->tid]); + shift_buffer_t *buf = popBuffer(getContextBufferPool(c)); shiftl(buf, 8192 / 2); setLen(buf, 0); size_t avail = rCap(buf); - n = SSL_read(cstate->ssl, rawBufMut(buf), avail); + n = SSL_read(cstate->ssl, rawBufMut(buf), avail); if (n > 0) { setLen(buf, n); context_t *data_ctx = newContextFrom(c); - data_ctx->payload = buf; + data_ctx->payload = buf; self->dw->downStream(self->dw, data_ctx); - if (!isAlive(c->line)) + if (! isAlive(c->line)) { reuseContextBuffer(c); destroyContext(c); @@ -386,14 +385,14 @@ static inline void downStream(tunnel_t *self, context_t *c) } else { - reuseBuffer(buffer_pools[c->line->tid], buf); + reuseBuffer(getContextBufferPool(c), buf); } } while (n > 0); - status = get_sslstatus(cstate->ssl, n); + status = getSslStatus(cstate->ssl, n); - if (status == SSLSTATUS_FAIL) + if (status == kSslstatusFail) { reuseContextBuffer(c); goto failed; @@ -411,7 +410,9 @@ static inline void downStream(tunnel_t *self, context_t *c) self->dw->downStream(self->dw, c); } else + { destroyContext(c); + } } return; @@ -424,12 +425,8 @@ failed:; cleanup(self, c); destroyContext(c); self->dw->downStream(self->dw, fail_context); - - return; } - - tunnel_t *newOpenSSLClient(node_instance_context_t *instance_info) { oss_client_state_t *state = malloc(sizeof(oss_client_state_t)); @@ -439,13 +436,13 @@ tunnel_t *newOpenSSLClient(node_instance_context_t *instance_info) memset(ssl_param, 0, sizeof(ssl_ctx_opt_t)); const cJSON *settings = instance_info->node_settings_json; - if (!(cJSON_IsObject(settings) && settings->child != NULL)) + if (! (cJSON_IsObject(settings) && settings->child != NULL)) { LOGF("JSON Error: OpenSSLClient->settings (object field) : The object was empty or invalid"); return NULL; } - if (!getStringFromJsonObject(&(state->sni), settings, "sni")) + if (! getStringFromJsonObject(&(state->sni), settings, "sni")) { LOGF("JSON Error: OpenSSLClient->settings->sni (string field) : The data was empty or invalid"); return NULL; @@ -456,12 +453,12 @@ tunnel_t *newOpenSSLClient(node_instance_context_t *instance_info) return NULL; } - if (!getBoolFromJsonObject(&(state->verify), settings, "verify")) + if (! getBoolFromJsonObject(&(state->verify), settings, "verify")) { state->verify = true; } - if (!getStringFromJsonObject((char **)&(state->alpn), settings, "alpn")) + if (! getStringFromJsonObject(&(state->alpn), settings, "alpn")) { LOGF("JSON Error: OpenSSLClient->settings->alpn (string field) : The data was empty or invalid"); return NULL; @@ -473,9 +470,9 @@ tunnel_t *newOpenSSLClient(node_instance_context_t *instance_info) } ssl_param->verify_peer = state->verify ? 1 : 0; - ssl_param->endpoint = SSL_CLIENT; + ssl_param->endpoint = kSslClient; // ssl_param->ca_path = "cacert.pem"; - state->ssl_context = ssl_ctx_new(ssl_param); + state->ssl_context = sslCtxNew(ssl_param); free(ssl_param); // SSL_CTX_load_verify_store(state->ssl_context,cacert_bytes); @@ -489,28 +486,31 @@ tunnel_t *newOpenSSLClient(node_instance_context_t *instance_info) struct { uint8_t len; - char alpn_data[]; - } *ossl_alpn = malloc(1 + alpn_len); + char alpn_data[]; + } *ossl_alpn = malloc(1 + alpn_len); ossl_alpn->len = alpn_len; memcpy(&(ossl_alpn->alpn_data[0]), state->alpn, alpn_len); - SSL_CTX_set_alpn_protos(state->ssl_context, (const unsigned char *)ossl_alpn, 1 + alpn_len); + SSL_CTX_set_alpn_protos(state->ssl_context, (const unsigned char *) ossl_alpn, 1 + alpn_len); free(ossl_alpn); - tunnel_t *t = newTunnel(); - t->state = state; - t->upStream = &upStream; - t->downStream = &downStream; + tunnel_t *t = newTunnel(); + t->state = state; + t->upStream = &upStream; + t->downStream = &downStream; atomic_thread_fence(memory_order_release); return t; } -api_result_t apiOpenSSLClient(tunnel_t *self, char *msg) +api_result_t apiOpenSSLClient(tunnel_t *self, const char *msg) { - (void)(self); (void)(msg); return (api_result_t){0}; // TODO + (void) (self); + (void) (msg); + return (api_result_t){0}; // TODO(root): } tunnel_t *destroyOpenSSLClient(tunnel_t *self) { + (void) (self); return NULL; } diff --git a/tunnels/client/openssl/openssl_client.h b/tunnels/client/openssl/openssl_client.h index 10251780..0304f3e2 100644 --- a/tunnels/client/openssl/openssl_client.h +++ b/tunnels/client/openssl/openssl_client.h @@ -1,12 +1,11 @@ #pragma once #include "api.h" -// -// con <------> OpenSSL-server <------> TLS(con) -// +// +// con <------> OpenSSL-client <------> TLS(con) // -tunnel_t *newOpenSSLClient(node_instance_context_t *instance_info); -api_result_t apiOpenSSLClient(tunnel_t *self, char *msg); -tunnel_t *destroyOpenSSLClient(tunnel_t *self); +tunnel_t * newOpenSSLClient(node_instance_context_t *instance_info); +api_result_t apiOpenSSLClient(tunnel_t *self, const char *msg); +tunnel_t * destroyOpenSSLClient(tunnel_t *self); tunnel_metadata_t getMetadataOpenSSLClient(); diff --git a/tunnels/client/preconnect/helpers.h b/tunnels/client/preconnect/helpers.h index dcf54906..2eb33ef8 100644 --- a/tunnels/client/preconnect/helpers.h +++ b/tunnels/client/preconnect/helpers.h @@ -1,27 +1,23 @@ #pragma once +#include "loggers/network_logger.h" #include "types.h" #include "utils/mathutils.h" -#include "loggers/network_logger.h" -#define STATE(x) ((preconnect_client_state_t *)((x)->state)) -#define CSTATE(x) ((preconnect_client_con_state_t *)((((x)->line->chains_state)[self->chain_index]))) -#define CSTATE_MUT(x) ((x)->line->chains_state)[self->chain_index] -#define ISALIVE(x) (((((x)->line->chains_state)[self->chain_index])) != NULL) -#define PRECONNECT_DELAY 100 +#define PRECONNECT_DELAY_SHORT 10 +#define PRECONNECT_DELAY_HIGH 750 -static void add_connection(thread_box_t *box, - preconnect_client_con_state_t *con) +static void addConnection(thread_box_t *box, preconnect_client_con_state_t *con) { - con->next = box->root.next; + con->next = box->root.next; box->root.next = con; - con->prev = &box->root; + con->prev = &box->root; if (con->next) { con->next->prev = con; } box->length += 1; } -static void remove_connection(thread_box_t *box, preconnect_client_con_state_t *con) +static void removeConnection(thread_box_t *box, preconnect_client_con_state_t *con) { con->prev->next = con->next; @@ -32,56 +28,58 @@ static void remove_connection(thread_box_t *box, preconnect_client_con_state_t * box->length -= 1; } -static preconnect_client_con_state_t *create_cstate(int tid) +static preconnect_client_con_state_t *createCstate(uint8_t tid) { preconnect_client_con_state_t *cstate = malloc(sizeof(preconnect_client_con_state_t)); memset(cstate, 0, sizeof(preconnect_client_con_state_t)); cstate->u = newLine(tid); - return cstate; } -static void destroy_cstate(preconnect_client_con_state_t *cstate) +static void destroyCstate(preconnect_client_con_state_t *cstate) { destroyLine(cstate->u); - free(cstate); } -static void do_connect(struct connect_arg *cg) +static void doConnect(struct connect_arg *cg) { - tunnel_t *self = cg->t; - preconnect_client_state_t *state = STATE(self); - preconnect_client_con_state_t *cstate = create_cstate(cg->tid); + tunnel_t * self = cg->t; + preconnect_client_state_t * state = STATE(self); + preconnect_client_con_state_t *cstate = createCstate(cg->tid); free(cg); (cstate->u->chains_state)[self->chain_index] = cstate; self->up->upStream(self->up, newInitContext(cstate->u)); } -static void connect_timer_finished(htimer_t *timer) +static void connectTimerFinished(htimer_t *timer) { - do_connect(hevent_userdata(timer)); + doConnect(hevent_userdata(timer)); htimer_del(timer); } -static void before_connect(hevent_t *ev) +static void beforeConnect(hevent_t *ev) { - struct connect_arg *cg = hevent_userdata(ev); - htimer_t *connect_timer = htimer_add(loops[cg->tid], connect_timer_finished, PRECONNECT_DELAY, 1); + struct connect_arg *cg = hevent_userdata(ev); + htimer_t * connect_timer = htimer_add(loops[cg->tid], connectTimerFinished, cg->delay, 1); hevent_set_userdata(connect_timer, cg); } -static void initiateConnect(tunnel_t *t) +static void initiateConnect(tunnel_t *self,bool delay) { - if (STATE(t)->unused_cons >= STATE(t)->min_unused_cons) + preconnect_client_state_t *state = STATE(self); + + if (state->unused_cons >= state->min_unused_cons) + { return; + } - int tid = 0; + uint8_t tid = 0; if (workers_count > 0) { - tid = atomic_fetch_add_explicit(&(STATE(t)->round_index), 1, memory_order_relaxed); + tid = atomic_fetch_add_explicit(&(state->round_index), 1, memory_order_relaxed); if (tid >= workers_count) { - atomic_store_explicit(&(STATE(t)->round_index), 0, memory_order_relaxed); + atomic_store_explicit(&(state->round_index), 0, memory_order_relaxed); tid = 0; } } @@ -89,11 +87,14 @@ static void initiateConnect(tunnel_t *t) hloop_t *worker_loop = loops[tid]; hevent_t ev; memset(&ev, 0, sizeof(ev)); - ev.loop = worker_loop; - ev.cb = before_connect; + ev.loop = worker_loop; + ev.cb = beforeConnect; + struct connect_arg *cg = malloc(sizeof(struct connect_arg)); - cg->t = t; - cg->tid = tid; - ev.userdata = cg; + cg->t = self; + cg->tid = tid; + cg->delay = delay ? PRECONNECT_DELAY_HIGH : PRECONNECT_DELAY_SHORT; + ev.userdata = cg; + hloop_post_event(worker_loop, &ev); } \ No newline at end of file diff --git a/tunnels/client/preconnect/preconnect_client.c b/tunnels/client/preconnect/preconnect_client.c index 0a22f51e..230ebceb 100644 --- a/tunnels/client/preconnect/preconnect_client.c +++ b/tunnels/client/preconnect/preconnect_client.c @@ -14,14 +14,14 @@ static inline void upStream(tunnel_t *self, context_t *c) switch (cstate->mode) { - case connected_direct: + case kConnectedDirect: self->up->upStream(self->up, c); break; - case connected_pair: + case kConnectedPair: self->up->upStream(self->up, switchLine(c, cstate->u)); break; - case notconnected: + case kNotconnected: default: LOGF("PreConnectClient: invalid value of connection state (memory error?)"); exit(1); @@ -31,8 +31,8 @@ static inline void upStream(tunnel_t *self, context_t *c) } else { - const unsigned int tid = c->line->tid; - thread_box_t * this_tb = &(state->workers[tid]); + const uint8_t tid = c->line->tid; + thread_box_t *this_tb = &(state->workers[tid]); if (c->init) { @@ -42,19 +42,19 @@ static inline void upStream(tunnel_t *self, context_t *c) atomic_fetch_add_explicit(&(state->active_cons), 1, memory_order_relaxed); preconnect_client_con_state_t *ucon = this_tb->root.next; - remove_connection(this_tb, ucon); + removeConnection(this_tb, ucon); ucon->d = c->line; - ucon->mode = connected_pair; + ucon->mode = kConnectedPair; CSTATE_MUT(c) = ucon; self->dw->downStream(self->dw, newEstContext(c->line)); - initiateConnect(self); + initiateConnect(self,false); } else { atomic_fetch_add_explicit(&(state->active_cons), 1, memory_order_relaxed); - preconnect_client_con_state_t *dcon = create_cstate(c->line->tid); + preconnect_client_con_state_t *dcon = createCstate(c->line->tid); CSTATE_MUT(c) = dcon; - dcon->mode = connected_direct; + dcon->mode = kConnectedDirect; self->up->upStream(self->up, c); return; } @@ -68,19 +68,19 @@ static inline void upStream(tunnel_t *self, context_t *c) switch (dcon->mode) { - case connected_direct: - destroy_cstate(dcon); + case kConnectedDirect: + destroyCstate(dcon); self->up->upStream(self->up, c); break; - case connected_pair:; + case kConnectedPair:; line_t *u_line = dcon->u; (dcon->u->chains_state)[self->chain_index] = NULL; context_t *fctx = switchLine(c, u_line); // created here to prevent destruction of line - destroy_cstate(dcon); + destroyCstate(dcon); self->up->upStream(self->up, fctx); break; - case notconnected: + case kNotconnected: default: LOGF("PreConnectClient: invalid value of connection state (memory error?)"); exit(1); @@ -101,15 +101,15 @@ static inline void downStream(tunnel_t *self, context_t *c) switch (cstate->mode) { - case connected_direct: + case kConnectedDirect: self->dw->downStream(self->dw, c); break; - case connected_pair: + case kConnectedPair: self->dw->downStream(self->dw, switchLine(c, cstate->d)); break; - case notconnected: + case kNotconnected: LOGE("PreConnectClient: this node is not purposed to handle downstream data before pairing"); default: LOGF("PreConnectClient: invalid value of connection state (memory error?)"); @@ -130,29 +130,35 @@ static inline void downStream(tunnel_t *self, context_t *c) switch (ucon->mode) { - case connected_direct: + case kConnectedDirect: atomic_fetch_add_explicit(&(state->active_cons), -1, memory_order_relaxed); - destroy_cstate(ucon); + destroyCstate(ucon); self->dw->downStream(self->dw, c); + initiateConnect(self,true); + break; - case connected_pair:; + case kConnectedPair:; atomic_fetch_add_explicit(&(state->active_cons), -1, memory_order_relaxed); line_t *d_line = ucon->d; (ucon->d->chains_state)[self->chain_index] = NULL; - destroy_cstate(ucon); + destroyCstate(ucon); self->dw->downStream(self->dw, switchLine(c, d_line)); + initiateConnect(self,false); + break; - case notconnected: + case kNotconnected: if (ucon->prev != NULL) { // fin after est atomic_fetch_add_explicit(&(state->unused_cons), -1, memory_order_relaxed); - remove_connection(this_tb, ucon); + removeConnection(this_tb, ucon); } - destroy_cstate(ucon); + destroyCstate(ucon); destroyContext(c); + initiateConnect(self,true); + break; default: @@ -161,35 +167,37 @@ static inline void downStream(tunnel_t *self, context_t *c) break; } - LOGD("PreConnectClient: disconnected, unused: %d active: %d", state->unused_cons, STATE(self)->active_cons); - initiateConnect(self); + LOGD("PreConnectClient: disconnected, unused: %d active: %d", state->unused_cons, state->active_cons); } else if (c->est) { - if (ucon->mode == notconnected) + if (ucon->mode == kNotconnected) { - add_connection(this_tb, ucon); + addConnection(this_tb, ucon); destroyContext(c); unsigned int unused = atomic_fetch_add_explicit(&(state->unused_cons), 1, memory_order_relaxed); LOGI("PreConnectClient: connected, unused: %d active: %d", unused + 1, state->active_cons); - initiateConnect(self); + initiateConnect(self,false); } else + { self->dw->downStream(self->dw, c); + } } } } -static void start_preconnect(htimer_t *timer) +static void startPreconnect(htimer_t *timer) { - tunnel_t *t = hevent_userdata(timer); + tunnel_t * self = hevent_userdata(timer); + preconnect_client_state_t *state = STATE(self); + for (int i = 0; i < workers_count; i++) { - const int cpt = STATE(t)->connection_per_thread; - + const int cpt = state->connection_per_thread; for (size_t ci = 0; ci < cpt; ci++) { - initiateConnect(t); + initiateConnect(self,true); } } @@ -206,7 +214,7 @@ tunnel_t *newPreConnectClient(node_instance_context_t *instance_info) getIntFromJsonObject(&(state->min_unused_cons), settings, "minimum-unused"); - state->min_unused_cons = min(max(workers_count * 2, state->min_unused_cons), 9999999); + state->min_unused_cons = min(max(workers_count * 4, state->min_unused_cons), 128); state->connection_per_thread = min(4, state->min_unused_cons / workers_count); tunnel_t *t = newTunnel(); @@ -214,23 +222,22 @@ tunnel_t *newPreConnectClient(node_instance_context_t *instance_info) t->upStream = &upStream; t->downStream = &downStream; - htimer_t *start_timer = htimer_add(loops[0], start_preconnect, start_delay_ms, 1); + htimer_t *start_timer = htimer_add(loops[0], startPreconnect, start_delay_ms, 1); hevent_set_userdata(start_timer, t); - atomic_thread_fence(memory_order_release); - return t; } -api_result_t apiPreConnectClient(tunnel_t *self, char *msg) +api_result_t apiPreConnectClient(tunnel_t *self, const char *msg) { (void) (self); (void) (msg); - return (api_result_t){0}; // TODO + return (api_result_t){0}; } tunnel_t *destroyPreConnectClient(tunnel_t *self) { + (void) (self); return NULL; } tunnel_metadata_t getMetadataPreConnectClient() diff --git a/tunnels/client/preconnect/preconnect_client.h b/tunnels/client/preconnect/preconnect_client.h index e85d6d33..e92d2dd0 100644 --- a/tunnels/client/preconnect/preconnect_client.h +++ b/tunnels/client/preconnect/preconnect_client.h @@ -1,15 +1,11 @@ #pragma once #include "api.h" -// +// // con <------> PreConnectClient <-------> con (established ahead of time) -// // -tunnel_t *newPreConnectClient(node_instance_context_t *instance_info); -api_result_t apiPreConnectClient(tunnel_t *self, const char *msg); -tunnel_t *destroyPreConnectClient(tunnel_t *self); +tunnel_t * newPreConnectClient(node_instance_context_t *instance_info); +api_result_t apiPreConnectClient(tunnel_t *self, const char *msg); +tunnel_t * destroyPreConnectClient(tunnel_t *self); tunnel_metadata_t getMetadataPreConnectClient(); - - - diff --git a/tunnels/client/preconnect/types.h b/tunnels/client/preconnect/types.h index 2ae43ef9..ee1e4c2c 100644 --- a/tunnels/client/preconnect/types.h +++ b/tunnels/client/preconnect/types.h @@ -5,42 +5,40 @@ struct connect_arg { - unsigned int tid; - tunnel_t *t; + uint8_t tid; + unsigned int delay; + tunnel_t * t; }; typedef enum { - notconnected, - connected_direct, - connected_pair + kNotconnected, + kConnectedDirect, + kConnectedPair } connection_state; typedef struct preconnect_client_con_state_s { struct preconnect_client_con_state_s *prev, *next; - line_t *u; - line_t *d; - connection_state mode; + line_t * u; + line_t * d; + connection_state mode; } preconnect_client_con_state_t; typedef struct thread_box_s { - size_t length; + size_t length; preconnect_client_con_state_t root; } thread_box_t; typedef struct preconnect_client_state_s { - atomic_uint active_cons; - atomic_uint unused_cons; - - atomic_uint round_index; - size_t connection_per_thread; - - // settings - int min_unused_cons; + atomic_uint active_cons; + atomic_uint unused_cons; + atomic_uint round_index; + size_t connection_per_thread; + int min_unused_cons; thread_box_t workers[]; } preconnect_client_state_t; diff --git a/tunnels/client/protobuf/protobuf_client.c b/tunnels/client/protobuf/protobuf_client.c index 882eaf8d..4ceccda6 100644 --- a/tunnels/client/protobuf/protobuf_client.c +++ b/tunnels/client/protobuf/protobuf_client.c @@ -11,12 +11,7 @@ // #include "packet.pb.h" #include "uleb128.h" -#define MAX_PACKET_SIZE (65536 * 16) - -#define STATE(x) ((protobuf_client_state_t *)((x)->state)) -#define CSTATE(x) ((protobuf_client_con_state_t *)((((x)->line->chains_state)[self->chain_index]))) -#define CSTATE_MUT(x) ((x)->line->chains_state)[self->chain_index] -#define ISALIVE(x) (CSTATE(x) != NULL) +#define MAX_PACKET_SIZE (65536 * 1) typedef struct protobuf_client_state_s { @@ -26,7 +21,7 @@ typedef struct protobuf_client_state_s typedef struct protobuf_client_con_state_s { buffer_stream_t *stream_buf; - size_t wanted; + bool first_sent; } protobuf_client_con_state_t; @@ -35,40 +30,15 @@ static void cleanup(protobuf_client_con_state_t *cstate) destroyBufferStream(cstate->stream_buf); free(cstate); } -static void downStream(tunnel_t *self, context_t *c); - -static void process(tunnel_t *self, context_t *cin) -{ - protobuf_client_con_state_t *cstate = CSTATE(cin); - buffer_stream_t *bstream = cstate->stream_buf; - if (bufferStreamLen(bstream) < cstate->wanted || cstate->wanted <= 0) { - return; -} - - context_t *c = newContextFrom(cin); - c->payload = bufferStreamRead(bstream, cstate->wanted); - self->dw->downStream(self->dw, c); - cstate->wanted = 0; - - if (bufferStreamLen(bstream) > 0) - { - context_t *c_left = newContextFrom(cin); - c_left->payload = bufferStreamRead(bstream, bufferStreamLen(bstream)); - self->downStream(self, c_left); - } -} static void upStream(tunnel_t *self, context_t *c) { - if (c->payload != NULL) { - size_t blen = bufLen(c->payload); - size_t calculated_bytes = size_uleb128(blen); - shiftl(c->payload, calculated_bytes); - write_uleb128(rawBufMut(c->payload), blen); - - shiftl(c->payload, 1); + size_t blen = bufLen(c->payload); + size_t calculated_bytes = sizeUleb128(blen); + shiftl(c->payload, calculated_bytes + 1); + writeUleb128(rawBufMut(c->payload) + 1, blen); writeUI8(c->payload, '\n'); } else @@ -76,9 +46,9 @@ static void upStream(tunnel_t *self, context_t *c) if (c->init) { protobuf_client_con_state_t *cstate = malloc(sizeof(protobuf_client_con_state_t)); - cstate->wanted = 0; - cstate->stream_buf = newBufferStream(buffer_pools[c->line->tid]); - CSTATE_MUT(c) = cstate; + cstate->first_sent = false; + cstate->stream_buf = newBufferStream(getContextBufferPool(c)); + CSTATE_MUT(c) = cstate; } else if (c->fin) { @@ -92,93 +62,103 @@ static void upStream(tunnel_t *self, context_t *c) static inline void downStream(tunnel_t *self, context_t *c) { + protobuf_client_con_state_t *cstate = CSTATE(c); if (c->payload != NULL) { - protobuf_client_con_state_t *cstate = CSTATE(c); - if (cstate->wanted > 0) + buffer_stream_t *bstream = cstate->stream_buf; + bufferStreamPush(cstate->stream_buf, c->payload); + c->payload = NULL; + + while (true) { - bufferStreamPush(cstate->stream_buf, c->payload); - c->payload = NULL; - process(self, c); - destroyContext(c); - return; - } - - - shift_buffer_t *buf = c->payload; - if (bufLen(buf) < 2) + if (bufferStreamLen(bstream) < 2) { - reuseContextBuffer(c); - cleanup(cstate); - CSTATE_MUT(c) = NULL; - self->dw->downStream(self->dw, newFinContext(c->line)); - self->up->upStream(self->up, newFinContext(c->line)); destroyContext(c); return; } + unsigned int read_len = (bufferStreamLen(bstream) >= 4 ? 4 : 2); + unsigned char uleb_encoded_buf[4]; + bufferStreamViewBytesAt(bstream, uleb_encoded_buf, 1, read_len); - shiftr(buf, 1); // first byte is \n (grpc byte array identifier? always \n? ) - size_t data_len = 0; - size_t bytes_passed = read_uleb128_to_uint64(rawBuf(buf), rawBuf(buf) + bufLen(buf), &data_len); - shiftr(buf, bytes_passed); - if (data_len > MAX_PACKET_SIZE) + size_t data_len = 0; + size_t bytes_passed = readUleb128ToUint64(uleb_encoded_buf, uleb_encoded_buf + read_len, &data_len); + if (data_len == 0) { - LOGE("ProtoBufServer: rejected, size too large %zu (%zu passed %d left)",data_len,bytes_passed,(int)(bufLen(buf))); - reuseContextBuffer(c); - cleanup(cstate); - CSTATE_MUT(c) = NULL; + if (uleb_encoded_buf[0] = 0x0) + { + LOGE("ProtoBufClient: rejected, invalid data"); + goto disconnect; + } - self->dw->downStream(self->dw, newFinContext(c->line)); - self->up->upStream(self->up, newFinContext(c->line)); + // keep waiting for more data to come destroyContext(c); return; } - if (data_len != bufLen(buf)) + if (data_len > MAX_PACKET_SIZE) + { + LOGE("ProtoBufClient: rejected, size too large %zu (%zu passed %lu left)", data_len, bytes_passed, + bufferStreamLen(bstream)); + goto disconnect; + } + if (! (bufferStreamLen(bstream) >= 1 + bytes_passed + data_len)) + { + destroyContext(c); + return; + } + context_t *upstream_ctx = newContextFrom(c); + upstream_ctx->payload = bufferStreamRead(cstate->stream_buf, 1 + bytes_passed + data_len); + shiftr(upstream_ctx->payload, 1 + bytes_passed); + if (! cstate->first_sent) + { + upstream_ctx->first = true; + cstate->first_sent = true; + } + self->dw->downStream(self->up, upstream_ctx); + if (! isAlive(c->line)) { - cstate->wanted = data_len; - bufferStreamPush(cstate->stream_buf, c->payload); - c->payload = NULL; - if (data_len >= bufLen(buf)) - { process(self, c); -} destroyContext(c); return; } - + } } else { if (c->fin) { - cleanup(CSTATE(c)); + cleanup(cstate); CSTATE_MUT(c) = NULL; } + self->dw->downStream(self->dw, c); } - - self->dw->downStream(self->dw, c); +disconnect: + cleanup(cstate); + CSTATE_MUT(c) = NULL; + self->up->upStream(self->up, newFinContext(c->line)); + self->dw->downStream(self->dw, newFinContext(c->line)); + destroyContext(c); } - tunnel_t *newProtoBufClient(node_instance_context_t *instance_info) { - - tunnel_t *t = newTunnel(); - - t->upStream = &upStream; - t->downStream = &downStream; + (void) instance_info; + tunnel_t *t = newTunnel(); + t->upStream = &upStream; + t->downStream = &downStream; atomic_thread_fence(memory_order_release); - return t; } api_result_t apiProtoBufClient(tunnel_t *self, const char *msg) { - (void)(self); (void)(msg); return (api_result_t){0}; // TODO(root): + (void) (self); + (void) (msg); + return (api_result_t){0}; // TODO(root): } tunnel_t *destroyProtoBufClient(tunnel_t *self) { + (void) (self); return NULL; } tunnel_metadata_t getMetadataProtoBufClient() diff --git a/tunnels/client/protobuf/protobuf_client.h b/tunnels/client/protobuf/protobuf_client.h index dbe5a5bb..d63b1c8c 100644 --- a/tunnels/client/protobuf/protobuf_client.h +++ b/tunnels/client/protobuf/protobuf_client.h @@ -3,12 +3,9 @@ // ----> encode ----> // con (protocolbuffers) con -// <---- decode <---- +// <---- decode <---- -tunnel_t *newProtoBufClient(node_instance_context_t *instance_info); -api_result_t apiProtoBufClient(tunnel_t *self, const char *msg); -tunnel_t *destroyProtoBufClient(tunnel_t *self); +tunnel_t * newProtoBufClient(node_instance_context_t *instance_info); +api_result_t apiProtoBufClient(tunnel_t *self, const char *msg); +tunnel_t * destroyProtoBufClient(tunnel_t *self); tunnel_metadata_t getMetadataProtoBufClient(); - - - diff --git a/tunnels/client/reverse/helpers.h b/tunnels/client/reverse/helpers.h index 18064bd9..23b2bbb4 100644 --- a/tunnels/client/reverse/helpers.h +++ b/tunnels/client/reverse/helpers.h @@ -1,26 +1,25 @@ #pragma once +#include "loggers/network_logger.h" #include "types.h" #include "utils/mathutils.h" -#include "loggers/network_logger.h" -#define STATE(x) ((reverse_client_state_t *)((x)->state)) -#define CSTATE_D(x) ((reverse_client_con_state_t *)((((x)->line->chains_state)[state->chain_index_pi]))) -#define CSTATE_U(x) ((reverse_client_con_state_t *)((((x)->line->chains_state)[state->chain_index_pi]))) -#define CSTATE_D_MUT(x) ((x)->line->chains_state)[state->chain_index_pi] -#define CSTATE_U_MUT(x) ((x)->line->chains_state)[state->chain_index_pi] -#define ISALIVE(x) (((((x)->line->chains_state)[state->chain_index_pi])) != NULL) +#define CSTATE_D(x) ((reverse_client_con_state_t *) ((((x)->line->chains_state)[state->chain_index_pi]))) +#define CSTATE_U(x) ((reverse_client_con_state_t *) ((((x)->line->chains_state)[state->chain_index_pi]))) +#define CSTATE_D_MUT(x) ((x)->line->chains_state)[state->chain_index_pi] +#define CSTATE_U_MUT(x) ((x)->line->chains_state)[state->chain_index_pi] +#define IS_ALIVE(x) (((((x)->line->chains_state)[state->chain_index_pi])) != NULL) #define PRECONNECT_DELAY_SHORT 10 -#define PRECONNECT_DELAY_HIGH 1500 +#define PRECONNECT_DELAY_HIGH 750 -static reverse_client_con_state_t *createCstate(int tid) +static reverse_client_con_state_t *createCstate(uint8_t tid) { reverse_client_con_state_t *cstate = malloc(sizeof(reverse_client_con_state_t)); memset(cstate, 0, sizeof(reverse_client_con_state_t)); line_t *up = newLine(tid); line_t *dw = newLine(tid); - cstate->u = up; - cstate->d = dw; + cstate->u = up; + cstate->d = dw; return cstate; } @@ -29,13 +28,12 @@ static void destroyCstate(reverse_client_con_state_t *cstate) { destroyLine(cstate->u); destroyLine(cstate->d); - free(cstate); } static void doConnect(struct connect_arg *cg) { - tunnel_t *self = cg->t; - reverse_client_state_t *state = STATE(self); + tunnel_t * self = cg->t; + reverse_client_state_t * state = STATE(self); reverse_client_con_state_t *cstate = createCstate(cg->tid); free(cg); (cstate->u->chains_state)[state->chain_index_pi] = cstate; @@ -50,27 +48,30 @@ static void connectTimerFinished(htimer_t *timer) } static void beforeConnect(hevent_t *ev) { - struct connect_arg *cg = hevent_userdata(ev); - htimer_t *connect_timer = htimer_add(loops[cg->tid], connectTimerFinished, cg->delay, 1); + struct connect_arg *cg = hevent_userdata(ev); + htimer_t * connect_timer = htimer_add(loops[cg->tid], connectTimerFinished, cg->delay, 1); hevent_set_userdata(connect_timer, cg); } -static void initiateConnect(tunnel_t *t, int tid) +static void initiateConnect(tunnel_t *self, uint8_t tid,bool delay) { - if (STATE(t)->unused_cons[tid] >= STATE(t)->connection_per_thread) { + reverse_client_state_t * state = STATE(self); + + if (state->unused_cons[tid] >= state->connection_per_thread) + { return; -} - bool more_delay = STATE(t)->unused_cons[tid] <= 0; - // STATE(t)->unused_cons[tid] += 1; + } + // bool more_delay = state->unused_cons[tid] <= 0; + // state->unused_cons[tid] += 1; // int tid = 0; // if (workers_count > 0) // { - // tid = atomic_fetch_add_explicit(&(STATE(t)->round_index), 1, memory_order_relaxed); + // tid = atomic_fetch_add_explicit(&(state->round_index), 1, memory_order_relaxed); // if (tid >= workers_count) // { - // atomic_store_explicit(&(STATE(t)->round_index), 0, memory_order_relaxed); + // atomic_store_explicit(&(state->round_index), 0, memory_order_relaxed); // tid = 0; // } // } @@ -78,12 +79,12 @@ static void initiateConnect(tunnel_t *t, int tid) hloop_t *worker_loop = loops[tid]; hevent_t ev; memset(&ev, 0, sizeof(ev)); - ev.loop = worker_loop; - ev.cb = beforeConnect; + ev.loop = worker_loop; + ev.cb = beforeConnect; struct connect_arg *cg = malloc(sizeof(struct connect_arg)); - cg->t = t; - cg->tid = tid; - cg->delay = more_delay?PRECONNECT_DELAY_HIGH:PRECONNECT_DELAY_SHORT; - ev.userdata = cg; + cg->t = self; + cg->tid = tid; + cg->delay = delay ? PRECONNECT_DELAY_HIGH : PRECONNECT_DELAY_SHORT; + ev.userdata = cg; hloop_post_event(worker_loop, &ev); } \ No newline at end of file diff --git a/tunnels/client/reverse/reverse_client.c b/tunnels/client/reverse/reverse_client.c index ab8cd8a9..eb68f50b 100644 --- a/tunnels/client/reverse/reverse_client.c +++ b/tunnels/client/reverse/reverse_client.c @@ -1,7 +1,7 @@ #include "reverse_client.h" +#include "helpers.h" #include "loggers/network_logger.h" #include "types.h" -#include "helpers.h" static inline void upStream(tunnel_t *self, context_t *c) { @@ -10,10 +10,10 @@ static inline void upStream(tunnel_t *self, context_t *c) if (c->payload != NULL) { reverse_client_con_state_t *dcstate = CSTATE_D(c); - if (!dcstate->first_sent_u) + if (! dcstate->first_sent_u) { dcstate->first_sent_u = true; - c->first = true; + c->first = true; } self->up->upStream(self->up, switchLine(c, dcstate->u)); } @@ -22,14 +22,16 @@ static inline void upStream(tunnel_t *self, context_t *c) if (c->fin) { - const unsigned int tid = c->line->tid; - reverse_client_con_state_t *dcstate = CSTATE_D(c); - CSTATE_D_MUT(c) = NULL; + const unsigned int tid = c->line->tid; + reverse_client_con_state_t *dcstate = CSTATE_D(c); + CSTATE_D_MUT(c) = NULL; (dcstate->u->chains_state)[state->chain_index_pi] = NULL; - context_t *fc = switchLine(c, dcstate->u); - destroy_cstate(dcstate); - const unsigned int old_reverse_cons = atomic_fetch_add_explicit(&(state->reverse_cons), -1, memory_order_relaxed); - LOGD("ReverseClient: disconnected, tid: %d unused: %u active: %d", fc->line->tid, state->unused_cons[tid], old_reverse_cons - 1); + context_t *fc = switchLine(c, dcstate->u); + destroyCstate(dcstate); + const unsigned int old_reverse_cons = + atomic_fetch_add_explicit(&(state->reverse_cons), -1, memory_order_relaxed); + LOGD("ReverseClient: disconnected, tid: %d unused: %u active: %d", fc->line->tid, state->unused_cons[tid], + old_reverse_cons - 1); self->up->upStream(self->up, fc); } else if (c->est) @@ -46,7 +48,7 @@ static inline void upStream(tunnel_t *self, context_t *c) static inline void downStream(tunnel_t *self, context_t *c) { reverse_client_state_t *state = STATE(self); - unsigned int tid = c->line->tid; + uint8_t tid = c->line->tid; if (c->payload != NULL) { @@ -54,29 +56,31 @@ static inline void downStream(tunnel_t *self, context_t *c) if (ucstate->pair_connected) { - if (!ucstate->first_sent_d) + if (! ucstate->first_sent_d) { ucstate->first_sent_d = true; - context_t *turned = switchLine(c, ucstate->d); - turned->first = true; + context_t *turned = switchLine(c, ucstate->d); + turned->first = true; self->dw->downStream(self->dw, turned); } - else { + else + { self->dw->downStream(self->dw, switchLine(c, ucstate->d)); -} + } } else { ucstate->pair_connected = true; - if (state->unused_cons[tid] > 0) { + if (state->unused_cons[tid] > 0) + { state->unused_cons[tid] -= 1; -} + } atomic_fetch_add_explicit(&(state->reverse_cons), 1, memory_order_relaxed); self->dw->downStream(self->dw, newInitContext(ucstate->d)); - + if (CSTATE_U(c) == NULL) { - reuseBuffer(buffer_pools[c->line->tid], c->payload); + reuseBuffer(getContextBufferPool(c), c->payload); c->payload = NULL; destroyContext(c); return; @@ -85,22 +89,21 @@ static inline void downStream(tunnel_t *self, context_t *c) // first byte is 0xFF a signal from reverse server uint8_t check = 0x0; readUI8(c->payload, &check); - assert(check == (unsigned char)0xFF); + assert(check == (unsigned char) 0xFF); shiftr(c->payload, 1); if (bufLen(c->payload) <= 0) { - initiateConnect(self, tid); - reuseBuffer(buffer_pools[c->line->tid], c->payload); + initiateConnect(self, tid, false); + reuseBuffer(getContextBufferPool(c), c->payload); c->payload = NULL; destroyContext(c); return; } - - ucstate->first_sent_d = true; - c->first = true; - self->dw->downStream(self->dw, switchLine(c, ucstate->d)); - initiateConnect(self, tid); - + + ucstate->first_sent_d = true; + c->first = true; + self->dw->downStream(self->dw, switchLine(c, ucstate->d)); + initiateConnect(self, tid, false); } } else @@ -108,27 +111,30 @@ static inline void downStream(tunnel_t *self, context_t *c) if (c->fin) { - reverse_client_con_state_t *ucstate = CSTATE_U(c); - CSTATE_U_MUT(c) = NULL; + reverse_client_con_state_t *ucstate = CSTATE_U(c); + CSTATE_U_MUT(c) = NULL; (ucstate->d->chains_state)[state->chain_index_pi] = NULL; if (ucstate->pair_connected) { - const unsigned int old_reverse_cons = atomic_fetch_add_explicit(&(state->reverse_cons), -1, memory_order_relaxed); - LOGD("ReverseClient: disconnected, tid: %d unused: %u active: %d", tid, state->unused_cons[tid], old_reverse_cons - 1); + const unsigned int old_reverse_cons = + atomic_fetch_add_explicit(&(state->reverse_cons), -1, memory_order_relaxed); + LOGD("ReverseClient: disconnected, tid: %d unused: %u active: %d", tid, state->unused_cons[tid], + old_reverse_cons - 1); context_t *fc = switchLine(c, ucstate->d); - destroy_cstate(ucstate); + destroyCstate(ucstate); self->dw->downStream(self->dw, fc); } else { - destroy_cstate(ucstate); - if (state->unused_cons[tid] > 0) { + destroyCstate(ucstate); + if (state->unused_cons[tid] > 0) + { state->unused_cons[tid] -= 1; -} + } LOGD("ReverseClient: disconnected, tid: %d unused: %u active: %d", tid, state->unused_cons[tid], atomic_load_explicit(&(state->reverse_cons), memory_order_relaxed)); - initiateConnect(self, tid); + initiateConnect(self, tid, true); destroyContext(c); } @@ -140,7 +146,7 @@ static inline void downStream(tunnel_t *self, context_t *c) LOGI("ReverseClient: connected, tid: %d unused: %u active: %d", tid, state->unused_cons[tid], atomic_load_explicit(&(state->reverse_cons), memory_order_relaxed)); destroyContext(c); - initiateConnect(self, tid); + initiateConnect(self, tid, false); } else { @@ -149,17 +155,17 @@ static inline void downStream(tunnel_t *self, context_t *c) } } - static void startReverseCelint(htimer_t *timer) { - tunnel_t *t = hevent_userdata(timer); + tunnel_t * self = hevent_userdata(timer); + reverse_client_state_t *state = STATE(self); for (int i = 0; i < workers_count; i++) { - const int cpt = STATE(t)->connection_per_thread; + const int cpt = state->connection_per_thread; for (size_t ci = 0; ci < cpt; ci++) { - initiateConnect(t, i); + initiateConnect(self, i, true); } } @@ -178,19 +184,19 @@ tunnel_t *newReverseClient(node_instance_context_t *instance_info) // int total = max(16, state->cons_forward); // int total = max(1, state->cons_forward); - state->min_unused_cons = min(max(workers_count * 4, state->min_unused_cons), 128); + state->min_unused_cons = min(max(workers_count * 4, state->min_unused_cons), 128); state->connection_per_thread = min(4, state->min_unused_cons / workers_count); // we are always the first line creator so its easy to get the positon independent index here - line_t *l = newLine(0); - int index = reserveChainStateIndex(l); + line_t *l = newLine(0); + int index = reserveChainStateIndex(l); state->chain_index_pi = index; destroyLine(l); - tunnel_t *t = newTunnel(); - t->state = state; - t->upStream = &upStream; - t->downStream = &downStream; + tunnel_t *t = newTunnel(); + t->state = state; + t->upStream = &upStream; + t->downStream = &downStream; htimer_t *start_timer = htimer_add(loops[0], startReverseCelint, start_delay_ms, 1); hevent_set_userdata(start_timer, t); @@ -201,14 +207,17 @@ tunnel_t *newReverseClient(node_instance_context_t *instance_info) api_result_t apiReverseClient(tunnel_t *self, const char *msg) { - (void)(self); (void)(msg); return (api_result_t){0}; // TODO(root): + (void) (self); + (void) (msg); + return (api_result_t){0}; // TODO(root): } tunnel_t *destroyReverseClient(tunnel_t *self) { + (void) (self); return NULL; } tunnel_metadata_t getMetadataReverseClient() { - return (tunnel_metadata_t){.version = 0001, .flags = TFLAG_ROUTE_STARTER}; + return (tunnel_metadata_t){.version = 0001, .flags = 0x0}; } \ No newline at end of file diff --git a/tunnels/client/reverse/reverse_client.h b/tunnels/client/reverse/reverse_client.h index 9482ec12..f3226e14 100644 --- a/tunnels/client/reverse/reverse_client.h +++ b/tunnels/client/reverse/reverse_client.h @@ -1,12 +1,9 @@ #pragma once #include "api.h" - // con 2 <------> Reverse(Client) <------> con 1 - - -tunnel_t *newReverseClient(node_instance_context_t *instance_info); -api_result_t apiReverseClient(tunnel_t *self, const char *msg); -tunnel_t *destroyReverseClient(tunnel_t *self); +tunnel_t * newReverseClient(node_instance_context_t *instance_info); +api_result_t apiReverseClient(tunnel_t *self, const char *msg); +tunnel_t * destroyReverseClient(tunnel_t *self); tunnel_metadata_t getMetadataReverseClient(); diff --git a/tunnels/client/reverse/types.h b/tunnels/client/reverse/types.h index bc23c696..8b4bc31f 100644 --- a/tunnels/client/reverse/types.h +++ b/tunnels/client/reverse/types.h @@ -5,17 +5,17 @@ struct connect_arg { - unsigned int tid; - int delay; - tunnel_t *t; + uint8_t tid; + unsigned int delay; + tunnel_t * t; }; typedef struct reverse_client_con_state_s { - bool pair_connected; - bool established; - bool first_sent_u; - bool first_sent_d; + bool pair_connected; + bool established; + bool first_sent_u; + bool first_sent_d; line_t *u; line_t *d; @@ -23,15 +23,11 @@ typedef struct reverse_client_con_state_s typedef struct reverse_client_state_s { - atomic_uint reverse_cons; - atomic_uint round_index; - - size_t chain_index_pi; - size_t connection_per_thread; - - // settings - int min_unused_cons; + atomic_uint reverse_cons; + atomic_uint round_index; + size_t chain_index_pi; + size_t connection_per_thread; + int min_unused_cons; unsigned int unused_cons[]; - } reverse_client_state_t; diff --git a/tunnels/client/wolfssl/CMakeLists.txt b/tunnels/client/wolfssl/CMakeLists.txt index 893294f7..24d52b5d 100644 --- a/tunnels/client/wolfssl/CMakeLists.txt +++ b/tunnels/client/wolfssl/CMakeLists.txt @@ -4,56 +4,62 @@ add_library(WolfSSLClient STATIC wolfssl_client.c ) -#cmake is not able to build fastest version of wolfssl yet (because all asm options are not provided in cmakelist), we used this: -# ./configure --enable-distro --enable-sp=rsa2048,asm --enable-harden --enable-static --enable-fast-rsa --enable-opensslall --enable-opensslextra --enable-tls13 --disable-oldtls --enable-intelasm --enable-aesni -# generate configure with autoreconf -i (sudo apt-get install autoconf) (sudo apt-get install libtool-bin) -# Note: before configure, add -# AC_DEFINE([NO_WOLFSSL_STUB], [1], [Description here]) -# to configure.ac ! - -# if compiling for ARM: ./configure --enable-distro --enable-sp=rsa2048,asm --enable-harden --enable-static --enable-fast-rsa --enable-opensslall --enable-opensslextra --enable-tls13 --disable-oldtls -# /src/.libs/libwolfssl.a +# This paragraph is disabled since wolfssl 5.7 update now has much better cmake interface +## ./configure --enable-distro --enable-sp=rsa2048,asm --enable-harden --enable-static --enable-fast-rsa --enable-opensslall --enable-opensslextra --enable-tls13 --disable-oldtls --enable-intelasm --enable-aesni +## generate configure with autoreconf -i (sudo apt-get install autoconf) (sudo apt-get install libtool-bin) +## Note: before configure, add +## AC_DEFINE([NO_WOLFSSL_STUB], [1], [Description here]) +## to configure.ac ! +## if compiling for ARM: ./configure --enable-distro --enable-sp=rsa2048,asm --enable-harden --enable-static --enable-fast-rsa --enable-opensslall --enable-opensslextra --enable-tls13 --disable-oldtls +## libs will be saved at: /src/.libs/libwolfssl.a #ww api target_include_directories(WolfSSLClient PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../ww) target_link_libraries(WolfSSLClient ww) -# todo select correct processor -if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "aarch64") -target_link_libraries(WolfSSLClient libwolfssl_arm64.a) -else() -target_link_libraries(WolfSSLClient libwolfssl_amd64.a) -endif() -target_include_directories(WolfSSLClient PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../shared/wolfssl) -target_link_directories(WolfSSLClient PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../shared/wolfssl) +target_include_directories(WolfSSLClient PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../shared/wolfssl) # add dependencies include(${CMAKE_BINARY_DIR}/cmake/CPM.cmake) - +# todo (WOLFSSL_CRYPTOCB) check this option doing anything useful and required or not (enables padding settings like openssl?) CPMAddPackage( NAME wolfssl VERSION 5.6.6-stable GITHUB_REPOSITORY wolfSSL/wolfssl OPTIONS + "WOLFSSL_REPRODUCIBLE_BUILD ON" + "WOLFSSL_ALPN ON" + "WOLFSSL_HARDEN ON" "WOLFSSL_OPENSSLEXTRA ON" "WOLFSSL_OPENSSLALL ON" + "WOLFSSL_SNI ON" + "WOLFSSL_SESSION_TICKET ON" "WOLFSSL_EXAMPLES OFF" "WOLFSSL_CRYPT_TESTS OFF" - "WOLFSSL_EXAMPLES OFF" - "WOLFSSL_EXAMPLES OFF" + "WOLFSSL_ASYNC_THREADS OFF" "BUILD_SHARED_LIBS OFF" ) - -target_compile_definitions(WolfSSLClient PRIVATE WolfSSLClient_VERSION=0.1) - - +target_compile_definitions(wolfssl PRIVATE NO_WOLFSSL_STUB=1) +target_compile_definitions(WolfSSLClient PRIVATE WolfSSLClient_VERSION=0.1) if(CMAKE_BUILD_TYPE STREQUAL "Debug") target_compile_definitions(WolfSSLClient PRIVATE DEBUG=1) endif() -target_include_directories(WolfSSLClient PRIVATE $) + + +# this code is used for linking with prebuilt .a (which you built with autoconf) +# target_link_directories(WolfSSLClient PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../shared/wolfssl) +# if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "aarch64") +# target_link_libraries(WolfSSLClient libwolfssl_arm64.a) +# else() +# target_link_libraries(WolfSSLClient libwolfssl_amd64.a) +# endif() +# target_include_directories(WolfSSLClient PRIVATE $) + +# this code is used for linking with cmake built wolfssl +target_link_libraries(WolfSSLClient wolfssl) diff --git a/tunnels/client/wolfssl/wolfssl_client.c b/tunnels/client/wolfssl/wolfssl_client.c index 9ec6fbd3..311c7c35 100644 --- a/tunnels/client/wolfssl/wolfssl_client.c +++ b/tunnels/client/wolfssl/wolfssl_client.c @@ -1,70 +1,64 @@ #include "wolfssl_client.h" #include "buffer_pool.h" #include "buffer_stream.h" +#include "loggers/network_logger.h" #include "managers/node_manager.h" #include "managers/socket_manager.h" -#include "loggers/network_logger.h" #include "utils/jsonutils.h" #include "wolfssl_globals.h" -#include #include #include #include #include +#include -#define STATE(x) ((wolfssl_client_state_t *)((x)->state)) -#define CSTATE(x) ((wolfssl_client_con_state_t *)((((x)->line->chains_state)[self->chain_index]))) -#define CSTATE_MUT(x) ((x)->line->chains_state)[self->chain_index] -#define ISALIVE(x) (CSTATE(x) != NULL) - -typedef struct wolfssl_client_state_s +typedef struct wssl_client_state_s { ssl_ctx_t ssl_context; // settings char *alpn; char *sni; - bool verify; + bool verify; -} wolfssl_client_state_t; +} wssl_client_state_t; -typedef struct wolfssl_client_con_state_s +typedef struct wssl_client_con_state_s { - bool handshake_completed; - SSL *ssl; - BIO *rbio; - BIO *wbio; + bool handshake_completed; + SSL * ssl; + BIO * rbio; + BIO * wbio; context_queue_t *queue; -} wolfssl_client_con_state_t; +} wssl_client_con_state_t; enum sslstatus { - SSLSTATUS_OK, - SSLSTATUS_WANT_IO, - SSLSTATUS_FAIL + kSslstatusOk, + kSslstatusWantIo, + kSslstatusFail }; - -static enum sslstatus get_sslstatus(SSL *ssl, int n) +static enum sslstatus getSslStatus(SSL *ssl, int n) { switch (SSL_get_error(ssl, n)) { case SSL_ERROR_NONE: - return SSLSTATUS_OK; + return kSslstatusOk; case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_READ: - return SSLSTATUS_WANT_IO; + return kSslstatusWantIo; case SSL_ERROR_ZERO_RETURN: case SSL_ERROR_SYSCALL: default: - return SSLSTATUS_FAIL; + return kSslstatusFail; } } static void cleanup(tunnel_t *self, context_t *c) { - wolfssl_client_con_state_t *cstate = CSTATE(c); + wssl_client_con_state_t *cstate = CSTATE(c); if (cstate != NULL) { SSL_free(cstate->ssl); /* free the SSL object and its BIO's */ @@ -75,40 +69,42 @@ static void cleanup(tunnel_t *self, context_t *c) } } -static void flush_write_queue(tunnel_t *self, context_t *c) +static void flushWriteQueue(tunnel_t *self, context_t *c) { - wolfssl_client_con_state_t *cstate = CSTATE(c); + wssl_client_con_state_t *cstate = CSTATE(c); while (contextQueueLen(cstate->queue) > 0) { self->upStream(self, contextQueuePop(cstate->queue)); - if (!isAlive(c->line)) + if (! isAlive(c->line)) + { return; + } } } static inline void upStream(tunnel_t *self, context_t *c) { - wolfssl_client_state_t *state = STATE(self); + wssl_client_state_t *state = STATE(self); if (c->payload != NULL) { - wolfssl_client_con_state_t *cstate = CSTATE(c); + wssl_client_con_state_t *cstate = CSTATE(c); - if (!cstate->handshake_completed) + if (! cstate->handshake_completed) { contextQueuePush(cstate->queue, c); return; } enum sslstatus status; - size_t len = bufLen(c->payload); + size_t len = bufLen(c->payload); while (len > 0) { - int n = SSL_write(cstate->ssl, rawBuf(c->payload), len); - status = get_sslstatus(cstate->ssl, n); + int n = SSL_write(cstate->ssl, rawBuf(c->payload), len); + status = getSslStatus(cstate->ssl, n); if (n > 0) { @@ -118,44 +114,46 @@ static inline void upStream(tunnel_t *self, context_t *c) /* take the output of the SSL object and queue it for socket write */ do { - shift_buffer_t *buf = popBuffer(buffer_pools[c->line->tid]); - size_t avail = rCap(buf); - n = BIO_read(cstate->wbio, rawBufMut(buf), avail); + shift_buffer_t *buf = popBuffer(getContextBufferPool(c)); + size_t avail = rCap(buf); + n = BIO_read(cstate->wbio, rawBufMut(buf), avail); if (n > 0) { setLen(buf, n); context_t *send_context = newContextFrom(c); - send_context->payload = buf; + send_context->payload = buf; self->up->upStream(self->up, send_context); - if (!isAlive(c->line)) + if (! isAlive(c->line)) { reuseContextBuffer(c); destroyContext(c); return; } } - else if (!BIO_should_retry(cstate->wbio)) + else if (! BIO_should_retry(cstate->wbio)) { // If BIO_should_retry() is false then the cause is an error condition. - reuseBuffer(buffer_pools[c->line->tid], buf); + reuseBuffer(getContextBufferPool(c), buf); reuseContextBuffer(c); goto failed; } else { - reuseBuffer(buffer_pools[c->line->tid], buf); + reuseBuffer(getContextBufferPool(c), buf); } } while (n > 0); } - if (status == SSLSTATUS_FAIL) + if (status == kSslstatusFail) { reuseContextBuffer(c); goto failed; } if (n == 0) + { break; + } } assert(bufLen(c->payload) == 0); reuseContextBuffer(c); @@ -166,55 +164,56 @@ static inline void upStream(tunnel_t *self, context_t *c) if (c->init) { - CSTATE_MUT(c) = malloc(sizeof(wolfssl_client_con_state_t)); - memset(CSTATE(c), 0, sizeof(wolfssl_client_con_state_t)); - wolfssl_client_con_state_t *cstate = CSTATE(c); - cstate->rbio = BIO_new(BIO_s_mem()); - cstate->wbio = BIO_new(BIO_s_mem()); - cstate->ssl = SSL_new(state->ssl_context); - cstate->queue = newContextQueue(buffer_pools[c->line->tid]); + CSTATE_MUT(c) = malloc(sizeof(wssl_client_con_state_t)); + memset(CSTATE(c), 0, sizeof(wssl_client_con_state_t)); + wssl_client_con_state_t *cstate = CSTATE(c); + cstate->rbio = BIO_new(BIO_s_mem()); + cstate->wbio = BIO_new(BIO_s_mem()); + cstate->ssl = SSL_new(state->ssl_context); + cstate->queue = newContextQueue(getContextBufferPool(c)); SSL_set_connect_state(cstate->ssl); /* sets ssl to work in client mode. */ SSL_set_bio(cstate->ssl, cstate->rbio, cstate->wbio); SSL_set_tlsext_host_name(cstate->ssl, state->sni); - context_t *clienthello_ctx = newContextFrom(c); + context_t *client_hello_ctx = newContextFrom(c); self->up->upStream(self->up, c); - if (!ISALIVE(clienthello_ctx)) + if (! isAlive(client_hello_ctx->line)) { - destroyContext(clienthello_ctx); + destroyContext(client_hello_ctx); return; } // printSSLState(cstate->ssl); int n = SSL_connect(cstate->ssl); // printSSLState(cstate->ssl); - enum sslstatus status = get_sslstatus(cstate->ssl, n); + enum sslstatus status = getSslStatus(cstate->ssl, n); /* Did SSL request to write bytes? */ - if (status == SSLSTATUS_WANT_IO) + if (status == kSslstatusWantIo) { - shift_buffer_t *buf = popBuffer(buffer_pools[clienthello_ctx->line->tid]); - size_t avail = rCap(buf); - n = BIO_read(cstate->wbio, rawBufMut(buf), avail); + shift_buffer_t *buf = popBuffer(getContextBufferPool(client_hello_ctx)); + size_t avail = rCap(buf); + n = BIO_read(cstate->wbio, rawBufMut(buf), avail); if (n > 0) { setLen(buf, n); - clienthello_ctx->payload = buf; - clienthello_ctx->first = true; - self->up->upStream(self->up, clienthello_ctx); - + client_hello_ctx->payload = buf; + client_hello_ctx->first = true; + self->up->upStream(self->up, client_hello_ctx); } - else if (!BIO_should_retry(cstate->rbio)) + else if (! BIO_should_retry(cstate->rbio)) { // If BIO_should_retry() is false then the cause is an error condition. - reuseBuffer(buffer_pools[clienthello_ctx->line->tid], buf); + reuseBuffer(getContextBufferPool(client_hello_ctx), buf); goto failed; } else { - reuseBuffer(buffer_pools[clienthello_ctx->line->tid], buf); + reuseBuffer(getContextBufferPool(client_hello_ctx), buf); } } - if (status == SSLSTATUS_FAIL) + if (status == kSslstatusFail) + { goto failed; + } } else if (c->fin) { @@ -228,23 +227,22 @@ static inline void upStream(tunnel_t *self, context_t *c) failed:; context_t *fail_context_up = newFinContext(c->line); - fail_context_up->src_io = c->src_io; + fail_context_up->src_io = c->src_io; self->up->upStream(self->up, fail_context_up); context_t *fail_context = newFinContext(c->line); cleanup(self, c); destroyContext(c); self->dw->downStream(self->dw, fail_context); - return; } static inline void downStream(tunnel_t *self, context_t *c) { - wolfssl_client_con_state_t *cstate = CSTATE(c); + wssl_client_con_state_t *cstate = CSTATE(c); if (c->payload != NULL) { - int n; + int n; enum sslstatus status; // if (!cstate->handshake_completed) @@ -263,72 +261,73 @@ static inline void downStream(tunnel_t *self, context_t *c) shiftr(c->payload, n); len -= n; - if (!cstate->handshake_completed) + if (! cstate->handshake_completed) { // printSSLState(cstate->ssl); n = SSL_connect(cstate->ssl); // printSSLState(cstate->ssl); - status = get_sslstatus(cstate->ssl, n); + status = getSslStatus(cstate->ssl, n); /* Did SSL request to write bytes? */ - if (status == SSLSTATUS_WANT_IO) + if (status == kSslstatusWantIo) + { do { - shift_buffer_t *buf = popBuffer(buffer_pools[c->line->tid]); - size_t avail = rCap(buf); - n = BIO_read(cstate->wbio, rawBufMut(buf), avail); + shift_buffer_t *buf = popBuffer(getContextBufferPool(c)); + size_t avail = rCap(buf); + n = BIO_read(cstate->wbio, rawBufMut(buf), avail); if (n > 0) { setLen(buf, n); context_t *req_cont = newContextFrom(c); - req_cont->payload = buf; + req_cont->payload = buf; self->up->upStream(self->up, req_cont); - if (!isAlive(c->line)) + if (! isAlive(c->line)) { reuseContextBuffer(c); destroyContext(c); return; } } - else if (!BIO_should_retry(cstate->rbio)) + else if (! BIO_should_retry(cstate->rbio)) { // If BIO_should_retry() is false then the cause is an error condition. reuseContextBuffer(c); - reuseBuffer(buffer_pools[c->line->tid], buf); + reuseBuffer(getContextBufferPool(c), buf); goto failed; } else { - reuseBuffer(buffer_pools[c->line->tid], buf); + reuseBuffer(getContextBufferPool(c), buf); } } while (n > 0); - - if (status == SSLSTATUS_FAIL) + } + if (status == kSslstatusFail) { - int x = SSL_get_verify_result(cstate->ssl); + SSL_get_verify_result(cstate->ssl); printSSLError(); reuseContextBuffer(c); goto failed; } /* Did SSL request to write bytes? */ - shift_buffer_t *buf = popBuffer(buffer_pools[c->line->tid]); - size_t avail = rCap(buf); - n = BIO_read(cstate->wbio, rawBufMut(buf), avail); + shift_buffer_t *buf = popBuffer(getContextBufferPool(c)); + size_t avail = rCap(buf); + n = BIO_read(cstate->wbio, rawBufMut(buf), avail); if (n > 0) { setLen(buf, n); context_t *data_ctx = newContext(c->line); - data_ctx->payload = buf; + data_ctx->payload = buf; self->up->upStream(self->up, data_ctx); } else { - reuseBuffer(buffer_pools[c->line->tid], buf); + reuseBuffer(getContextBufferPool(c), buf); } - if (!SSL_is_init_finished(cstate->ssl)) + if (! SSL_is_init_finished(cstate->ssl)) { // reuseContextBuffer(c); // destroyContext(c); @@ -336,19 +335,19 @@ static inline void downStream(tunnel_t *self, context_t *c) } else { - LOGD("OpensslClient: Tls handshake complete"); + LOGD("WolfClient: Tls handshake complete"); cstate->handshake_completed = true; - context_t *dw_est_ctx = newContextFrom(c); - dw_est_ctx->est = true; + context_t *dw_est_ctx = newContextFrom(c); + dw_est_ctx->est = true; self->dw->downStream(self->dw, dw_est_ctx); - if (!isAlive(c->line)) + if (! isAlive(c->line)) { - LOGW("OpensslClient: prev node instantly closed the est with fin"); + LOGW("WolfsslClient: prev node instantly closed the est with fin"); reuseContextBuffer(c); destroyContext(c); return; } - flush_write_queue(self, c); + flushWriteQueue(self, c); // queue is flushed and we are done // reuseContextBuffer(c); // destroyContext(c); @@ -362,25 +361,25 @@ static inline void downStream(tunnel_t *self, context_t *c) /* The encrypted data is now in the input bio so now we can perform actual * read of unencrypted data. */ - // shift_buffer_t *buf = popBuffer(buffer_pools[c->line->tid]); + // shift_buffer_t *buf = popBuffer(getContextBufferPool(c)); // shiftl(buf, 8192 / 2); // setLen(buf, 0); do { - shift_buffer_t *buf = popBuffer(buffer_pools[c->line->tid]); + shift_buffer_t *buf = popBuffer(getContextBufferPool(c)); shiftl(buf, 8192 / 2); setLen(buf, 0); size_t avail = rCap(buf); - n = SSL_read(cstate->ssl, rawBufMut(buf), avail); + n = SSL_read(cstate->ssl, rawBufMut(buf), avail); if (n > 0) { setLen(buf, n); context_t *data_ctx = newContextFrom(c); - data_ctx->payload = buf; + data_ctx->payload = buf; self->dw->downStream(self->dw, data_ctx); - if (!isAlive(c->line)) + if (! isAlive(c->line)) { reuseContextBuffer(c); destroyContext(c); @@ -389,14 +388,14 @@ static inline void downStream(tunnel_t *self, context_t *c) } else { - reuseBuffer(buffer_pools[c->line->tid], buf); + reuseBuffer(getContextBufferPool(c), buf); } } while (n > 0); - status = get_sslstatus(cstate->ssl, n); + status = getSslStatus(cstate->ssl, n); - if (status == SSLSTATUS_FAIL) + if (status == kSslstatusFail) { reuseContextBuffer(c); goto failed; @@ -414,7 +413,9 @@ static inline void downStream(tunnel_t *self, context_t *c) self->dw->downStream(self->dw, c); } else + { destroyContext(c); + } } return; @@ -427,43 +428,24 @@ failed:; cleanup(self, c); destroyContext(c); self->dw->downStream(self->dw, fail_context); - - return; -} - -static void wolfSSLUpStream(tunnel_t *self, context_t *c) -{ - upStream(self, c); -} -static void wolfSSLPacketUpStream(tunnel_t *self, context_t *c) -{ - upStream(self, c); // TODO : DTLS -} -static void wolfSSLDownStream(tunnel_t *self, context_t *c) -{ - downStream(self, c); -} -static void wolfSSLPacketDownStream(tunnel_t *self, context_t *c) -{ - downStream(self, c); } tunnel_t *newWolfSSLClient(node_instance_context_t *instance_info) { - wolfssl_client_state_t *state = malloc(sizeof(wolfssl_client_state_t)); - memset(state, 0, sizeof(wolfssl_client_state_t)); + wssl_client_state_t *state = malloc(sizeof(wssl_client_state_t)); + memset(state, 0, sizeof(wssl_client_state_t)); ssl_ctx_opt_t *ssl_param = malloc(sizeof(ssl_ctx_opt_t)); memset(ssl_param, 0, sizeof(ssl_ctx_opt_t)); const cJSON *settings = instance_info->node_settings_json; - if (!(cJSON_IsObject(settings) && settings->child != NULL)) + if (! (cJSON_IsObject(settings) && settings->child != NULL)) { LOGF("JSON Error: WolfSSLClient->settings (object field) : The object was empty or invalid"); return NULL; } - if (!getStringFromJsonObject(&(state->sni), settings, "sni")) + if (! getStringFromJsonObject(&(state->sni), settings, "sni")) { LOGF("JSON Error: WolfSSLClient->settings->sni (string field) : The data was empty or invalid"); return NULL; @@ -474,12 +456,12 @@ tunnel_t *newWolfSSLClient(node_instance_context_t *instance_info) return NULL; } - if (!getBoolFromJsonObject(&(state->verify), settings, "verify")) + if (! getBoolFromJsonObject(&(state->verify), settings, "verify")) { state->verify = true; } - if (!getStringFromJsonObject((char **)&(state->alpn), settings, "alpn")) + if (! getStringFromJsonObject(&(state->alpn), settings, "alpn")) { LOGF("JSON Error: WolfSSLClient->settings->alpn (string field) : The data was empty or invalid"); return NULL; @@ -491,9 +473,9 @@ tunnel_t *newWolfSSLClient(node_instance_context_t *instance_info) } ssl_param->verify_peer = state->verify ? 1 : 0; - ssl_param->endpoint = SSL_CLIENT; + ssl_param->endpoint = kSslClient; // ssl_param->ca_path = "cacert.pem"; - state->ssl_context = ssl_ctx_new(ssl_param); + state->ssl_context = sslCtxNew(ssl_param); free(ssl_param); // SSL_CTX_load_verify_store(state->ssl_context,cacert_bytes); @@ -507,31 +489,31 @@ tunnel_t *newWolfSSLClient(node_instance_context_t *instance_info) struct { uint8_t len; - char alpn_data[]; - } *ossl_alpn = malloc(1 + alpn_len); + char alpn_data[]; + } *ossl_alpn = malloc(1 + alpn_len); ossl_alpn->len = alpn_len; memcpy(&(ossl_alpn->alpn_data[0]), state->alpn, alpn_len); - SSL_CTX_set_alpn_protos(state->ssl_context, (const unsigned char *)ossl_alpn, 1 + alpn_len); + SSL_CTX_set_alpn_protos(state->ssl_context, (const unsigned char *) ossl_alpn, 1 + alpn_len); free(ossl_alpn); - tunnel_t *t = newTunnel(); - t->state = state; - - t->upStream = &wolfSSLUpStream; - t->packetUpStream = &wolfSSLPacketUpStream; - t->downStream = &wolfSSLDownStream; - t->packetDownStream = &wolfSSLPacketDownStream; + tunnel_t *t = newTunnel(); + t->state = state; + t->upStream = &upStream; + t->downStream = &downStream; atomic_thread_fence(memory_order_release); return t; } -api_result_t apiWolfSSLClient(tunnel_t *self, char *msg) +api_result_t apiWolfSSLClient(tunnel_t *self, const char *msg) { - (void)(self); (void)(msg); return (api_result_t){0}; // TODO + (void) (self); + (void) (msg); + return (api_result_t){0}; } tunnel_t *destroyWolfSSLClient(tunnel_t *self) { + (void) (self); return NULL; } diff --git a/tunnels/client/wolfssl/wolfssl_client.h b/tunnels/client/wolfssl/wolfssl_client.h index d43dd266..be0c065d 100644 --- a/tunnels/client/wolfssl/wolfssl_client.h +++ b/tunnels/client/wolfssl/wolfssl_client.h @@ -1,12 +1,11 @@ #pragma once #include "api.h" -// -// con <------> OpenSSL-server <------> TLS(con) -// +// +// con <------> WolfSSL-client <------> TLS(con) // -tunnel_t *newWolfSSLClient(node_instance_context_t *instance_info); -api_result_t apiWolfSSLClient(tunnel_t *self, char *msg); -tunnel_t *destroyWolfSSLClient(tunnel_t *self); +tunnel_t * newWolfSSLClient(node_instance_context_t *instance_info); +api_result_t apiWolfSSLClient(tunnel_t *self,const char *msg); +tunnel_t * destroyWolfSSLClient(tunnel_t *self); tunnel_metadata_t getMetadataWolfSSLClient(); diff --git a/tunnels/logger/logger_tunnel.c b/tunnels/logger/logger_tunnel.c index 318b2dec..e16ee8d0 100644 --- a/tunnels/logger/logger_tunnel.c +++ b/tunnels/logger/logger_tunnel.c @@ -2,11 +2,6 @@ #include "buffer_pool.h" #include "loggers/network_logger.h" -#define STATE(x) ((logger_tunnel_state_t *) ((x)->state)) -#define CSTATE(x) ((logger_tunnel_con_state_t *) ((((x)->line->chains_state)[self->chain_index]))) -#define CSTATE_MUT(x) ((x)->line->chains_state)[self->chain_index] -#define ISALIVE(x) (CSTATE(x) != NULL) - #undef min static inline size_t min(size_t x, size_t y) { @@ -38,18 +33,16 @@ static inline void upStream(tunnel_t *self, context_t *c) { // send back something - { - context_t *reply = newContextFrom(c); - reply->payload = popBuffer(buffer_pools[c->line->tid]); - reuseContextBuffer(c); - destroyContext(c); - sprintf((char *) rawBuf(reply->payload), "%s", "salam"); - setLen(reply->payload, strlen("salam")); - self->dw->downStream(self->dw, reply); - } - // context_t *reply = newFinContext(c->line); - // destroyContext(c); - // self->dw->downStream(self->dw, reply); + // { + // context_t *reply = newContextFrom(c); + // reply->payload = popBuffer(getContextBufferPool(c)); + // reuseContextBuffer(c); + // destroyContext(c); + // sprintf((char *) rawBuf(reply->payload), "%s", "salam"); + // setLen(reply->payload, strlen("salam")); + // self->dw->downStream(self->dw, reply); + // } + } } else @@ -77,7 +70,9 @@ static inline void upStream(tunnel_t *self, context_t *c) self->up->upStream(self->up, c); } else + { destroyContext(c); + } } } } @@ -97,13 +92,13 @@ static inline void downStream(tunnel_t *self, context_t *c) { // send back something - { - context_t *reply = newContextFrom(c); - reply->payload = popBuffer(buffer_pools[c->line->tid]); - sprintf((char *) rawBuf(reply->payload), "%s", "salam"); - setLen(reply->payload, strlen("salam")); - self->up->upStream(self->up, reply); - } + // { + // context_t *reply = newContextFrom(c); + // reply->payload = popBuffer(getContextBufferPool(c)); + // sprintf((char *) rawBuf(reply->payload), "%s", "salam"); + // setLen(reply->payload, strlen("salam")); + // self->up->upStream(self->up, reply); + // } reuseContextBuffer(c); destroyContext(c); @@ -147,25 +142,26 @@ static inline void downStream(tunnel_t *self, context_t *c) tunnel_t *newLoggerTunnel(node_instance_context_t *instance_info) { - + (void) instance_info; tunnel_t *t = newTunnel(); t->upStream = &upStream; t->downStream = &downStream; return t; } -api_result_t apiLoggerTunnel(tunnel_t *self, char *msg) +api_result_t apiLoggerTunnel(tunnel_t *self, const char *msg) { (void) (self); (void) (msg); - return (api_result_t){0}; // TODO + return (api_result_t){0}; } tunnel_t *destroyLoggerTunnel(tunnel_t *self) { + (void) (self); return NULL; } tunnel_metadata_t getMetadataLoggerTunnel() { - return (tunnel_metadata_t){.version = 0001, .flags = 0x0}; + return (tunnel_metadata_t){.version = 0001, .flags = kNodeFlagChainHead}; } \ No newline at end of file diff --git a/tunnels/logger/logger_tunnel.h b/tunnels/logger/logger_tunnel.h index 9cd96cb9..ce051f5c 100644 --- a/tunnels/logger/logger_tunnel.h +++ b/tunnels/logger/logger_tunnel.h @@ -1,12 +1,12 @@ #pragma once #include "api.h" -// -// dw <------> networklogger(stdout + file) <------> up -// +// +// dw <------> networklogger <------> up +// // -tunnel_t *newLoggerTunnel(node_instance_context_t *instance_info); -api_result_t apiLoggerTunnel(tunnel_t *self, const char *msg); -tunnel_t *destroyLoggerTunnel(tunnel_t *self); +tunnel_t * newLoggerTunnel(node_instance_context_t *instance_info); +api_result_t apiLoggerTunnel(tunnel_t *self, const char *msg); +tunnel_t * destroyLoggerTunnel(tunnel_t *self); tunnel_metadata_t getMetadataLoggerTunnel(); diff --git a/tunnels/server/boringssl/boringssl_server.c b/tunnels/server/boringssl/boringssl_server.c index e6bd5d34..6474b993 100644 --- a/tunnels/server/boringssl/boringssl_server.c +++ b/tunnels/server/boringssl/boringssl_server.c @@ -12,7 +12,7 @@ // #define STATE(x) ((oss_server_state_t *)((x)->state)) // #define CSTATE(x) ((oss_server_con_state_t *)((((x)->line->chains_state)[self->chain_index]))) // #define CSTATE_MUT(x) ((x)->line->chains_state)[self->chain_index] -// #define ISALIVE(x) (CSTATE(x) != NULL) +// #define isAlive(x) (CSTATE(x) != NULL) // typedef struct oss_server_state_s // { @@ -131,7 +131,7 @@ // if (status == SSLSTATUS_WANT_IO) // do // { -// shift_buffer_t *buf = popBuffer(buffer_pools[c->line->tid]); +// shift_buffer_t *buf = popBuffer(getContextBufferPool(c)); // size_t avail = rCap(buf); // n = BIO_read(cstate->wbio, rawBuf(buf), avail); // // assert(-1 == BIO_read(cstate->wbio, rawBuf(buf), avail)); @@ -152,12 +152,12 @@ // { // // If BIO_should_retry() is false then the cause is an error condition. // reuseContextBuffer(c); -// reuseBuffer(buffer_pools[c->line->tid], buf); +// reuseBuffer(getContextBufferPool(c), buf); // goto failed; // } // else // { -// reuseBuffer(buffer_pools[c->line->tid], buf); +// reuseBuffer(getContextBufferPool(c), buf); // } // } while (n > 0); @@ -196,7 +196,7 @@ // /* The encrypted data is now in the input bio so now we can perform actual // * read of unencrypted data. */ -// shift_buffer_t *buf = popBuffer(buffer_pools[c->line->tid]); +// shift_buffer_t *buf = popBuffer(getContextBufferPool(c)); // shiftl(buf, 8192 / 2); // setLen(buf, 0); // do @@ -230,7 +230,7 @@ // } // else // { -// reuseBuffer(buffer_pools[c->line->tid], buf); +// reuseBuffer(getContextBufferPool(c), buf); // } // status = get_sslstatus(cstate->ssl, n); @@ -240,7 +240,7 @@ // if (status == SSLSTATUS_WANT_IO) // do // { -// shift_buffer_t *buf = popBuffer(buffer_pools[c->line->tid]); +// shift_buffer_t *buf = popBuffer(getContextBufferPool(c)); // size_t avail = rCap(buf); // n = BIO_read(cstate->wbio, rawBuf(buf), avail); @@ -261,7 +261,7 @@ // else if (!BIO_should_retry(cstate->wbio)) // { // // If BIO_should_retry() is false then the cause is an error condition. -// reuseBuffer(buffer_pools[c->line->tid], buf); +// reuseBuffer(getContextBufferPool(c), buf); // reuseContextBuffer(c); // destroyContext(c); @@ -269,7 +269,7 @@ // } // else // { -// reuseBuffer(buffer_pools[c->line->tid], buf); +// reuseBuffer(getContextBufferPool(c), buf); // } // } while (n > 0); @@ -362,7 +362,7 @@ // do // { -// shift_buffer_t *buf = popBuffer(buffer_pools[c->line->tid]); +// shift_buffer_t *buf = popBuffer(getContextBufferPool(c)); // size_t avail = rCap(buf); // n = BIO_read(cstate->wbio, rawBuf(buf), avail); // if (n > 0) @@ -383,13 +383,13 @@ // else if (!BIO_should_retry(cstate->wbio)) // { // // If BIO_should_retry() is false then the cause is an error condition. -// reuseBuffer(buffer_pools[c->line->tid], buf); +// reuseBuffer(getContextBufferPool(c), buf); // reuseContextBuffer(c); // goto failed_after_establishment; // } // else // { -// reuseBuffer(buffer_pools[c->line->tid], buf); +// reuseBuffer(getContextBufferPool(c), buf); // } // } while (n > 0); // } diff --git a/tunnels/server/header/header_server.c b/tunnels/server/header/header_server.c index 4cdb25a9..cef899cb 100644 --- a/tunnels/server/header/header_server.c +++ b/tunnels/server/header/header_server.c @@ -18,7 +18,9 @@ typedef struct header_server_state_s typedef struct header_server_con_state_s { - bool init_sent; + bool init_sent; + bool first_sent; + shift_buffer_t *buf; } header_server_con_state_t; @@ -28,19 +30,22 @@ static void upStream(tunnel_t *self, context_t *c) header_server_con_state_t *cstate = CSTATE(c); if (c->payload != NULL) { - if (c->first) + if (! cstate->init_sent) { - - shift_buffer_t *buf = c->payload; - if (bufLen(buf) < 2) + if (cstate->buf) { - reuseContextBuffer(c); - self->dw->downStream(self->dw, newFinContext(c->line)); + cstate->buf = appendBufferMerge(getContextBufferPool(c), cstate->buf, c->payload); + c->payload = cstate->buf; + } + if (bufLen(c->payload) < 2) + { + cstate->buf = c->payload; + c->payload = NULL; destroyContext(c); return; } - - uint16_t port = 0; + shift_buffer_t *buf = c->payload; + uint16_t port = 0; switch ((enum header_dynamic_value_status) state->data.status) { case kHdvsConstant: @@ -55,30 +60,42 @@ static void upStream(tunnel_t *self, context_t *c) destroyContext(c); return; } - - break; - - default: break; } cstate->init_sent = true; self->up->upStream(self->up, newInitContext(c->line)); - if (! isAlive(c->line)) + if (bufLen(buf) > 0) + { + if (! isAlive(c->line)) + { + reuseContextBuffer(c); + destroyContext(c); + return; + } + } + else { reuseContextBuffer(c); destroyContext(c); return; } } + if (! cstate->first_sent) + { + c->first = true; + cstate->first_sent = true; + } + self->up->upStream(self->up, c); + } else if (c->init) { cstate = malloc(sizeof(header_server_con_state_t)); cstate->init_sent = false; + cstate->first_sent = false; CSTATE_MUT(c) = cstate; destroyContext(c); - return; } else if (c->fin) { @@ -93,10 +110,7 @@ static void upStream(tunnel_t *self, context_t *c) { destroyContext(c); } - return; } - - self->up->upStream(self->up, c); } static inline void downStream(tunnel_t *self, context_t *c) diff --git a/tunnels/server/http2/helpers.h b/tunnels/server/http2/helpers.h index 492e2e77..0c8db90d 100644 --- a/tunnels/server/http2/helpers.h +++ b/tunnels/server/http2/helpers.h @@ -28,7 +28,7 @@ static nghttp2_nv makeNv2(const char *name, const char *value, int namelen, int static void printFrameHd(const nghttp2_frame_hd *hd) { LOGD("[frame] length=%d type=%x flags=%x stream_id=%d\n", (int) hd->length, (int) hd->type, (int) hd->flags, - hd->stream_id); + hd->stream_id); } static void addStream(http2_server_con_state_t *con, http2_server_child_con_state_t *stream) @@ -51,7 +51,7 @@ static void removeStream(http2_server_con_state_t *con, http2_server_child_con_s } } http2_server_child_con_state_t *createHttp2Stream(http2_server_con_state_t *con, line_t *this_line, - tunnel_t *target_tun, int32_t stream_id) + tunnel_t *target_tun, int32_t stream_id) { http2_server_child_con_state_t *stream; stream = malloc(sizeof(http2_server_child_con_state_t)); @@ -73,9 +73,10 @@ static void deleteHttp2Stream(http2_server_child_con_state_t *stream) stream->line->chains_state[stream->tunnel->chain_index - 1] = NULL; destroyBufferStream(stream->chunkbs); destroyLine(stream->line); - if (stream->request_path) { + if (stream->request_path) + { free(stream->request_path); -} + } free(stream); } @@ -116,4 +117,3 @@ static void deleteHttp2Connection(http2_server_con_state_t *con) con->line->chains_state[self->chain_index] = NULL; free(con); } - diff --git a/tunnels/server/http2/http2_server.c b/tunnels/server/http2/http2_server.c index 29d84183..afa0bd30 100644 --- a/tunnels/server/http2/http2_server.c +++ b/tunnels/server/http2/http2_server.c @@ -17,7 +17,7 @@ static int onHeaderCallback(nghttp2_session *session, const nghttp2_frame *frame } // LOGD("onHeaderCallback\n"); - print_frame_hd(&frame->hd); + printFrameHd(&frame->hd); const char *name = (const char *) _name; const char *value = (const char *) _value; // LOGD("%s: %s\n", name, value); @@ -81,7 +81,7 @@ static int onDataChunkRecvCallback(nghttp2_session *session, uint8_t flags, int3 if (con->content_type == kApplicationGrpc) { - shift_buffer_t *buf = popBuffer(buffer_pools[con->line->tid]); + shift_buffer_t *buf = popBuffer(getLineBufferPool(con->line)); shiftl(buf, lCap(buf) / 2); // use some unused space setLen(buf, len); writeRaw(buf, data, len); @@ -95,7 +95,7 @@ static int onDataChunkRecvCallback(nghttp2_session *session, uint8_t flags, int3 grpc_message_hd msghd; grpcMessageHdUnpack(&msghd, rawBuf(gheader_buf)); stream->bytes_needed = msghd.length; - reuseBuffer(buffer_pools[con->line->tid], gheader_buf); + reuseBuffer(getLineBufferPool(con->line), gheader_buf); } if (stream->bytes_needed > 0 && bufferStreamLen(stream->chunkbs) >= stream->bytes_needed) { @@ -121,7 +121,7 @@ static int onDataChunkRecvCallback(nghttp2_session *session, uint8_t flags, int3 } else { - shift_buffer_t *buf = popBuffer(buffer_pools[con->line->tid]); + shift_buffer_t *buf = popBuffer(getLineBufferPool(con->line)); shiftl(buf, lCap(buf) / 2); // use some unused space setLen(buf, len); writeRaw(buf, data, len); @@ -146,7 +146,7 @@ static int onFrameRecvCallback(nghttp2_session *session, const nghttp2_frame *fr return 0; } // LOGD("onFrameRecvCallback\n"); - print_frame_hd(&frame->hd); + printFrameHd(&frame->hd); http2_server_con_state_t *con = (http2_server_con_state_t *) userdata; tunnel_t * self = con->tunnel; @@ -187,7 +187,7 @@ static int onFrameRecvCallback(nghttp2_session *session, const nghttp2_frame *fr context_t *fc = newFinContext(stream->line); tunnel_t * dest = stream->tunnel; removeStream(con, stream); - delete_http2_stream(stream); + deleteHttp2Stream(stream); CSTATE_MUT(fc) = NULL; dest->upStream(dest, fc); @@ -392,7 +392,7 @@ static inline void downStream(tunnel_t *self, context_t *c) nghttp2_session_set_stream_user_data(con->session, stream->stream_id, NULL); removeStream(con, stream); - delete_http2_stream(stream); + deleteHttp2Stream(stream); CSTATE_MUT(c) = NULL; while (trySendResponse(self, con, 0, NULL, NULL)) diff --git a/tunnels/server/openssl/openssl_server.c b/tunnels/server/openssl/openssl_server.c index 75d5c604..eb67d4d7 100644 --- a/tunnels/server/openssl/openssl_server.c +++ b/tunnels/server/openssl/openssl_server.c @@ -236,7 +236,7 @@ static inline void upStream(tunnel_t *self, context_t *c) { do { - shift_buffer_t *buf = popBuffer(buffer_pools[c->line->tid]); + shift_buffer_t *buf = popBuffer(getContextBufferPool(c)); size_t avail = rCap(buf); n = BIO_read(cstate->wbio, rawBufMut(buf), avail); // assert(-1 == BIO_read(cstate->wbio, rawBuf(buf), avail)); @@ -257,12 +257,12 @@ static inline void upStream(tunnel_t *self, context_t *c) { // If BIO_should_retry() is false then the cause is an error condition. reuseContextBuffer(c); - reuseBuffer(buffer_pools[c->line->tid], buf); + reuseBuffer(getContextBufferPool(c), buf); goto disconnect; } else { - reuseBuffer(buffer_pools[c->line->tid], buf); + reuseBuffer(getContextBufferPool(c), buf); } } while (n > 0); } @@ -318,7 +318,7 @@ static inline void upStream(tunnel_t *self, context_t *c) do { - shift_buffer_t *buf = popBuffer(buffer_pools[c->line->tid]); + shift_buffer_t *buf = popBuffer(getContextBufferPool(c)); shiftl(buf, 8192 / 2); setLen(buf, 0); size_t avail = rCap(buf); @@ -344,7 +344,7 @@ static inline void upStream(tunnel_t *self, context_t *c) } else { - reuseBuffer(buffer_pools[c->line->tid], buf); + reuseBuffer(getContextBufferPool(c), buf); } } while (n > 0); @@ -357,7 +357,7 @@ static inline void upStream(tunnel_t *self, context_t *c) { do { - shift_buffer_t *buf = popBuffer(buffer_pools[c->line->tid]); + shift_buffer_t *buf = popBuffer(getContextBufferPool(c)); size_t avail = rCap(buf); n = BIO_read(cstate->wbio, rawBufMut(buf), avail); @@ -378,13 +378,13 @@ static inline void upStream(tunnel_t *self, context_t *c) else if (! BIO_should_retry(cstate->wbio)) { // If BIO_should_retry() is false then the cause is an error condition. - reuseBuffer(buffer_pools[c->line->tid], buf); + reuseBuffer(getContextBufferPool(c), buf); reuseContextBuffer(c); goto failed_after_establishment; } else { - reuseBuffer(buffer_pools[c->line->tid], buf); + reuseBuffer(getContextBufferPool(c), buf); } } while (n > 0); } @@ -410,7 +410,7 @@ static inline void upStream(tunnel_t *self, context_t *c) cstate->rbio = BIO_new(BIO_s_mem()); cstate->wbio = BIO_new(BIO_s_mem()); cstate->ssl = SSL_new(state->ssl_context); - cstate->fallback_buf = newBufferStream(buffer_pools[c->line->tid]); + cstate->fallback_buf = newBufferStream(getContextBufferPool(c)); SSL_set_accept_state(cstate->ssl); /* sets ssl to work in server mode. */ SSL_set_bio(cstate->ssl, cstate->rbio, cstate->wbio); if (state->anti_tit) @@ -510,7 +510,7 @@ static inline void downStream(tunnel_t *self, context_t *c) do { - shift_buffer_t *buf = popBuffer(buffer_pools[c->line->tid]); + shift_buffer_t *buf = popBuffer(getContextBufferPool(c)); size_t avail = rCap(buf); n = BIO_read(cstate->wbio, rawBufMut(buf), avail); if (n > 0) @@ -530,13 +530,13 @@ static inline void downStream(tunnel_t *self, context_t *c) else if (! BIO_should_retry(cstate->wbio)) { // If BIO_should_retry() is false then the cause is an error condition. - reuseBuffer(buffer_pools[c->line->tid], buf); + reuseBuffer(getContextBufferPool(c), buf); reuseContextBuffer(c); goto failed_after_establishment; } else { - reuseBuffer(buffer_pools[c->line->tid], buf); + reuseBuffer(getContextBufferPool(c), buf); } } while (n > 0); } diff --git a/tunnels/server/preconnect/preconnect_server.c b/tunnels/server/preconnect/preconnect_server.c index ce7bb4e1..67459a24 100644 --- a/tunnels/server/preconnect/preconnect_server.c +++ b/tunnels/server/preconnect/preconnect_server.c @@ -14,7 +14,7 @@ typedef struct preconnect_server_con_state_s } preconnect_server_con_state_t; -static void upStream(tunnel_t *self, context_t *c, TunnelFlowRoutine upstream) +static void upStream(tunnel_t *self, context_t *c) { if (c->payload != NULL) @@ -31,7 +31,7 @@ static void upStream(tunnel_t *self, context_t *c, TunnelFlowRoutine upstream) return; } } - upstream(self->up, c); + self->up->upStream(self->up, c); } else if (c->init) { @@ -49,7 +49,7 @@ static void upStream(tunnel_t *self, context_t *c, TunnelFlowRoutine upstream) CSTATE_MUT(c) = NULL; if (send_fin) { - upstream(self->up, c); + self->up->upStream(self->up, c); } else { @@ -60,7 +60,7 @@ static void upStream(tunnel_t *self, context_t *c, TunnelFlowRoutine upstream) } } -static inline void downStream(tunnel_t *self, context_t *c, TunnelFlowRoutine downstream) +static inline void downStream(tunnel_t *self, context_t *c) { if (c->fin) @@ -69,25 +69,10 @@ static inline void downStream(tunnel_t *self, context_t *c, TunnelFlowRoutine do CSTATE_MUT(c) = NULL; } - downstream(self->dw, c); + self->dw->downStream(self->dw, c); } -static void preConnectServerUpStream(tunnel_t *self, context_t *c) -{ - upStream(self, c, self->up->upStream); -} -static void preConnectServerPacketUpStream(tunnel_t *self, context_t *c) -{ - upStream(self, c, self->up->packetUpStream); -} -static void preConnectServerDownStream(tunnel_t *self, context_t *c) -{ - downStream(self, c, self->dw->downStream); -} -static void preConnectServerPacketDownStream(tunnel_t *self, context_t *c) -{ - downStream(self, c, self->dw->packetDownStream); -} + tunnel_t *newPreConnectServer(node_instance_context_t *instance_info) { diff --git a/tunnels/server/protobuf/protobuf_server.c b/tunnels/server/protobuf/protobuf_server.c index a65f5e57..0381460d 100644 --- a/tunnels/server/protobuf/protobuf_server.c +++ b/tunnels/server/protobuf/protobuf_server.c @@ -21,7 +21,6 @@ typedef struct protobuf_server_state_s typedef struct protobuf_server_con_state_s { buffer_stream_t *stream_buf; - size_t wanted; bool first_sent; } protobuf_server_con_state_t; @@ -32,7 +31,7 @@ static void cleanup(protobuf_server_con_state_t *cstate) free(cstate); } -static inline void upStream(tunnel_t *self, context_t *c, TunnelFlowRoutine upstream, TunnelFlowRoutine downstream) +static inline void upStream(tunnel_t *self, context_t *c) { protobuf_server_con_state_t *cstate = CSTATE(c); @@ -60,7 +59,8 @@ static inline void upStream(tunnel_t *self, context_t *c, TunnelFlowRoutine upst { if (uleb_encoded_buf[0] = 0x0) { - // invalid + LOGE("ProtoBufServer: rejected, invalid data"); + goto disconnect; } @@ -70,7 +70,8 @@ static inline void upStream(tunnel_t *self, context_t *c, TunnelFlowRoutine upst } if (data_len > MAX_PACKET_SIZE) { - // overflow + LOGE("ProtoBufServer: rejected, size too large %zu (%zu passed %lu left)", data_len, bytes_passed, + bufferStreamLen(bstream)); goto disconnect; } if (! (bufferStreamLen(bstream) >= 1 + bytes_passed + data_len)) @@ -86,7 +87,7 @@ static inline void upStream(tunnel_t *self, context_t *c, TunnelFlowRoutine upst upstream_ctx->first = true; cstate->first_sent = true; } - upstream(self->up, upstream_ctx); + self->up->upStream(self->up, upstream_ctx); if (! isAlive(c->line)) { destroyContext(c); @@ -99,9 +100,8 @@ static inline void upStream(tunnel_t *self, context_t *c, TunnelFlowRoutine upst if (c->init) { cstate = malloc(sizeof(protobuf_server_con_state_t)); - cstate->wanted = 0; cstate->first_sent = false; - cstate->stream_buf = newBufferStream(buffer_pools[c->line->tid]); + cstate->stream_buf = newBufferStream(getContextBufferPool(c)); CSTATE_MUT(c) = cstate; } else if (c->fin) @@ -109,27 +109,27 @@ static inline void upStream(tunnel_t *self, context_t *c, TunnelFlowRoutine upst cleanup(cstate); CSTATE_MUT(c) = NULL; } - upstream(self->up, c); + self->up->upStream(self->up, c); } return; disconnect: cleanup(cstate); CSTATE_MUT(c) = NULL; - upstream(self->up, newFinContext(c->line)); - downstream(self->dw, newFinContext(c->line)); + self->up->upStream(self->up, newFinContext(c->line)); + self->dw->downStream(self->dw, newFinContext(c->line)); destroyContext(c); } -static inline void downStream(tunnel_t *self, context_t *c, TunnelFlowRoutine downstream) +static inline void downStream(tunnel_t *self, context_t *c) { if (c->payload != NULL) { size_t blen = bufLen(c->payload); - size_t calculated_bytes = size_uleb128(blen); + size_t calculated_bytes = sizeUleb128(blen); shiftl(c->payload, calculated_bytes + 1); - write_uleb128(rawBufMut(c->payload) + 1, blen); + writeUleb128(rawBufMut(c->payload) + 1, blen); writeUI8(c->payload, '\n'); } else @@ -141,11 +141,9 @@ static inline void downStream(tunnel_t *self, context_t *c, TunnelFlowRoutine do CSTATE_MUT(c) = NULL; } } - downstream(self->dw, c); + self->dw->downStream(self->dw, c); } - - tunnel_t *newProtoBufServer(node_instance_context_t *instance_info) { diff --git a/tunnels/server/reverse/reverse_server.c b/tunnels/server/reverse/reverse_server.c index ee451f50..8c26ab49 100644 --- a/tunnels/server/reverse/reverse_server.c +++ b/tunnels/server/reverse/reverse_server.c @@ -35,7 +35,7 @@ static void flushWriteQueue(tunnel_t *self, reverse_server_con_state_t *cstate) else { cstate->signal_sent = true; - shift_buffer_t *buf = popBuffer(buffer_pools[cstate->d->tid]); + shift_buffer_t *buf = popBuffer(getLineBufferPool(cstate->d)); shiftl(buf, 1); writeUI8(buf, 0xFF); context_t *c = newContext(cstate->d); @@ -57,14 +57,14 @@ static inline void upStream(tunnel_t *self, context_t *c) else { // a real pair will not send that before it receives something - reuseBuffer(buffer_pools[c->line->tid], c->payload); + reuseBuffer(getContextBufferPool(c), c->payload); c->payload = NULL; destroyContext(c); } } else { - const unsigned int tid = c->line->tid; + const uint8_t tid = c->line->tid; thread_box_t * this_tb = &(state->threadlocal_pool[tid]); if (c->init) { @@ -76,7 +76,7 @@ static inline void upStream(tunnel_t *self, context_t *c) if (this_tb->u_count > 0) { reverse_server_con_state_t *ucstate = this_tb->u_cons_root.next; - remove_connection_u(this_tb, ucstate); + removeConnectionU(this_tb, ucstate); ucstate->d = c->line; ucstate->paired = true; CSTATE_D_MUT(c) = ucstate; @@ -86,9 +86,9 @@ static inline void upStream(tunnel_t *self, context_t *c) } else { - reverse_server_con_state_t *dcstate = create_cstate(false, c->line); + reverse_server_con_state_t *dcstate = createCstate(false, c->line); CSTATE_D_MUT(c) = dcstate; - add_connection_d(this_tb, dcstate); + addConnectionD(this_tb, dcstate); } destroyContext(c); } @@ -101,13 +101,13 @@ static inline void upStream(tunnel_t *self, context_t *c) { line_t *u_line = dcstate->u; (dcstate->u->chains_state)[state->chain_index_u] = NULL; - destroy_cstate(dcstate); + destroyCstate(dcstate); self->up->upStream(self->up, switchLine(c, u_line)); } else { - remove_connection_d(this_tb, dcstate); - destroy_cstate(dcstate); + removeConnectionD(this_tb, dcstate); + destroyCstate(dcstate); destroyContext(c); } } @@ -130,7 +130,7 @@ static inline void downStream(tunnel_t *self, context_t *c) } else { - const unsigned int tid = c->line->tid; + const uint8_t tid = c->line->tid; thread_box_t * this_tb = &(state->threadlocal_pool[tid]); if (c->init) { @@ -143,7 +143,7 @@ static inline void downStream(tunnel_t *self, context_t *c) { reverse_server_con_state_t *dcstate = this_tb->d_cons_root.next; - remove_connection_d(this_tb, dcstate); + removeConnectionD(this_tb, dcstate); dcstate->u = c->line; dcstate->paired = true; CSTATE_U_MUT(c) = dcstate; @@ -172,9 +172,9 @@ static inline void downStream(tunnel_t *self, context_t *c) else { LOGW("reverseServer: no peer left, waiting tid: %d", c->line->tid); - reverse_server_con_state_t *ucstate = create_cstate(true, c->line); + reverse_server_con_state_t *ucstate = createCstate(true, c->line); CSTATE_U_MUT(c) = ucstate; - add_connection_u(this_tb, ucstate); + addConnectionU(this_tb, ucstate); } destroyContext(c); } @@ -188,13 +188,13 @@ static inline void downStream(tunnel_t *self, context_t *c) line_t *d_line = ucstate->d; (ucstate->d->chains_state)[state->chain_index_d] = NULL; - destroy_cstate(ucstate); + destroyCstate(ucstate); self->dw->downStream(self->dw, switchLine(c, d_line)); } else { - remove_connection_u(this_tb, ucstate); - destroy_cstate(ucstate); + removeConnectionU(this_tb, ucstate); + destroyCstate(ucstate); destroyContext(c); } } @@ -230,5 +230,5 @@ tunnel_t *destroyReverseServer(tunnel_t *self) } tunnel_metadata_t getMetadataReverseServer() { - return (tunnel_metadata_t){.version = 0001, .flags = TFLAG_ROUTE_STARTER}; + return (tunnel_metadata_t){.version = 0001, .flags = kNodeFlagChainHead}; } \ No newline at end of file diff --git a/tunnels/server/trojan/auth/trojan_auth_server.c b/tunnels/server/trojan/auth/trojan_auth_server.c index 6a69cdba..a9fa08a3 100644 --- a/tunnels/server/trojan/auth/trojan_auth_server.c +++ b/tunnels/server/trojan/auth/trojan_auth_server.c @@ -84,8 +84,11 @@ static inline void upStream(tunnel_t *self, context_t *c) // gettimeofday(&tv1, NULL); { - // the payload must not come buffeered here (gfw can do this but not the client) + // beware! trojan auth will not use stream buffer, at least the auth chunk must come in first sequence + // the payload must not come buffeered here (gfw can do this and detect trojan authentication + // but the client is not supposed to send small segments) // so , if its incomplete we go to fallback! + // this is also mentioned in standard trojan docs (first packet also contains part of final payload) size_t len = bufLen(c->payload); if (len < (sizeof(sha224_hex_t) + CRLF_LEN)) { @@ -107,14 +110,14 @@ static inline void upStream(tunnel_t *self, context_t *c) if (find_result.ref == hmap_users_t_end(&(state->users)).ref) { // user not in database - LOGW("TrojanAuthServer: a trojan-user rejecetd because not found in database"); + LOGW("TrojanAuthServer: a trojan-user rejected because not found in database"); goto failed; } trojan_user_t *tuser = (find_result.ref->second); if (! tuser->user.enable) { // user disabled - LOGW("TrojanAuthServer: user \"%s\" rejecetd because not enabled", tuser->user.name); + LOGW("TrojanAuthServer: user \"%s\" rejected because not enabled", tuser->user.name); goto failed; } @@ -136,7 +139,6 @@ static inline void upStream(tunnel_t *self, context_t *c) self->up->upStream(self->up, c); } // gettimeofday(&tv2, NULL); - // double time_spent = (double)(tv2.tv_usec - tv1.tv_usec) / 1000000 + (double)(tv2.tv_sec - // tv1.tv_sec); LOGD("Auth: took %lf sec", time_spent); return; diff --git a/tunnels/server/trojan/socks/trojan_socks_server.c b/tunnels/server/trojan/socks/trojan_socks_server.c index 9810af79..90d36f9d 100644 --- a/tunnels/server/trojan/socks/trojan_socks_server.c +++ b/tunnels/server/trojan/socks/trojan_socks_server.c @@ -4,7 +4,7 @@ #include "loggers/network_logger.h" #include "utils/stringutils.h" #include "utils/userutils.h" - +#include "utils/sockutils.h" #define CRLF_LEN 2 @@ -29,7 +29,6 @@ typedef struct trojan_socks_server_con_state_s { bool init_sent; bool first_sent; - bool is_udp_forward; buffer_stream_t *udp_buf; @@ -79,14 +78,13 @@ static bool parseAddress(context_t *c) socket_context_t *dest_context = &(c->line->dest_ctx); enum trojan_cmd command = ((unsigned char *) rawBuf(c->payload))[0]; enum trojan_atyp address_type = ((unsigned char *) rawBuf(c->payload))[1]; - dest_context->acmd = (enum socket_address_cmd)(command); - dest_context->address_type = (enum socket_address_type)(address_type); + dest_context->address_type = (enum socket_address_type)(address_type); shiftr(c->payload, 2); switch (command) { case kTrojancmdConnect: - dest_context->protocol = IPPROTO_TCP; + dest_context->address_protocol = kSapTcp; switch (address_type) { case kTrojanatypIpV4: @@ -132,7 +130,7 @@ static bool parseAddress(context_t *c) } break; case kTrojancmdUdpAssociate: - dest_context->protocol = IPPROTO_UDP; + dest_context->address_protocol = kSapUdp; switch (address_type) { @@ -205,10 +203,10 @@ static bool processUdp(tunnel_t *self, trojan_socks_server_con_state_t *cstate, return true; } - uint8_t address_type = bufferStreamViewByteAt(bstream, 0); - uint16_t packet_size = 0; - uint16_t full_len = 0; - uint8_t domain_len = 0; + uint8_t address_type = bufferStreamViewByteAt(bstream, 0); + uint16_t packet_size = 0; + uint16_t full_len = 0; + uint8_t domain_len = 0; switch (address_type) { case kTrojanatypIpV4: @@ -301,7 +299,7 @@ static bool processUdp(tunnel_t *self, trojan_socks_server_con_state_t *cstate, { case kTrojanatypIpV4: dest_context->addr.sa.sa_family = AF_INET; - dest_context->address_type = kSatIPV4; + dest_context->address_type = kSatIPV4; memcpy(&(dest_context->addr.sin.sin_addr), rawBuf(c->payload), 4); shiftr(c->payload, 4); if (! cstate->first_sent) @@ -330,7 +328,7 @@ static bool processUdp(tunnel_t *self, trojan_socks_server_con_state_t *cstate, break; case kTrojanatypIpV6: - dest_context->address_type = kSatIPV6; + dest_context->address_type = kSatIPV6; dest_context->addr.sa.sa_family = AF_INET6; memcpy(&(dest_context->addr.sin.sin_addr), rawBuf(c->payload), 16); shiftr(c->payload, 16); @@ -376,7 +374,7 @@ static bool processUdp(tunnel_t *self, trojan_socks_server_con_state_t *cstate, { context_t *up_init_ctx = newContextFrom(c); up_init_ctx->init = true; - self->up->packetUpStream(self->up, up_init_ctx); + self->up->upStream(self->up, up_init_ctx); if (! isAlive(c->line)) { LOGW("TrojanSocksServer: next node instantly closed the init with fin"); @@ -385,7 +383,7 @@ static bool processUdp(tunnel_t *self, trojan_socks_server_con_state_t *cstate, cstate->init_sent = true; } - self->up->packetUpStream(self->up, c); + self->up->upStream(self->up, c); // line is alvie because caller is holding a context, but still fin could received // and state is gone @@ -408,7 +406,7 @@ static inline void upStream(tunnel_t *self, context_t *c) trojan_socks_server_con_state_t *cstate = CSTATE(c); socket_context_t * dest_context = &(c->line->dest_ctx); - if (dest_context->protocol == IPPROTO_TCP) + if (dest_context->address_protocol == kSapTcp) { context_t *up_init_ctx = newContextFrom(c); up_init_ctx->init = true; @@ -422,11 +420,9 @@ static inline void upStream(tunnel_t *self, context_t *c) } cstate->init_sent = true; } - else if (dest_context->protocol == IPPROTO_UDP) + else if (dest_context->address_protocol == kSapUdp) { // udp will not call init here since no dest_context addr is available right now - cstate->is_udp_forward = true; - // self->up->packetUpStream(self->up, up_init_ctx); } if (bufLen(c->payload) <= 0) @@ -435,7 +431,7 @@ static inline void upStream(tunnel_t *self, context_t *c) destroyContext(c); return; } - if (dest_context->protocol == IPPROTO_TCP) + if (dest_context->address_protocol == kSapTcp) { if (! cstate->first_sent) { @@ -445,7 +441,7 @@ static inline void upStream(tunnel_t *self, context_t *c) self->up->upStream(self->up, c); return; } - if (dest_context->protocol == IPPROTO_UDP) + if (dest_context->address_protocol == kSapUdp) { bufferStreamPush(cstate->udp_buf, c->payload); c->payload = NULL; @@ -496,7 +492,7 @@ static inline void upStream(tunnel_t *self, context_t *c) { trojan_socks_server_con_state_t *cstate = CSTATE(c); - if (cstate->is_udp_forward) + if (c->line->dest_ctx.address_protocol == kSapUdp) { bufferStreamPush(cstate->udp_buf, c->payload); c->payload = NULL; @@ -537,7 +533,7 @@ static inline void upStream(tunnel_t *self, context_t *c) CSTATE_MUT(c) = malloc(sizeof(trojan_socks_server_con_state_t)); memset(CSTATE(c), 0, sizeof(trojan_socks_server_con_state_t)); trojan_socks_server_con_state_t *cstate = CSTATE(c); - cstate->udp_buf = newBufferStream(buffer_pools[c->line->tid]); + cstate->udp_buf = newBufferStream(getContextBufferPool(c)); allocateDomainBuffer(&(c->line->dest_ctx)); destroyContext(c); } @@ -545,20 +541,12 @@ static inline void upStream(tunnel_t *self, context_t *c) { trojan_socks_server_con_state_t *cstate = CSTATE(c); bool init_sent = cstate->init_sent; - bool is_udp = cstate->is_udp_forward; destroyBufferStream(cstate->udp_buf); free(cstate); CSTATE_MUT(c) = NULL; if (init_sent) { - if (is_udp) - { - self->up->packetUpStream(self->up, c); - } - else - { - self->up->upStream(self->up, c); - } + self->up->upStream(self->up, c); } else { @@ -570,7 +558,7 @@ static inline void upStream(tunnel_t *self, context_t *c) static inline void downStream(tunnel_t *self, context_t *c) { - trojan_socks_server_con_state_t *cstate = CSTATE(c); + trojan_socks_server_con_state_t *cstate = CSTATE(c); if (c->fin) { @@ -580,44 +568,23 @@ static inline void downStream(tunnel_t *self, context_t *c) self->dw->downStream(self->dw, c); return; } - if (cstate->is_udp_forward && c->payload != NULL) + if (c->line->dest_ctx.address_protocol == kSapUdp && c->payload != NULL) { makeUdpPacketAddress(c); } self->dw->downStream(self->dw, c); } -static void trojanSocksServerUpStream(tunnel_t *self, context_t *c) -{ - upStream(self, c); -} -static void trojanSocksServerPacketUpStream(tunnel_t *self, context_t *c) -{ - if (c->init || c->first) - { - LOGE("TrojanSocksServer: trojan protocol is not meant to work on top of udp"); - } - upStream(self, c); -} -static void trojanSocksServerDownStream(tunnel_t *self, context_t *c) -{ - downStream(self, c); -} -static void trojanSocksServerPacketDownStream(tunnel_t *self, context_t *c) -{ - downStream(self, c); -} - tunnel_t *newTrojanSocksServer(node_instance_context_t *instance_info) { (void) instance_info; trojan_socks_server_state_t *state = malloc(sizeof(trojan_socks_server_state_t)); memset(state, 0, sizeof(trojan_socks_server_state_t)); - tunnel_t *t = newTunnel(); - t->state = state; - t->upStream = &upStream; - t->downStream = &downStream; + tunnel_t *t = newTunnel(); + t->state = state; + t->upStream = &upStream; + t->downStream = &downStream; atomic_thread_fence(memory_order_release); return t; } @@ -625,7 +592,9 @@ api_result_t apiTrojanSocksServer(tunnel_t *self, const char *msg) { (void) self; (void) msg; - (void)(self); (void)(msg); return (api_result_t){0}; // TODO(root): + (void) (self); + (void) (msg); + return (api_result_t){0}; // TODO(root): } tunnel_t *destroyTrojanSocksServer(tunnel_t *self) diff --git a/tunnels/server/wolfssl/CMakeLists.txt b/tunnels/server/wolfssl/CMakeLists.txt index 06a9372c..c50ffa56 100644 --- a/tunnels/server/wolfssl/CMakeLists.txt +++ b/tunnels/server/wolfssl/CMakeLists.txt @@ -4,55 +4,62 @@ add_library(WolfSSLServer STATIC wolfssl_server.c ) -#cmake is not able to build fastest version of wolfssl yet (because all asm options are not provided in cmakelist), we used this: -# ./configure --enable-distro --enable-sp=rsa2048,asm --enable-harden --enable-static --enable-fast-rsa --enable-opensslall --enable-opensslextra --enable-tls13 --disable-oldtls --enable-intelasm --enable-aesni -# generate configure with autoreconf -i (sudo apt-get install autoconf) (sudo apt-get install libtool-bin) -# Note: before configure, add -# AC_DEFINE([NO_WOLFSSL_STUB], [1], [Description here]) -# to configure.ac ! - -# if compiling for ARM: ./configure --enable-distro --enable-sp=rsa2048,asm --enable-harden --enable-static --enable-fast-rsa --enable-opensslall --enable-opensslextra --enable-tls13 --disable-oldtls -# /src/.libs/libwolfssl.a +# This paragraph is disabled since wolfssl 5.7 update now has much better cmake interface +## ./configure --enable-distro --enable-sp=rsa2048,asm --enable-harden --enable-static --enable-fast-rsa --enable-opensslall --enable-opensslextra --enable-tls13 --disable-oldtls --enable-intelasm --enable-aesni +## generate configure with autoreconf -i (sudo apt-get install autoconf) (sudo apt-get install libtool-bin) +## Note: before configure, add +## AC_DEFINE([NO_WOLFSSL_STUB], [1], [Description here]) +## to configure.ac ! +## if compiling for ARM: ./configure --enable-distro --enable-sp=rsa2048,asm --enable-harden --enable-static --enable-fast-rsa --enable-opensslall --enable-opensslextra --enable-tls13 --disable-oldtls +## libs will be saved at: /src/.libs/libwolfssl.a #ww api target_include_directories(WolfSSLServer PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../ww) target_link_libraries(WolfSSLServer ww) -# todo select correct processor -if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "aarch64") -target_link_libraries(WolfSSLServer libwolfssl_arm64.a) -else() -target_link_libraries(WolfSSLServer libwolfssl_amd64.a) -endif() -target_include_directories(WolfSSLServer PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../shared/wolfssl) +target_include_directories(WolfSSLServer PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../shared/wolfssl) # add dependencies include(${CMAKE_BINARY_DIR}/cmake/CPM.cmake) - +# todo (WOLFSSL_CRYPTOCB) check this option doing anything useful and required or not (enables padding settings like openssl?) CPMAddPackage( NAME wolfssl VERSION 5.6.6-stable GITHUB_REPOSITORY wolfSSL/wolfssl OPTIONS + "WOLFSSL_REPRODUCIBLE_BUILD ON" + "WOLFSSL_ALPN ON" + "WOLFSSL_HARDEN ON" "WOLFSSL_OPENSSLEXTRA ON" "WOLFSSL_OPENSSLALL ON" + "WOLFSSL_SNI ON" + "WOLFSSL_SESSION_TICKET ON" "WOLFSSL_EXAMPLES OFF" "WOLFSSL_CRYPT_TESTS OFF" - "WOLFSSL_EXAMPLES OFF" - "WOLFSSL_EXAMPLES OFF" + "WOLFSSL_ASYNC_THREADS OFF" "BUILD_SHARED_LIBS OFF" ) - +target_compile_definitions(wolfssl PRIVATE NO_WOLFSSL_STUB=1) target_compile_definitions(WolfSSLServer PRIVATE WolfSSLServer_VERSION=0.1) - - if(CMAKE_BUILD_TYPE STREQUAL "Debug") target_compile_definitions(WolfSSLServer PRIVATE DEBUG=1) endif() -target_include_directories(WolfSSLServer PRIVATE $) + + +# this code is used for linking with prebuilt .a (which you built with autoconf) +# target_link_directories(WolfSSLServer PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../shared/wolfssl) +# if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "aarch64") +# target_link_libraries(WolfSSLServer libwolfssl_arm64.a) +# else() +# target_link_libraries(WolfSSLServer libwolfssl_amd64.a) +# endif() +# target_include_directories(WolfSSLServer PRIVATE $) + +# this code is used for linking with cmake built wolfssl +target_link_libraries(WolfSSLServer wolfssl) diff --git a/tunnels/server/wolfssl/wolfssl_server.c b/tunnels/server/wolfssl/wolfssl_server.c index e654d09c..09c52e7b 100644 --- a/tunnels/server/wolfssl/wolfssl_server.c +++ b/tunnels/server/wolfssl/wolfssl_server.c @@ -236,7 +236,7 @@ static inline void upStream(tunnel_t *self, context_t *c) { do { - shift_buffer_t *buf = popBuffer(buffer_pools[c->line->tid]); + shift_buffer_t *buf = popBuffer(getContextBufferPool(c)); size_t avail = rCap(buf); n = BIO_read(cstate->wbio, rawBufMut(buf), avail); // assert(-1 == BIO_read(cstate->wbio, rawBuf(buf), avail)); @@ -257,12 +257,12 @@ static inline void upStream(tunnel_t *self, context_t *c) { // If BIO_should_retry() is false then the cause is an error condition. reuseContextBuffer(c); - reuseBuffer(buffer_pools[c->line->tid], buf); + reuseBuffer(getContextBufferPool(c), buf); goto disconnect; } else { - reuseBuffer(buffer_pools[c->line->tid], buf); + reuseBuffer(getContextBufferPool(c), buf); } } while (n > 0); } @@ -318,7 +318,7 @@ static inline void upStream(tunnel_t *self, context_t *c) do { - shift_buffer_t *buf = popBuffer(buffer_pools[c->line->tid]); + shift_buffer_t *buf = popBuffer(getContextBufferPool(c)); shiftl(buf, 8192 / 2); setLen(buf, 0); size_t avail = rCap(buf); @@ -344,7 +344,7 @@ static inline void upStream(tunnel_t *self, context_t *c) } else { - reuseBuffer(buffer_pools[c->line->tid], buf); + reuseBuffer(getContextBufferPool(c), buf); } } while (n > 0); @@ -357,7 +357,7 @@ static inline void upStream(tunnel_t *self, context_t *c) { do { - shift_buffer_t *buf = popBuffer(buffer_pools[c->line->tid]); + shift_buffer_t *buf = popBuffer(getContextBufferPool(c)); size_t avail = rCap(buf); n = BIO_read(cstate->wbio, rawBufMut(buf), avail); @@ -378,13 +378,13 @@ static inline void upStream(tunnel_t *self, context_t *c) else if (! BIO_should_retry(cstate->wbio)) { // If BIO_should_retry() is false then the cause is an error condition. - reuseBuffer(buffer_pools[c->line->tid], buf); + reuseBuffer(getContextBufferPool(c), buf); reuseContextBuffer(c); goto failed_after_establishment; } else { - reuseBuffer(buffer_pools[c->line->tid], buf); + reuseBuffer(getContextBufferPool(c), buf); } } while (n > 0); } @@ -410,7 +410,7 @@ static inline void upStream(tunnel_t *self, context_t *c) cstate->rbio = BIO_new(BIO_s_mem()); cstate->wbio = BIO_new(BIO_s_mem()); cstate->ssl = SSL_new(state->ssl_context); - cstate->fallback_buf = newBufferStream(buffer_pools[c->line->tid]); + cstate->fallback_buf = newBufferStream(getContextBufferPool(c)); SSL_set_accept_state(cstate->ssl); /* sets ssl to work in server mode. */ SSL_set_bio(cstate->ssl, cstate->rbio, cstate->wbio); // if (state->anti_tit) @@ -507,7 +507,7 @@ static inline void downStream(tunnel_t *self, context_t *c) do { - shift_buffer_t *buf = popBuffer(buffer_pools[c->line->tid]); + shift_buffer_t *buf = popBuffer(getContextBufferPool(c)); size_t avail = rCap(buf); n = BIO_read(cstate->wbio, rawBufMut(buf), avail); if (n > 0) @@ -527,13 +527,13 @@ static inline void downStream(tunnel_t *self, context_t *c) else if (! BIO_should_retry(cstate->wbio)) { // If BIO_should_retry() is false then the cause is an error condition. - reuseBuffer(buffer_pools[c->line->tid], buf); + reuseBuffer(getContextBufferPool(c), buf); reuseContextBuffer(c); goto failed_after_establishment; } else { - reuseBuffer(buffer_pools[c->line->tid], buf); + reuseBuffer(getContextBufferPool(c), buf); } } while (n > 0); } @@ -685,7 +685,7 @@ tunnel_t *newWolfSSLServer(node_instance_context_t *instance_info) ssl_param->verify_peer = 0; // no mtls ssl_param->endpoint = kSslServer; - state->ssl_context = ssl_ctx_new(ssl_param); + state->ssl_context = sslCtxNew(ssl_param); // int brotli_alg = TLSEXT_comp_cert_brotli; // SSL_set1_cert_comp_preference(state->ssl_context,&brotli_alg,1); // SSL_compress_certs(state->ssl_context,TLSEXT_comp_cert_brotli); @@ -700,7 +700,7 @@ tunnel_t *newWolfSSLServer(node_instance_context_t *instance_info) return NULL; } - SSL_CTX_set_alpn_select_cb(state->ssl_context, on_alpn_select, NULL); + SSL_CTX_set_alpn_select_cb(state->ssl_context, onAlpnSelect, NULL); tunnel_t *t = newTunnel(); t->state = state; @@ -718,9 +718,6 @@ api_result_t apiWolfSSLServer(tunnel_t *self, const char *msg) { (void) self; (void) msg; - - (void) (self); - (void) (msg); return (api_result_t){0}; } diff --git a/tunnels/shared/protobuf/uleb128.h b/tunnels/shared/protobuf/uleb128.h index c1000d34..c9c9627b 100644 --- a/tunnels/shared/protobuf/uleb128.h +++ b/tunnels/shared/protobuf/uleb128.h @@ -39,7 +39,7 @@ static inline size_t readUleb128ToUint64(const unsigned char *restrict buffer_st return p - buffer_start; } -// writes and moves to right, use size_uleb128 to calculate the len before write +// writes and moves to right, use sizeUleb128 to calculate the len before write static inline void writeUleb128(unsigned char *p, size_t val) { unsigned char c; diff --git a/tunnels/shared/trojan/sha2.c b/tunnels/shared/trojan/sha2.c index b85f30c2..45773c7a 100644 --- a/tunnels/shared/trojan/sha2.c +++ b/tunnels/shared/trojan/sha2.c @@ -542,9 +542,9 @@ void sha224(const uint8 *message, uint64 len, uint8 *digest) { sha224_ctx ctx; - sha224_init(&ctx); - sha224_update(&ctx, message, len); - sha224_final(&ctx, digest); + sha224Init(&ctx); + sha224Update(&ctx, message, len); + sha224Final(&ctx, digest); } void sha224Init(sha224_ctx *ctx) @@ -653,9 +653,9 @@ void sha256(const uint8 *message, uint64 len, uint8 *digest) { sha256_ctx ctx; - sha256_init(&ctx); - sha256_update(&ctx, message, len); - sha256_final(&ctx, digest); + sha256Init(&ctx); + sha256Update(&ctx, message, len); + sha256Final(&ctx, digest); } void sha256Init(sha256_ctx *ctx) @@ -765,9 +765,9 @@ void sha384(const uint8 *message, uint64 len, uint8 *digest) { sha384_ctx ctx; - sha384_init(&ctx); - sha384_update(&ctx, message, len); - sha384_final(&ctx, digest); + sha384Init(&ctx); + sha384Update(&ctx, message, len); + sha384Final(&ctx, digest); } void sha384Init(sha384_ctx *ctx) @@ -875,9 +875,9 @@ void sha512(const uint8 *message, uint64 len, uint8 *digest) { sha512_ctx ctx; - sha512_init(&ctx); - sha512_update(&ctx, message, len); - sha512_final(&ctx, digest); + sha512Init(&ctx); + sha512Update(&ctx, message, len); + sha512Final(&ctx, digest); } void sha512Init(sha512_ctx *ctx) @@ -1020,12 +1020,12 @@ static void test_sha224_long_message(uint8 *digest) memset(message, 'a', sizeof(message)); - sha224_init(&ctx); + sha224Init(&ctx); for (i = 0; i < 10000000; i++) { - sha224_update(&ctx, message, sizeof(message)); + sha224Update(&ctx, message, sizeof(message)); } - sha224_final(&ctx, digest); + sha224Final(&ctx, digest); } static void test_sha256_long_message(uint8 *digest) @@ -1036,12 +1036,12 @@ static void test_sha256_long_message(uint8 *digest) memset(message, 'a', sizeof(message)); - sha256_init(&ctx); + sha256Init(&ctx); for (i = 0; i < 10000000; i++) { - sha256_update(&ctx, message, sizeof(message)); + sha256Update(&ctx, message, sizeof(message)); } - sha256_final(&ctx, digest); + sha256Final(&ctx, digest); } static void test_sha384_long_message(uint8 *digest) @@ -1052,12 +1052,12 @@ static void test_sha384_long_message(uint8 *digest) memset(message, 'a', sizeof(message)); - sha384_init(&ctx); + sha384Init(&ctx); for (i = 0; i < 10000000; i++) { - sha384_update(&ctx, message, sizeof(message)); + sha384Update(&ctx, message, sizeof(message)); } - sha384_final(&ctx, digest); + sha384Final(&ctx, digest); } static void test_sha512_long_message(uint8 *digest) @@ -1068,12 +1068,12 @@ static void test_sha512_long_message(uint8 *digest) memset(message, 'a', sizeof(message)); - sha512_init(&ctx); + sha512Init(&ctx); for (i = 0; i < 10000000; i++) { - sha512_update(&ctx, message, sizeof(message)); + sha512Update(&ctx, message, sizeof(message)); } - sha512_final(&ctx, digest); + sha512Final(&ctx, digest); } #endif /* TEST_VECTORS_LONG */ diff --git a/tunnels/shared/wolfssl/libwolfssl_arm64.a b/tunnels/shared/wolfssl/libwolfssl_arm64.a index c8b54875..4fa4acac 100644 Binary files a/tunnels/shared/wolfssl/libwolfssl_arm64.a and b/tunnels/shared/wolfssl/libwolfssl_arm64.a differ diff --git a/tunnels/shared/wolfssl/wolfssl_globals.h b/tunnels/shared/wolfssl/wolfssl_globals.h index 1bd2b2ff..66717454 100644 --- a/tunnels/shared/wolfssl/wolfssl_globals.h +++ b/tunnels/shared/wolfssl/wolfssl_globals.h @@ -2,11 +2,11 @@ #include "loggers/network_logger.h" #include "cacert.h" +#include #include #include #include #include -#include enum { kSslServer = 0, @@ -15,7 +15,7 @@ enum static int wolfssl_lib_initialized = false; -static void opensslGlobalInit() +static void wolfSslGlobalInit() { if (wolfssl_lib_initialized == 0) { @@ -50,7 +50,7 @@ typedef void *ssl_ctx_t; ///> SSL_CTX static ssl_ctx_t sslCtxNew(ssl_ctx_opt_t *param) { - opensslGlobalInit(); + wolfSslGlobalInit(); #if OPENSSL_VERSION_NUMBER < 0x10100000L SSL_CTX *ctx = SSL_CTX_new(SSLv23_method()); @@ -152,7 +152,7 @@ static ssl_ctx_t sslCtxNew(ssl_ctx_opt_t *param) static void printSSLState(const SSL *ssl) // NOLINT (ssl in unused problem) { - const char *current_state = SSL_state_string_long(s); + const char *current_state = SSL_state_string_long(ssl); LOGD("%s", current_state); } diff --git a/ww/CMakeLists.txt b/ww/CMakeLists.txt index 4b162826..3033cd2e 100644 --- a/ww/CMakeLists.txt +++ b/ww/CMakeLists.txt @@ -11,6 +11,7 @@ add_library(ww STATIC buffer_pool.c http_def.c cacert.c + sync_dns.c utils/utils.c managers/socket_manager.c managers/node_manager.c diff --git a/ww/buffer_pool.c b/ww/buffer_pool.c index 2ed667e1..4e297713 100644 --- a/ww/buffer_pool.c +++ b/ww/buffer_pool.c @@ -7,76 +7,74 @@ #include "loggers/network_logger.h" #endif -#define LOW_MEMORY 0 // no preallocation (very small) -#define MED1_MEMORY 1 // APPROX 10MB per thread -#define MED2_MEMORY 2 // APPROX 20MB per thread -#define HIG1_MEMORY 3 // APPROX 28MB per thread -#define HIG2_MEMORY 4 // APPROX 36MB per thread -#define MEMORY_PROFILE HIG2_MEMORY +#define LOW_MEMORY 0 // no preallocation (very small) +#define MED1_MEMORY 1 // APPROX 10MB per thread +#define MED2_MEMORY 2 // APPROX 20MB per thread +#define HIG1_MEMORY 3 // APPROX 28MB per thread +#define HIG2_MEMORY 4 // APPROX 36MB per thread + +#define MEMORY_PROFILE HIG2_MEMORY // todo (cmake) #define EVP_READ_BUFSIZE (1U << 15) // 32K -#define BUFFERPOOL_CONTAINER_LEN (50 + (250 * MEMORY_PROFILE)) +#define BUFFERPOOL_CONTAINER_LEN ((16 * 4) + ((16 * 16) * MEMORY_PROFILE)) #define BUFFER_SIZE ((MEMORY_PROFILE < MED2_MEMORY) ? 0 : EVP_READ_BUFSIZE) -static void firstCharge(buffer_pool_t *state) +static void firstCharge(buffer_pool_t *pool) { - // state->chunks = 1; - state->available = malloc(2 * BUFFERPOOL_CONTAINER_LEN * sizeof(shift_buffer_t *)); - for (size_t i = 0; i < BUFFERPOOL_CONTAINER_LEN; i++) { - state->available[i] = newShiftBuffer(BUFFER_SIZE); + pool->available[i] = newShiftBuffer(BUFFER_SIZE); } - state->len = BUFFERPOOL_CONTAINER_LEN; + pool->len = BUFFERPOOL_CONTAINER_LEN; } -static void reCharge(buffer_pool_t *state) +static void reCharge(buffer_pool_t *pool) { - const size_t increase = min((2 * BUFFERPOOL_CONTAINER_LEN - state->len), BUFFERPOOL_CONTAINER_LEN); - for (size_t i = state->len; i < (state->len + increase); i++) + const size_t increase = min((2 * BUFFERPOOL_CONTAINER_LEN - pool->len), BUFFERPOOL_CONTAINER_LEN); + for (size_t i = pool->len; i < (pool->len + increase); i++) { - state->available[i] = newShiftBuffer(BUFFER_SIZE); + pool->available[i] = newShiftBuffer(BUFFER_SIZE); } - state->len += increase; + pool->len += increase; #ifdef DEBUG - LOGD("BufferPool: allocated %d new buffers, %zu are in use", increase, state->in_use); + LOGD("BufferPool: allocated %d new buffers, %zu are in use", increase, pool->in_use); #endif } -static void giveMemBackToOs(buffer_pool_t *state) +static void giveMemBackToOs(buffer_pool_t *pool) { - const size_t decrease = min(state->len, BUFFERPOOL_CONTAINER_LEN); + const size_t decrease = min(pool->len, BUFFERPOOL_CONTAINER_LEN); - for (size_t i = state->len - decrease; i < state->len; i++) + for (size_t i = pool->len - decrease; i < pool->len; i++) { - destroyShiftBuffer(state->available[i]); + destroyShiftBuffer(pool->available[i]); } - state->len -= decrease; + pool->len -= decrease; #ifdef DEBUG - LOGD("BufferPool: freed %d buffers, %zu are in use", decrease, state->in_use); + LOGD("BufferPool: freed %d buffers, %zu are in use", decrease, pool->in_use); #endif malloc_trim(0); // y tho? } -shift_buffer_t *popBuffer(buffer_pool_t *state) +shift_buffer_t *popBuffer(buffer_pool_t *pool) { // return newShiftBuffer(BUFFER_SIZE); - if (state->len <= 0) + if (pool->len <= 0) { - reCharge(state); + reCharge(pool); } - --(state->len); - shift_buffer_t *result = state->available[state->len]; + --(pool->len); + shift_buffer_t *result = pool->available[pool->len]; #ifdef DEBUG - state->in_use += 1; + pool->in_use += 1; #endif return result; } -void reuseBuffer(buffer_pool_t *state, shift_buffer_t *b) +void reuseBuffer(buffer_pool_t *pool, shift_buffer_t *b) { // destroyShiftBuffer(b); // return; @@ -86,27 +84,43 @@ void reuseBuffer(buffer_pool_t *state, shift_buffer_t *b) return; } #ifdef DEBUG - state->in_use -= 1; + pool->in_use -= 1; #endif reset(b, BUFFER_SIZE); - state->available[state->len] = b; - ++(state->len); - if (state->len > BUFFERPOOL_CONTAINER_LEN + (BUFFERPOOL_CONTAINER_LEN / 2)) + pool->available[pool->len] = b; + ++(pool->len); + if (pool->len > (BUFFERPOOL_CONTAINER_LEN + (BUFFERPOOL_CONTAINER_LEN / 2))) { - giveMemBackToOs(state); + giveMemBackToOs(pool); } } -buffer_pool_t *createBufferPool() +shift_buffer_t *appendBufferMerge(buffer_pool_t *pool, shift_buffer_t *restrict b1, shift_buffer_t *restrict b2) { - buffer_pool_t *state = malloc(sizeof(buffer_pool_t)); - memset(state, 0, sizeof(buffer_pool_t)); + unsigned int b1_length = bufLen(b1); + unsigned int b2_length = bufLen(b2); + if (b1_length >= b2_length) + { + appendBuffer(b1, b2); + reuseBuffer(pool, b2); + return b1; + } + shiftl(b2, b1_length); + memcpy(rawBufMut(b2), rawBuf(b1), b1_length); + reuseBuffer(pool, b1); + return b2; +} - state->available = 0; - state->len = 0; +buffer_pool_t *createBufferPool() +{ + const int container_len = 2 * BUFFERPOOL_CONTAINER_LEN * sizeof(shift_buffer_t *); + buffer_pool_t *pool = malloc(sizeof(buffer_pool_t) + container_len); #ifdef DEBUG - state->in_use = 0; + memset(pool, 0xEE, sizeof(buffer_pool_t) + container_len); + pool->in_use = 0; #endif - firstCharge(state); - return state; + memset(pool, 0, sizeof(buffer_pool_t)); + pool->len = 0; + firstCharge(pool); + return pool; } diff --git a/ww/buffer_pool.h b/ww/buffer_pool.h index 42500344..be7b373e 100644 --- a/ww/buffer_pool.h +++ b/ww/buffer_pool.h @@ -6,31 +6,31 @@ #endif struct buffer_pool_s { - shift_buffer_t **available; - unsigned int len; + unsigned int len; #ifdef DEBUG atomic_size_t in_use; #endif + shift_buffer_t *available[]; }; typedef struct buffer_pool_s buffer_pool_t; buffer_pool_t * createBufferPool(); -shift_buffer_t *popBuffer(buffer_pool_t *state); -void reuseBuffer(buffer_pool_t *state, shift_buffer_t *b); - +shift_buffer_t *popBuffer(buffer_pool_t *pool); +void reuseBuffer(buffer_pool_t *pool, shift_buffer_t *b); +shift_buffer_t *appendBufferMerge(buffer_pool_t *pool, shift_buffer_t *restrict b1, shift_buffer_t *restrict b2); // [not used] when you change the owner thread of a buffer, you should // notify the original buffer pool that 1 buffer is lost form it // this however, is not used #ifdef DEBUG -static inline void notifyDetached(buffer_pool_t *state) +static inline void notifyDetached(buffer_pool_t *pool) { - state->in_use -= 1; + pool->in_use -= 1; } #else -static inline void notifyDetached(buffer_pool_t *state) +static inline void notifyDetached(buffer_pool_t *pool) { - (void) state; + (void) pool; } #endif diff --git a/ww/library_loader.h b/ww/library_loader.h index 3c664c26..b853be31 100644 --- a/ww/library_loader.h +++ b/ww/library_loader.h @@ -8,7 +8,7 @@ typedef struct tunnel_lib_s { hash_t hash_name; struct tunnel_s *(*creation_proc)(node_instance_context_t *instance_info); - api_result_t (*api_proc)(struct tunnel_s *instance, char *msg); + api_result_t (*api_proc)(struct tunnel_s *instance,const char *msg); struct tunnel_s *(*destroy_proc)(struct tunnel_s *instance); tunnel_metadata_t (*getmetadata_proc)(); diff --git a/ww/managers/node_manager.c b/ww/managers/node_manager.c index a524efff..6647aaa3 100644 --- a/ww/managers/node_manager.c +++ b/ww/managers/node_manager.c @@ -64,12 +64,14 @@ void runNode(node_t *n1, size_t chain_index) static void runNodes() { +begin:; c_foreach(p1, map_node_t, state->node_map) { node_t *n1 = p1.ref->second; if (n1 != NULL && n1->instance == NULL && n1->route_starter == true) { runNode(n1, 0); + goto begin; } } } @@ -138,7 +140,7 @@ static void cycleProcess() bool found = false; c_foreach(n1, map_node_t, state->node_map) { - if ((n1.ref->second->metadata.flags & TFLAG_ROUTE_STARTER) == TFLAG_ROUTE_STARTER) + if ((n1.ref->second->metadata.flags & kNodeFlagChainHead) == kNodeFlagChainHead) { found = true; n1.ref->second->route_starter = true; @@ -146,18 +148,61 @@ static void cycleProcess() } if (! found) { - LOGW("Node Map has detecetd 0 listener nodes..."); + LOGW("NodeMap: detecetd 0 chainhead nodes, the"); } } } +void registerNode(node_t *new_node, cJSON *node_settings) +{ + new_node->hash_name = CALC_HASH_BYTES(new_node->name, strlen(new_node->name)); + new_node->hash_type = CALC_HASH_BYTES(new_node->type, strlen(new_node->type)); + if (new_node->next) + { + new_node->hash_next = CALC_HASH_BYTES(new_node->next, strlen(new_node->next)); + } + // load lib + tunnel_lib_t lib = loadTunnelLibByHash(new_node->hash_type); + if (lib.hash_name == 0) + { + LOGF("NodeManager: node creation failure: library \"%s\" (hash: %lx) could not be loaded ", new_node->type, + new_node->hash_type); + exit(1); + } + else + { + LOGD("%-18s: library \"%s\" loaded successfully", new_node->name, new_node->type); + } + new_node->metadata = lib.getmetadata_proc(); + struct tunnel_lib_s *heap_lib = malloc(sizeof(struct tunnel_lib_s)); + memset(heap_lib, 0, sizeof(struct tunnel_lib_s)); + *heap_lib = lib; + new_node->lib = heap_lib; + + node_instance_context_t new_node_ctx = {0}; + + new_node_ctx.node_json = NULL; + new_node_ctx.node_settings_json = node_settings; + new_node_ctx.node = new_node; + new_node_ctx.node_file_handle = state->config_file; + new_node->instance_context = new_node_ctx; + map_node_t *map = &(state->node_map); + + if (map_node_t_contains(map, new_node->hash_name)) + { + LOGF("NodeManager: duplicate node \"%s\" (hash: %lx) ", new_node->name, new_node->hash_name); + exit(1); + } + map_node_t_insert(map, new_node->hash_name, new_node); +} + + static void startParsingFiles() { cJSON *nodes_json = state->config_file->nodes; cJSON *node_json = NULL; cJSON_ArrayForEach(node_json, nodes_json) { - node_t *new_node = malloc(sizeof(node_t)); memset(new_node, 0, sizeof(node_t)); if (! getStringFromJsonObject(&(new_node->name), node_json, "name")) @@ -166,7 +211,6 @@ static void startParsingFiles() state->config_file->file_path); exit(1); } - new_node->hash_name = CALC_HASH_BYTES(new_node->name, strlen(new_node->name)); if (! getStringFromJsonObject(&(new_node->type), node_json, "type")) { @@ -174,53 +218,9 @@ static void startParsingFiles() state->config_file->file_path); exit(1); } - new_node->hash_type = CALC_HASH_BYTES(new_node->type, strlen(new_node->type)); - - if (getStringFromJsonObject(&(new_node->next), node_json, "next")) - { - new_node->hash_next = CALC_HASH_BYTES(new_node->next, strlen(new_node->next)); - } - int int_ver = 0; - if (getIntFromJsonObject(&int_ver, node_json, "version")) - { - new_node->version = int_ver; - } - - // load lib - tunnel_lib_t lib = loadTunnelLibByHash(new_node->hash_type); - if (lib.hash_name == 0) - { - LOGF("NodeManager: node creation failure: library \"%s\" (hash: %lx) could not be loaded ", new_node->type, - new_node->hash_type); - exit(1); - } - else - { - LOGD("%-18s: library \"%s\" loaded successfully", new_node->name, new_node->type); - } - new_node->metadata = lib.getmetadata_proc(); - struct tunnel_lib_s *heap_lib = malloc(sizeof(struct tunnel_lib_s)); - memset(heap_lib, 0, sizeof(struct tunnel_lib_s)); - *heap_lib = lib; - new_node->lib = heap_lib; - - cJSON *js_settings = cJSON_GetObjectItemCaseSensitive(node_json, "settings"); - - node_instance_context_t new_node_ctx = {0}; - - new_node_ctx.node_json = node_json; - new_node_ctx.node_settings_json = js_settings; - new_node_ctx.self_node_handle = new_node; - new_node_ctx.self_file_handle = state->config_file; - new_node->instance_context = new_node_ctx; - map_node_t *map = &(state->node_map); - - if (map_node_t_contains(map, new_node->hash_name)) - { - LOGF("NodeManager: duplicate node \"%s\" (hash: %lx) ", new_node->name, new_node->hash_name); - exit(1); - } - map_node_t_insert(map, new_node->hash_name, new_node); + getStringFromJsonObject(&(new_node->next), node_json, "next"); + getIntFromJsonObjectOrDefault(&(new_node->version), node_json, "version", 0); + registerNode(new_node, cJSON_GetObjectItemCaseSensitive(node_json, "settings")); } cycleProcess(); pathWalk(); diff --git a/ww/managers/node_manager.h b/ww/managers/node_manager.h index 1a2d2166..88b98372 100644 --- a/ww/managers/node_manager.h +++ b/ww/managers/node_manager.h @@ -24,6 +24,7 @@ struct node_manager_s; void runNode(node_t *n1, size_t chain_index); node_t * getNode(hash_t hash_node_name); +void registerNode(node_t *new_node, cJSON *node_settings); void runConfigFile(config_file_t *config_file); struct node_manager_s *getNodeManager(); void setNodeManager(struct node_manager_s *state); diff --git a/ww/node.h b/ww/node.h index 70af2c11..f0884d9c 100644 --- a/ww/node.h +++ b/ww/node.h @@ -4,37 +4,42 @@ typedef struct node_instance_context_s { - struct cJSON *node_json; - struct cJSON *node_settings_json; // node_json -> settings - struct node_s *self_node_handle; - struct config_file_s *self_file_handle; - size_t chain_index; + struct cJSON * node_json; + struct cJSON * node_settings_json; // node_json -> settings + struct config_file_s *node_file_handle; + struct node_s * node; + size_t chain_index; } node_instance_context_t; +enum node_flags +{ + kNodeFlagNone = (1 << 0), + // this node can be a chain head (begin of the chain) + kNodeFlagChainHead = (1 << 1) + +}; typedef struct tunnel_metadata_s { - int32_t version; - int32_t flags; + int32_t version; + enum node_flags flags; } tunnel_metadata_t; -#define TFLAG_ROUTE_STARTER (1 << 0) - typedef struct node_s { - char *name; + char * name; hash_t hash_name; - char *type; + char * type; hash_t hash_type; - char *next; + char * next; hash_t hash_next; - size_t version; + uint32_t version; //------------ evaluated: - size_t refrenced; - bool route_starter; + uint32_t refrenced; + bool route_starter; - tunnel_metadata_t metadata; - struct tunnel_lib_s *lib; + tunnel_metadata_t metadata; + struct tunnel_lib_s * lib; node_instance_context_t instance_context; - struct tunnel_s *instance; + struct tunnel_s * instance; } node_t; diff --git a/ww/shiftbuffer.c b/ww/shiftbuffer.c index 9642403a..fed94eff 100644 --- a/ww/shiftbuffer.c +++ b/ww/shiftbuffer.c @@ -3,6 +3,7 @@ #include // for assert #include //cel,log2,pow +extern bool isShallow(shift_buffer_t *self); extern unsigned int lCap(shift_buffer_t *self); extern unsigned int rCap(shift_buffer_t *self); extern unsigned int bufLen(shift_buffer_t *self); @@ -139,3 +140,11 @@ void expand(shift_buffer_t *self, unsigned int increase) free(old_buf); } } + +void appendBuffer(shift_buffer_t *restrict root, shift_buffer_t *restrict buf) +{ + unsigned int root_length = bufLen(root); + unsigned int append_length = bufLen(buf); + setLen(root, root_length + append_length); + memcpy(rawBufMut(root) + root_length, rawBuf(buf), append_length); +} diff --git a/ww/shiftbuffer.h b/ww/shiftbuffer.h index ae3353af..afc0267d 100644 --- a/ww/shiftbuffer.h +++ b/ww/shiftbuffer.h @@ -27,6 +27,7 @@ shift_buffer_t *newShallowShiftBuffer(shift_buffer_t *owner); void reset(shift_buffer_t *self, unsigned int cap); void unShallow(shift_buffer_t *self); void expand(shift_buffer_t *self, unsigned int increase); +void appendBuffer(shift_buffer_t * restrict root, shift_buffer_t * restrict buf); inline bool isShallow(shift_buffer_t *self) { @@ -107,10 +108,9 @@ inline void readUI16(shift_buffer_t *self, uint16_t *dest) memcpy(dest, rawBuf(self), sizeof(uint16_t)); } - /* Call setLen to know how much memory you own before any kind of writing -*/ +*/ inline unsigned char *rawBufMut(shift_buffer_t *self) { @@ -146,4 +146,3 @@ inline void writeUI8(shift_buffer_t *self, uint8_t data) { writeRaw(self, &data, sizeof(uint8_t)); } - diff --git a/ww/sync_dns.c b/ww/sync_dns.c index b520358d..144c3fee 100644 --- a/ww/sync_dns.c +++ b/ww/sync_dns.c @@ -13,7 +13,7 @@ bool resolveContextSync(socket_context_t *sctx) #endif /* resolve domain */ { - if (sockaddr_set_ip_port(&(sctx->addr), sctx->domain, old_port) != 0) + if (sockaddr_set_ipport(&(sctx->addr), sctx->domain, old_port) != 0) { LOGE("SyncDns: resolve failed %s", sctx->domain); return false; diff --git a/ww/tunnel.c b/ww/tunnel.c index 3142e487..e1639888 100644 --- a/ww/tunnel.c +++ b/ww/tunnel.c @@ -1,16 +1,26 @@ #include "tunnel.h" #include "string.h" // memset -extern line_t * newLine(uint16_t tid); -extern uint8_t reserveChainStateIndex(line_t *l); -extern void destroyLine(line_t *l); -extern void destroyContext(context_t *c); -extern context_t *newContext(line_t *line); -extern context_t *newContextFrom(context_t *source); -extern context_t *newEstContext(line_t *line); -extern context_t *newFinContext(line_t *line); -extern context_t *newInitContext(line_t *line); -extern context_t *switchLine(context_t *c, line_t *line); +extern line_t * newLine(uint8_t tid); +extern uint8_t reserveChainStateIndex(line_t *l); +extern void destroyLine(line_t *l); +extern void destroyContext(context_t *c); +extern void internalUnRefLine(line_t *l); +extern bool isAlive(line_t *line); +extern void reuseContextBuffer(context_t *c); +extern bool isFullyAuthenticated(line_t *line); +extern bool isAuthenticated(line_t *line); +extern void markAuthenticated(line_t *line); +extern void markAuthenticationNodePresence(line_t *line); +extern context_t * newContext(line_t *line); +extern context_t * newContextFrom(context_t *source); +extern context_t * newEstContext(line_t *line); +extern context_t * newFinContext(line_t *line); +extern context_t * newInitContext(line_t *line); +extern context_t * switchLine(context_t *c, line_t *line); +extern buffer_pool_t *geBufferPool(uint8_t tid); +extern buffer_pool_t *getLineBufferPool(line_t *l); +extern buffer_pool_t *getContextBufferPool(context_t *c); // `from` upstreams to `to` void chainUp(tunnel_t *from, tunnel_t *to) @@ -21,7 +31,7 @@ void chainUp(tunnel_t *from, tunnel_t *to) void chainDown(tunnel_t *from, tunnel_t *to) { assert(to->dw == NULL); // 2 nodes cannot chain to 1 exact node - to->dw = from; + to->dw = from; } // `from` <-> `to` void chain(tunnel_t *from, tunnel_t *to) @@ -29,7 +39,6 @@ void chain(tunnel_t *from, tunnel_t *to) chainUp(from, to); chainDown(from, to); to->chain_index = from->chain_index + 1; - } tunnel_t *newTunnel() diff --git a/ww/tunnel.h b/ww/tunnel.h index 55897c8d..461127ca 100644 --- a/ww/tunnel.h +++ b/ww/tunnel.h @@ -14,14 +14,13 @@ typedef struct line_s { - hloop_t *loop; - uint16_t tid; - uint16_t refc; - uint16_t lcid; - uint8_t auth_cur; - uint8_t auth_max; - bool alive; - + uint8_t tid; + uint16_t refc; + uint8_t lcid; + uint8_t auth_cur; + uint8_t auth_max; + bool alive; + hloop_t * loop; socket_context_t src_ctx; socket_context_t dest_ctx; void * chains_state[]; @@ -67,7 +66,7 @@ void chainUp(tunnel_t *from, tunnel_t *to); void defaultUpStream(tunnel_t *self, context_t *c); void defaultDownStream(tunnel_t *self, context_t *c); -inline line_t *newLine(uint16_t tid) +inline line_t *newLine(uint8_t tid) { size_t size = sizeof(line_t) + (sizeof(void *) * MAX_CHAIN_LEN); line_t *result = malloc(size); @@ -93,7 +92,7 @@ inline uint8_t reserveChainStateIndex(line_t *l) l->lcid -= 1; return result; } -static inline void internalUnRefLine(line_t *l) +inline void internalUnRefLine(line_t *l) { l->refc -= 1; // check line @@ -204,9 +203,22 @@ inline bool isFullyAuthenticated(line_t *line) return line->auth_cur >= line->auth_max; } + +inline buffer_pool_t *geBufferPool(uint8_t tid) +{ + return buffer_pools[tid]; +} +inline buffer_pool_t *getLineBufferPool(line_t *l) +{ + return buffer_pools[l->tid]; +} +inline buffer_pool_t *getContextBufferPool(context_t *c) +{ + return buffer_pools[c->line->tid]; +} inline void reuseContextBuffer(context_t *c) { assert(c->payload != NULL); - reuseBuffer(buffer_pools[c->line->tid], c->payload); + reuseBuffer(getContextBufferPool(c), c->payload); c->payload = NULL; -} +} \ No newline at end of file diff --git a/ww/utils/sockutils.h b/ww/utils/sockutils.h index d7448154..07c24005 100644 --- a/ww/utils/sockutils.h +++ b/ww/utils/sockutils.h @@ -2,22 +2,22 @@ #include "basic_types.h" #include "hv/hsocket.h" -inline void socketAddrCopy(const sockaddr_u *restrict dest, const sockaddr_u *restrict source) +inline void sockAddrCopy(sockaddr_u *restrict dest, const sockaddr_u *restrict source) { if (source->sa.sa_family == AF_INET) { - memcpy(dest->sin.sin_addr.s_addr, source->sin.sin_addr.s_addr, sizeof(source->sin.sin_addr.s_addr)); + memcpy(&(dest->sin.sin_addr.s_addr), &(source->sin.sin_addr.s_addr), sizeof(source->sin.sin_addr.s_addr)); return; } - memcpy(dest->sin6.sin6_addr.s6_addr, source->sin6.sin6_addr.s6_addr, sizeof(source->sin6.sin6_addr.s6_addr)); + memcpy(&(dest->sin6.sin6_addr.s6_addr), &(source->sin6.sin6_addr.s6_addr), sizeof(source->sin6.sin6_addr.s6_addr)); } -inline bool socketCmpIPV4(const sockaddr_u *restrict addr1, const sockaddr_u *restrict addr2) +inline bool sockAddrCmpIPV4(const sockaddr_u *restrict addr1, const sockaddr_u *restrict addr2) { return (addr1->sin.sin_addr.s_addr == addr2->sin.sin_addr.s_addr); } -inline bool socketCmpIPV6(const sockaddr_u *restrict addr1, const sockaddr_u *restrict addr2) +inline bool sockAddrCmpIPV6(const sockaddr_u *restrict addr1, const sockaddr_u *restrict addr2) { int r = memcmp(addr1->sin6.sin6_addr.s6_addr, addr2->sin6.sin6_addr.s6_addr, sizeof(addr1->sin6.sin6_addr.s6_addr)); if (r != 0) @@ -35,9 +35,14 @@ inline bool socketCmpIPV6(const sockaddr_u *restrict addr1, const sockaddr_u *re return true; } -bool socketCmpIP(const sockaddr_u *restrict addr1, const sockaddr_u *restrict addr2); -void copySocketContextAddr(socket_context_t *dest, const socket_context_t *source); -void copySocketContextPort(socket_context_t *dest, socket_context_t *source); +bool socketCmpIP(const sockaddr_u *restrict addr1, const sockaddr_u *restrict addr2); +void copySocketContextAddr(socket_context_t *dest, const socket_context_t *source); +void copySocketContextPort(socket_context_t *dest, socket_context_t *source); +inline void setSocketContextPort(socket_context_t *dest, uint16_t port) +{ + dest->addr.sin.sin_port = port; +} + enum socket_address_type getHostAddrType(char *host); inline void allocateDomainBuffer(socket_context_t *scontext) @@ -51,10 +56,10 @@ inline void allocateDomainBuffer(socket_context_t *scontext) } } // len is max 255 since it is 8bit -inline void setSocketContextDomain(socket_context_t *restrict scontext, char *restrict domain, uint8_t len) +inline void setSocketContextDomain(socket_context_t *restrict scontext,const char *restrict domain, uint8_t len) { assert(scontext->domain != NULL); - domain[len] = 0x0; memcpy(scontext->domain, domain, len); + scontext->domain[len] = 0x0; scontext->domain_len = len; } \ No newline at end of file diff --git a/ww/utils/utils.c b/ww/utils/utils.c index 5342e4a8..b2e1dff8 100644 --- a/ww/utils/utils.c +++ b/ww/utils/utils.c @@ -12,11 +12,12 @@ #include #include -extern void socketAddrCopy(const sockaddr_u *restrict dest, const sockaddr_u *restrict source); -extern bool socketCmpIPV4(const sockaddr_u *restrict addr1, const sockaddr_u *restrict addr2); -extern bool socketCmpIPV6(const sockaddr_u *restrict addr1, const sockaddr_u *restrict addr2); +extern void sockAddrCopy(sockaddr_u *restrict dest, const sockaddr_u *restrict source); +extern bool sockAddrCmpIPV4(const sockaddr_u *restrict addr1, const sockaddr_u *restrict addr2); +extern bool sockAddrCmpIPV6(const sockaddr_u *restrict addr1, const sockaddr_u *restrict addr2); extern void allocateDomainBuffer(socket_context_t *scontext); -extern void setSocketContextDomain(socket_context_t *restrict scontext, char *restrict domain, uint8_t len); +extern void setSocketContextDomain(socket_context_t *restrict scontext, const char *restrict domain, uint8_t len); +extern void setSocketContextPort(socket_context_t *dest, uint16_t port); char *readFile(const char *const path) { @@ -170,12 +171,12 @@ bool socketCmpIP(const sockaddr_u *restrict addr1, const sockaddr_u *restrict ad } if (addr1->sa.sa_family == AF_INET) { - return socketCmpIPV4(addr1, addr2); + return sockAddrCmpIPV4(addr1, addr2); } if (addr1->sa.sa_family == AF_INET6) { - return socketCmpIPV6(addr1, addr2); + return sockAddrCmpIPV6(addr1, addr2); } assert(! "unknown sa_family"); @@ -186,7 +187,7 @@ bool socketCmpIP(const sockaddr_u *restrict addr1, const sockaddr_u *restrict ad void copySocketContextAddr(socket_context_t *dest, const socket_context_t *const source) { dest->address_protocol = source->address_protocol; - dest->address_type = source->address_type; + dest->address_type = source->address_type; switch (dest->address_type) { case kSatIPV4: @@ -221,9 +222,8 @@ void copySocketContextAddr(socket_context_t *dest, const socket_context_t *const if (source->domain_resolved) { dest->domain_resolved = true; - socketAddrCopy(&(dest->addr), &(source->addr)); + sockAddrCopy(&(dest->addr), &(source->addr)); } - } break; diff --git a/ww/ww.c b/ww/ww.c index 2dd4ef8f..cf37145a 100644 --- a/ww/ww.c +++ b/ww/ww.c @@ -9,26 +9,26 @@ #include "managers/socket_manager.h" unsigned int workers_count = 0; -hthread_t *workers = NULL; -struct hloop_s **loops = NULL; -struct buffer_pool_s **buffer_pools = NULL; +hthread_t * workers = NULL; +struct hloop_s ** loops = NULL; +struct buffer_pool_s ** buffer_pools = NULL; struct socket_manager_s *socekt_manager = NULL; -struct node_manager_s *node_manager = NULL; -logger_t *core_logger = NULL; -logger_t *network_logger = NULL; -logger_t *dns_logger = NULL; +struct node_manager_s * node_manager = NULL; +logger_t * core_logger = NULL; +logger_t * network_logger = NULL; +logger_t * dns_logger = NULL; struct ww_runtime_state_s { unsigned int workers_count; - hthread_t *workers; - struct hloop_s **loops; - struct buffer_pool_s **buffer_pools; + hthread_t * workers; + struct hloop_s ** loops; + struct buffer_pool_s ** buffer_pools; struct socket_manager_s *socekt_manager; - struct node_manager_s *node_manager; - logger_t *core_logger; - logger_t *network_logger; - logger_t *dns_logger; + struct node_manager_s * node_manager; + logger_t * core_logger; + logger_t * network_logger; + logger_t * dns_logger; }; void setWW(struct ww_runtime_state_s *state) @@ -76,7 +76,7 @@ _Noreturn void runMainThread() exit(0); } -static HTHREAD_ROUTINE(worker_thread) //NOLINT +static HTHREAD_ROUTINE(worker_thread) // NOLINT { hloop_t *loop = (hloop_t *) userdata; hloop_run(loop); @@ -107,7 +107,12 @@ void createWW(ww_construction_data_t runtime_data) } workers_count = workers_count; - workers = (hthread_t *) malloc(sizeof(hthread_t) * workers_count); + if (workers_count <= 0 || workers_count > 255) + { + fprintf(stderr, "workers count was not in valid range, value: %u range:[1,255]", workers_count); + } + + workers = (hthread_t *) malloc(sizeof(hthread_t) * workers_count); loops = (hloop_t **) malloc(sizeof(hloop_t *) * workers_count); for (int i = 1; i < workers_count; ++i)