From e99a1447c4c426fb4ed7355162664d256cbc31d3 Mon Sep 17 00:00:00 2001 From: Dmitry Puzyrkov <dmitry.puzyrkov@demlabs.net> Date: Thu, 25 Aug 2022 17:42:55 +0000 Subject: [PATCH] [*] windows-related stuff fixed. --- CMakeLists.txt | 6 +- dap-sdk/io/CMakeLists.txt | 12 +- dap-sdk/io/dap_context.c | 1 - dap-sdk/io/dap_net.c | 4 + dap-sdk/io/dap_server.c | 10 +- dap-sdk/io/dap_timerfd.c | 4 +- dap-sdk/io/dap_worker.c | 2 +- .../net/server/cli_server/dap_cli_server.c | 761 +++++++++--------- dap-sdk/net/server/enc_server/CMakeLists.txt | 28 +- dap-sdk/net/server/http_server/CMakeLists.txt | 28 +- dap-sdk/plugin/CMakeLists.txt | 6 +- 11 files changed, 439 insertions(+), 423 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0cf516a405..536279c694 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -245,9 +245,9 @@ if (CELLFRAME_MODULES MATCHES "modules-dynamic") endif() if (WIN32) - set(CELLFRAME_LIBS ${CELLFRAME_LIBS} KERNEL32 USER32 SHELL32 WINMM GDI32 ADVAPI32 - Ole32 Version Imm32 OleAut32 ws2_32 ntdll psapi - Shlwapi Bcrypt Crypt32 Secur32 userenv mqrt) + set(CELLFRAME_LIBS ${CELLFRAME_LIBS} kernel32 user32 shell32 winmm gdi32 advapi32 + ole32 version imm32 oleaut32 ws2_32 ntdll psapi + shlwapi bcrypt crypt32 secur32 userenv mqrt) endif() if (DARWIN) diff --git a/dap-sdk/io/CMakeLists.txt b/dap-sdk/io/CMakeLists.txt index fc87bf0605..88f6d4d421 100644 --- a/dap-sdk/io/CMakeLists.txt +++ b/dap-sdk/io/CMakeLists.txt @@ -6,8 +6,11 @@ set(CMAKE_C_STANDARD 11) add_definitions ("-D_GNU_SOURCE") if(WIN32) - file(GLOB DAP_IO_SOURCES *.c ../../../3rdparty/wepoll/*.c) - file(GLOB DAP_IO_HEADERS include/*.h ../../../3rdparty/wepoll/*.h) + file(GLOB DAP_IO_SOURCES *.c ${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty/wepoll/*.c) + file(GLOB DAP_IO_HEADERS include/*.h ${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty/wepoll/*.h) + + + else() file(GLOB DAP_IO_SOURCES *.c) file(GLOB DAP_IO_HEADERS include/*.h) @@ -34,10 +37,11 @@ endif() target_include_directories(${PROJECT_NAME} PUBLIC include) target_include_directories(${PROJECT_NAME} PRIVATE src) -target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../3rdparty/uthash/src) +target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty/uthash/src) + if (WIN32) - target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../3rdparty/wepoll) + target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty/wepoll) endif() if (${BUILD_DAP_IO_TESTS} MATCHES ON) diff --git a/dap-sdk/io/dap_context.c b/dap-sdk/io/dap_context.c index 99c1329b3a..8e3625e5ca 100644 --- a/dap-sdk/io/dap_context.c +++ b/dap-sdk/io/dap_context.c @@ -1816,7 +1816,6 @@ dap_events_socket_t * dap_context_create_event(dap_context_t * a_context, dap_ev dap_events_socket_t * dap_context_create_pipe(dap_context_t * a_context, dap_events_socket_callback_t a_callback, uint32_t a_flags) { #ifdef DAP_OS_WINDOWS - UNUSED(a_w); UNUSED(a_callback); UNUSED(a_flags); return NULL; diff --git a/dap-sdk/io/dap_net.c b/dap-sdk/io/dap_net.c index 8625166953..c4b9fb3b9e 100644 --- a/dap-sdk/io/dap_net.c +++ b/dap-sdk/io/dap_net.c @@ -29,6 +29,10 @@ #define LOG_TAG "dap_net" +#ifdef _WIN32 + #define poll WSAPoll +#endif + /** * @brief dap_net_resolve_host * @param a_host hostname diff --git a/dap-sdk/io/dap_server.c b/dap-sdk/io/dap_server.c index f9d38db30e..497b8d062e 100644 --- a/dap-sdk/io/dap_server.c +++ b/dap-sdk/io/dap_server.c @@ -289,10 +289,10 @@ static int s_server_run(dap_server_t * a_server, dap_events_socket_callbacks_t * } #ifdef DAP_EVENTS_CAPS_EPOLL - for(size_t l_worker_id = 0; l_worker_id < dap_events_worker_get_count() ; l_worker_id++){ + for(size_t l_worker_id = 0; l_worker_id < dap_events_thread_get_count() ; l_worker_id++){ dap_worker_t *l_w = dap_events_worker_get(l_worker_id); assert(l_w); - dap_events_socket_t * l_es = dap_events_socket_wrap2( a_server, a_server->events, a_server->socket_listener, &l_callbacks); + dap_events_socket_t * l_es = dap_events_socket_wrap2( a_server, a_server->socket_listener, &l_callbacks); a_server->es_listeners = dap_list_append(a_server->es_listeners, l_es); if (l_es) { @@ -319,6 +319,12 @@ static int s_server_run(dap_server_t * a_server, dap_events_socket_callbacks_t * assert(l_w); dap_events_socket_t * l_es = dap_events_socket_wrap2( a_server, a_server->socket_listener, &l_callbacks); if (l_es) { + #ifdef DAP_EVENTS_CAPS_EPOLL + l_es->ev_base_flags = EPOLLIN; + #ifdef EPOLLEXCLUSIVE + l_es->ev_base_flags |= EPOLLET | EPOLLEXCLUSIVE; + #endif + #endif a_server->es_listeners = dap_list_append(a_server->es_listeners, l_es); l_es->type = a_server->type == SERVER_TCP ? DESCRIPTOR_TYPE_SOCKET_LISTENING : DESCRIPTOR_TYPE_SOCKET_UDP; l_es->_inheritor = a_server; diff --git a/dap-sdk/io/dap_timerfd.c b/dap-sdk/io/dap_timerfd.c index b9323e8ece..a8c494426c 100644 --- a/dap-sdk/io/dap_timerfd.c +++ b/dap-sdk/io/dap_timerfd.c @@ -283,7 +283,7 @@ static void s_es_callback_timer(struct dap_events_socket *a_event_sock) s_timerfd_reset(l_timer_fd, a_event_sock); } else { #ifdef _WIN32 - DeleteTimerQueueTimer(hTimerQueue, l_timerfd->th, NULL); + DeleteTimerQueueTimer(hTimerQueue, l_timer_fd->th, NULL); #endif l_timer_fd->events_socket->flags |= DAP_SOCK_SIGNAL_CLOSE; } @@ -347,7 +347,7 @@ void dap_timerfd_delete(dap_timerfd_t *a_timerfd) if (!a_timerfd) return; #ifdef _WIN32 - DeleteTimerQueueTimer(hTimerQueue, l_timerfd->th, NULL); + DeleteTimerQueueTimer(hTimerQueue, a_timerfd->th, NULL); #endif if (a_timerfd->events_socket->context->worker) dap_events_socket_remove_and_delete_mt(a_timerfd->events_socket->context->worker, a_timerfd->esocket_uuid); diff --git a/dap-sdk/io/dap_worker.c b/dap-sdk/io/dap_worker.c index 0c6133276f..f3a116e183 100644 --- a/dap-sdk/io/dap_worker.c +++ b/dap-sdk/io/dap_worker.c @@ -305,7 +305,7 @@ static bool s_socket_all_check_activity( void * a_arg) //dap_ctime_r(&l_curtime, l_curtimebuf); //log_it(L_DEBUG,"Check sockets activity on worker #%u at %s", l_worker->id, l_curtimebuf); size_t l_esockets_counter = 0; - uint l_esockets_count = HASH_CNT(hh, l_worker->context->esockets); + u_int l_esockets_count = HASH_CNT(hh, l_worker->context->esockets); HASH_ITER(hh, l_worker->context->esockets, l_es, tmp ) { if (l_esockets_counter >= l_worker->context->event_sockets_count || l_esockets_counter >= l_esockets_count){ log_it(L_ERROR, "Something wrong with context's esocket table: %u esockets in context, %u in table but we're on %zu iteration", diff --git a/dap-sdk/net/server/cli_server/dap_cli_server.c b/dap-sdk/net/server/cli_server/dap_cli_server.c index 0d8a22796e..daa4002500 100644 --- a/dap-sdk/net/server/cli_server/dap_cli_server.c +++ b/dap-sdk/net/server/cli_server/dap_cli_server.c @@ -84,6 +84,301 @@ static void* s_thread_main_func(void *args); static inline void s_cmd_add_ex(const char * a_name, dap_cli_server_cmd_callback_ex_t a_func, void *a_arg_func, const char *a_doc, const char *a_doc_ex); +#ifdef _WIN32 + +/** + * @brief p_get_next_str + * + * @param hPipe + * @param dwLen + * @param stop_str + * @param del_stop_str + * @param timeout + * @return char* + */ +char *p_get_next_str( HANDLE hPipe, int *dwLen, const char *stop_str, bool del_stop_str, int timeout ) +{ + UNUSED(timeout); + bool bSuccess = false; + long nRecv = 0; // count of bytes received + size_t stop_str_len = (stop_str) ? strlen(stop_str) : 0; + // if there is nothing to look for + + if(!stop_str_len) + return NULL; + + size_t lpszBuffer_len = 256; + char *lpszBuffer = DAP_NEW_Z_SIZE(char, lpszBuffer_len); + // received string will not be larger than MAX_REPLY_LEN + + while( 1 ) //nRecv < MAX_REPLY_LEN) + { + long ret = 0; + // read one byte +// long ret = s_recv( nSocket, (unsigned char *) (lpszBuffer + nRecv), 1, timeout); + + bSuccess = ReadFile( hPipe, lpszBuffer + nRecv, + lpszBuffer_len - nRecv, (LPDWORD)&ret, NULL ); + + //int ret = recv(nSocket,lpszBuffer+nRecv,1, 0); + if ( ret <= 0 || !bSuccess ) + break; + + nRecv += ret; + //printf("**debug** socket=%d read %d bytes '%0s'",nSocket, ret, (lpszBuffer + nRecv)); + + while((nRecv + 1) >= (long) lpszBuffer_len) + { + lpszBuffer_len *= 2; + lpszBuffer = (char*) realloc(lpszBuffer, lpszBuffer_len); + } + + // search for the required string + if(nRecv >= (long) stop_str_len) { + // found the required string + if(!strncasecmp(lpszBuffer + nRecv - stop_str_len, stop_str, stop_str_len)) { + bSuccess = true; + break; + } + } + }; + + // end reading + + if(bSuccess) { + // delete the searched string + if(del_stop_str) { + lpszBuffer[nRecv - (long) stop_str_len] = '\0'; + if(dwLen) + *dwLen =(int) nRecv - (int) stop_str_len; + } + else { + lpszBuffer[nRecv] = '\0'; + if(dwLen) + *dwLen = (int) nRecv; + } + lpszBuffer = DAP_REALLOC(lpszBuffer,(size_t) *dwLen + 1); + return lpszBuffer; + } + + // in case of an error or missing string + + if(dwLen) + *dwLen = 0; + + free(lpszBuffer); + + return NULL; +} + +/** + * @brief thread_pipe_client_func + * threading function for processing a request from a client + * @param args + * @return void* + */ +static void *thread_pipe_client_func( void *args ) +{ + HANDLE hPipe = (HANDLE)args; + +// SOCKET newsockfd = (SOCKET) (intptr_t) args; + if(s_debug_cli) + log_it(L_INFO, "new connection pipe = %p", hPipe); + + int str_len, marker = 0; + int timeout = 5000; // 5 sec + int argc = 0; + + dap_list_t *cmd_param_list = NULL; + + while( 1 ) + { + // wait data from client +// int is_data = s_poll( newsockfd, timeout ); + // timeout +// if(!is_data) +// continue; + // error (may be socket closed) +// if(is_data < 0) +// break; + +// int is_valid = is_valid_socket(newsockfd); +// if(!is_valid) +// { +// break; +// } + + // receiving http header + char *str_header = p_get_next_str( hPipe, &str_len, "\r\n", true, timeout ); + + // bad format + if(!str_header) + break; + + if ( str_header && strlen(str_header) == 0) { + marker++; + if(marker == 1) + continue; + } + + // filling parameters of command + if ( marker == 1 ) { + cmd_param_list = dap_list_append( cmd_param_list, str_header ); + //printf("g_list_append argc=%d command=%s ", argc, str_header); + argc ++; + } + else + free( str_header ); + + if ( marker == 2 ) { + + dap_list_t *list = cmd_param_list; + // form command + + unsigned int argc = dap_list_length( list ); + // command is found + + if ( argc >= 1) { + + int l_verbose = 0; + char *cmd_name = list->data; + list = dap_list_next( list ); + + // execute command + char *str_cmd = dap_strdup_printf( "%s", cmd_name ); + dap_cli_cmd_t *l_cmd = dap_cli_server_cmd_find( cmd_name ); + int res = -1; + char *str_reply = NULL; + + if ( l_cmd ) { + + while( list ) { + str_cmd = dap_strdup_printf( "%s;%s", str_cmd, list->data ); + list = dap_list_next(list); + } + + log_it(L_INFO, "execute command = %s", str_cmd ); + // exec command + + char **l_argv = dap_strsplit( str_cmd, ";", -1 ); + // Call the command function + + if ( l_cmd && l_argv && l_cmd->func ) { + if (l_cmd->arg_func) { + res = l_cmd->func_ex(argc, l_argv, l_cmd->arg_func, &str_reply); + } else { + res = l_cmd->func(argc, l_argv, &str_reply); + } + } + + else if ( l_cmd ) { + log_it(L_WARNING,"NULL arguments for input for command \"%s\"", str_cmd ); + }else { + log_it(L_WARNING,"No function for command \"%s\" but it registred?!", str_cmd ); + } + + // find '-verbose' command + l_verbose = dap_cli_server_cmd_find_option_val( l_argv, 1, argc, "-verbose", NULL ); + dap_strfreev( l_argv ); + + } else { + str_reply = dap_strdup_printf("can't recognize command = %s", str_cmd ); + log_it( L_ERROR, str_reply ); + } + + char *reply_body; + + if(l_verbose) + reply_body = dap_strdup_printf("%d\r\nret_code: %d\r\n%s\r\n", res, res, (str_reply) ? str_reply : ""); + else + reply_body = dap_strdup_printf("%d\r\n%s\r\n", res, (str_reply) ? str_reply : ""); + + // return the result of the command function + char *reply_str = dap_strdup_printf( "HTTP/1.1 200 OK\r\n" + "Content-Length: %d\r\n\r\n" + "%s", + strlen(reply_body), reply_body ); + + int ret;// = send( newsockfd, reply_str, strlen(reply_str) ,0 ); + + WriteFile( hPipe, reply_str, strlen(reply_str), (LPDWORD)&ret, NULL ); + + DAP_DELETE(str_reply); + DAP_DELETE(reply_str); + DAP_DELETE(reply_body); + + DAP_DELETE(str_cmd); + } + dap_list_free_full(cmd_param_list, free); + break; + } + } + + // close connection +// int cs = closesocket(newsockfd); + + log_it( L_INFO, "close connection pipe = %p", hPipe ); + + FlushFileBuffers( hPipe ); + DisconnectNamedPipe( hPipe ); + CloseHandle( hPipe ); + + return NULL; +} + + +/** + * @brief thread_pipe_func + * main threading server function pipe win32 + * @param args + * @return void* + */ +static void* thread_pipe_func( void *args ) +{ + UNUSED(args); + BOOL fConnected = FALSE; + pthread_t threadId; + HANDLE hPipe = INVALID_HANDLE_VALUE; + static const char *cPipeName = "\\\\.\\pipe\\node_cli.pipe"; + + for (;;) + { +/// printf( "\nPipe Server: Main thread awaiting client connection on %s\n", lpszPipename ); + + hPipe = CreateNamedPipe( + cPipeName, // pipe name + PIPE_ACCESS_DUPLEX, // read/write access + PIPE_TYPE_MESSAGE | // message type pipe + PIPE_READMODE_MESSAGE | // message-read mode + PIPE_WAIT, // blocking mode + PIPE_UNLIMITED_INSTANCES, // max. instances + 4096, // output buffer size + 4096, // input buffer size + 0, // client time-out + NULL ); // default security attribute + + if ( hPipe == INVALID_HANDLE_VALUE ) { + log_it( L_ERROR, "CreateNamedPipe failed, GLE = %lu.\n", GetLastError() ); + return NULL; + } + + fConnected = ConnectNamedPipe( hPipe, NULL ) ? TRUE : ( GetLastError() == ERROR_PIPE_CONNECTED ); + + if ( fConnected ) + { + log_it( L_INFO, "Client %p connected, creating a processing thread.\n", hPipe ); + + pthread_create( &threadId, NULL, thread_pipe_client_func, hPipe ); + pthread_detach( threadId ); + } + else + CloseHandle( hPipe ); + } + + return NULL; +} +#endif + /** * @brief dap_cli_server_init @@ -328,280 +623,62 @@ int res; // feature of disconnection under Unix (QNX) // under Windows, with socket closed res = 0, in Unix res = -1 - char buf[2]; - if ( 0 > (res = recv(sd, buf, 1, MSG_PEEK)) ) // MSG_PEEK The data is treated as unread and the next recv() function shall still return this data. - return false; - - // data in the buffer must be(count_desc>0), but read 0 bytes(res=0) - if(!res && (fds.revents & POLLIN)) - return false; - } - - return true; -} - - -/** - * @brief s_get_next_str - * Reading from the socket till arrival the specified string - * - * stop_str - string to which reading will continue - * del_stop_str - удалÑть ли Ñтроку Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка в конце - * timeout - in ms - * return: string (if waited for final characters) or NULL, if the string requires deletion - * @param nSocket - * @param dwLen - * @param stop_str - * @param del_stop_str - * @param timeout - * @return char* - */ -char* s_get_next_str( SOCKET nSocket, int *dwLen, const char *stop_str, bool del_stop_str, int timeout ) -{ - bool bSuccess = false; - long nRecv = 0; // count of bytes received - size_t stop_str_len = (stop_str) ? strlen(stop_str) : 0; - // if there is nothing to look for - if(!stop_str_len) - return NULL; - size_t lpszBuffer_len = 256; - char *lpszBuffer = DAP_NEW_Z_SIZE(char, lpszBuffer_len); - // received string will not be larger than MAX_REPLY_LEN - - while(1) //nRecv < MAX_REPLY_LEN) - { - // read one byte - long ret = dap_net_recv(nSocket, (unsigned char *) (lpszBuffer + nRecv), 1, timeout); - //int ret = recv(nSocket,lpszBuffer+nRecv,1, 0); - if(ret <= 0) - { - break; - } - nRecv += ret; - //printf("**debug** socket=%d read %d bytes '%0s'",nSocket, ret, (lpszBuffer + nRecv)); - while((nRecv + 1) >= (long) lpszBuffer_len) - { - lpszBuffer_len *= 2; - lpszBuffer = (char*) realloc(lpszBuffer, lpszBuffer_len); - } - // search for the required string - if(nRecv >= (long) stop_str_len) { - // found the required string - if(!strncasecmp(lpszBuffer + nRecv - stop_str_len, stop_str, stop_str_len)) { - bSuccess = true; - break; - } - } - }; - - // end reading - - if(bSuccess) { - // delete the searched string - if(del_stop_str) { - lpszBuffer[nRecv - (long) stop_str_len] = '\0'; - if(dwLen) - *dwLen =(int) nRecv - (int) stop_str_len; - } - else { - lpszBuffer[nRecv] = '\0'; - if(dwLen) - *dwLen = (int) nRecv; - } - char * l_buf_realloc = DAP_REALLOC(lpszBuffer,(size_t) *dwLen + 1); - if( l_buf_realloc) - lpszBuffer = l_buf_realloc; - return lpszBuffer; - } - - // in case of an error or missing string - - if(dwLen) - *dwLen = 0; - - free(lpszBuffer); - - return NULL; -} - -/** - * threading function for processing a request from a client - */ -static void* s_thread_one_client_func(void *args) -{ -SOCKET newsockfd = (SOCKET) (intptr_t) args; -int str_len, marker = 0, timeout = 5000, argc = 0, is_data; -dap_list_t *cmd_param_list = NULL; -char *str_header; - - if(s_debug_cli) - log_it(L_DEBUG, "new connection sockfd=%"DAP_FORMAT_SOCKET, newsockfd); - - - while ( !(0 > (is_data = s_poll(newsockfd, timeout))) ) // wait data from client - { - if ( !(is_data) ) // timeout - continue; - - if ( !is_valid_socket(newsockfd) ) - break; - - // receiving http header - if ( !(str_header = s_get_next_str(newsockfd, &str_len, "\r\n", true, timeout)) ) - break; // bad format - - if(str_header && !strlen(str_header) ) { - marker++; - if(marker == 1){ - DAP_DELETE(str_header); - continue; - } - } - - // filling parameters of command - if(marker == 1) { - cmd_param_list = dap_list_append(cmd_param_list, str_header); - //printf("g_list_append argc=%d command=%s ", argc, str_header); - argc++; - } - else - DAP_DEL_Z(str_header); - - if(marker == 2 && cmd_param_list) { - dap_list_t *list = cmd_param_list; - // form command - argc = dap_list_length(list); - // command is found - if(argc >= 1) { - int l_verbose = 0; - char *cmd_name = list->data; - list = dap_list_next(list); - // execute command - char *str_cmd = dap_strdup_printf("%s", cmd_name); - dap_cli_cmd_t *l_cmd = dap_cli_server_cmd_find(cmd_name); - int res = -1; - char *str_reply = NULL; - if(l_cmd){ - while(list) { - char *str_cmd_prev = str_cmd; - str_cmd = dap_strdup_printf("%s;%s", str_cmd, list->data); - list = dap_list_next(list); - DAP_DELETE(str_cmd_prev); - } - if(l_cmd->overrides.log_cmd_call) - l_cmd->overrides.log_cmd_call(str_cmd); - else - log_it(L_DEBUG, "execute command=%s", str_cmd); - // exec command - - char **l_argv = dap_strsplit(str_cmd, ";", -1); - // Call the command function - if(l_cmd && l_argv && l_cmd->func) { - if (l_cmd->arg_func) { - res = l_cmd->func_ex(argc, l_argv, l_cmd->arg_func, &str_reply); - } else { - res = l_cmd->func(argc, l_argv, &str_reply); - } - } else if (l_cmd) { - log_it(L_WARNING,"NULL arguments for input for command \"%s\"", str_cmd); - }else { - log_it(L_WARNING,"No function for command \"%s\" but it registred?!", str_cmd); - } - // find '-verbose' command - l_verbose = dap_cli_server_cmd_find_option_val(l_argv, 1, argc, "-verbose", NULL); - dap_strfreev(l_argv); - } else { - str_reply = dap_strdup_printf("can't recognize command=%s", str_cmd); - log_it(L_ERROR,"Reply string: \"%s\"", str_reply); - } - char *reply_body; - if(l_verbose) - reply_body = dap_strdup_printf("%d\r\nret_code: %d\r\n%s\r\n", res, res, (str_reply) ? str_reply : ""); - else - reply_body = dap_strdup_printf("%d\r\n%s\r\n", res, (str_reply) ? str_reply : ""); - // return the result of the command function - char *reply_str = dap_strdup_printf("HTTP/1.1 200 OK\r\n" - "Content-Length: %d\r\n\r\n" - "%s", strlen(reply_body), reply_body); - size_t l_reply_step = 32768; - size_t l_reply_len = strlen(reply_str); - size_t l_reply_rest = l_reply_len; - - while(l_reply_rest) { - size_t l_send_bytes = min(l_reply_step, l_reply_rest); - int ret = send(newsockfd, reply_str + l_reply_len - l_reply_rest, l_send_bytes, 0); - if(ret<=0) - break; - l_reply_rest-=l_send_bytes; - }; - - DAP_DELETE(str_reply); - DAP_DELETE(reply_str); - DAP_DELETE(reply_body); + char buf[2]; + if ( 0 > (res = recv(sd, buf, 1, MSG_PEEK)) ) // MSG_PEEK The data is treated as unread and the next recv() function shall still return this data. + return false; - DAP_DELETE(str_cmd); - } - dap_list_free_full(cmd_param_list, NULL); - break; - } + // data in the buffer must be(count_desc>0), but read 0 bytes(res=0) + if(!res && (fds.revents & POLLIN)) + return false; } - // close connection - int cs = closesocket(newsockfd); - if (s_debug_cli) - log_it(L_DEBUG, "close connection=%d sockfd=%"DAP_FORMAT_SOCKET, cs, newsockfd); - return NULL; + return true; } -#ifdef _WIN32 /** - * @brief p_get_next_str + * @brief s_get_next_str + * Reading from the socket till arrival the specified string * - * @param hPipe + * stop_str - string to which reading will continue + * del_stop_str - удалÑть ли Ñтроку Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка в конце + * timeout - in ms + * return: string (if waited for final characters) or NULL, if the string requires deletion + * @param nSocket * @param dwLen * @param stop_str * @param del_stop_str * @param timeout * @return char* */ -char *p_get_next_str( HANDLE hPipe, int *dwLen, const char *stop_str, bool del_stop_str, int timeout ) +char* s_get_next_str( SOCKET nSocket, int *dwLen, const char *stop_str, bool del_stop_str, int timeout ) { - UNUSED(timeout); bool bSuccess = false; long nRecv = 0; // count of bytes received size_t stop_str_len = (stop_str) ? strlen(stop_str) : 0; // if there is nothing to look for - if(!stop_str_len) return NULL; - size_t lpszBuffer_len = 256; char *lpszBuffer = DAP_NEW_Z_SIZE(char, lpszBuffer_len); // received string will not be larger than MAX_REPLY_LEN - while( 1 ) //nRecv < MAX_REPLY_LEN) + while(1) //nRecv < MAX_REPLY_LEN) { - long ret = 0; // read one byte -// long ret = s_recv( nSocket, (unsigned char *) (lpszBuffer + nRecv), 1, timeout); - - bSuccess = ReadFile( hPipe, lpszBuffer + nRecv, - lpszBuffer_len - nRecv, (LPDWORD)&ret, NULL ); - + long ret = dap_net_recv(nSocket, (unsigned char *) (lpszBuffer + nRecv), 1, timeout); //int ret = recv(nSocket,lpszBuffer+nRecv,1, 0); - if ( ret <= 0 || !bSuccess ) + if(ret <= 0) + { break; - + } nRecv += ret; //printf("**debug** socket=%d read %d bytes '%0s'",nSocket, ret, (lpszBuffer + nRecv)); - while((nRecv + 1) >= (long) lpszBuffer_len) { lpszBuffer_len *= 2; lpszBuffer = (char*) realloc(lpszBuffer, lpszBuffer_len); } - // search for the required string if(nRecv >= (long) stop_str_len) { // found the required string @@ -626,7 +703,9 @@ char *p_get_next_str( HANDLE hPipe, int *dwLen, const char *stop_str, bool del_s if(dwLen) *dwLen = (int) nRecv; } - lpszBuffer = DAP_REALLOC(lpszBuffer,(size_t) *dwLen + 1); + char * l_buf_realloc = DAP_REALLOC(lpszBuffer,(size_t) *dwLen + 1); + if( l_buf_realloc) + lpszBuffer = l_buf_realloc; return lpszBuffer; } @@ -641,136 +720,115 @@ char *p_get_next_str( HANDLE hPipe, int *dwLen, const char *stop_str, bool del_s } /** - * @brief thread_pipe_client_func * threading function for processing a request from a client - * @param args - * @return void* */ -static void *thread_pipe_client_func( void *args ) +static void* s_thread_one_client_func(void *args) { - HANDLE hPipe = (HANDLE)args; +SOCKET newsockfd = (SOCKET) (intptr_t) args; +int str_len, marker = 0, timeout = 5000, argc = 0, is_data; +dap_list_t *cmd_param_list = NULL; +char *str_header; -// SOCKET newsockfd = (SOCKET) (intptr_t) args; if(s_debug_cli) - log_it(L_INFO, "new connection pipe = %p", hPipe); - - int str_len, marker = 0; - int timeout = 5000; // 5 sec - int argc = 0; + log_it(L_DEBUG, "new connection sockfd=%"DAP_FORMAT_SOCKET, newsockfd); - dap_list_t *cmd_param_list = NULL; - while( 1 ) + while ( !(0 > (is_data = s_poll(newsockfd, timeout))) ) // wait data from client { - // wait data from client -// int is_data = s_poll( newsockfd, timeout ); - // timeout -// if(!is_data) -// continue; - // error (may be socket closed) -// if(is_data < 0) -// break; + if ( !(is_data) ) // timeout + continue; -// int is_valid = is_valid_socket(newsockfd); -// if(!is_valid) -// { -// break; -// } + if ( !is_valid_socket(newsockfd) ) + break; // receiving http header - char *str_header = p_get_next_str( hPipe, &str_len, "\r\n", true, timeout ); - - // bad format - if(!str_header) - break; + if ( !(str_header = s_get_next_str(newsockfd, &str_len, "\r\n", true, timeout)) ) + break; // bad format - if ( str_header && strlen(str_header) == 0) { + if(str_header && !strlen(str_header) ) { marker++; - if(marker == 1) + if(marker == 1){ + DAP_DELETE(str_header); continue; + } } // filling parameters of command - if ( marker == 1 ) { - cmd_param_list = dap_list_append( cmd_param_list, str_header ); + if(marker == 1) { + cmd_param_list = dap_list_append(cmd_param_list, str_header); //printf("g_list_append argc=%d command=%s ", argc, str_header); - argc ++; + argc++; } else - free( str_header ); - - if ( marker == 2 ) { + DAP_DEL_Z(str_header); + if(marker == 2 && cmd_param_list) { dap_list_t *list = cmd_param_list; // form command - - unsigned int argc = dap_list_length( list ); + argc = dap_list_length(list); // command is found - - if ( argc >= 1) { - - int l_verbose = 0; + if(argc >= 1) { + int l_verbose = 0; char *cmd_name = list->data; - list = dap_list_next( list ); - + list = dap_list_next(list); // execute command - char *str_cmd = dap_strdup_printf( "%s", cmd_name ); - dap_cli_cmd_t *l_cmd = dap_cli_server_cmd_find( cmd_name ); + char *str_cmd = dap_strdup_printf("%s", cmd_name); + dap_cli_cmd_t *l_cmd = dap_cli_server_cmd_find(cmd_name); int res = -1; char *str_reply = NULL; - - if ( l_cmd ) { - - while( list ) { - str_cmd = dap_strdup_printf( "%s;%s", str_cmd, list->data ); + if(l_cmd){ + while(list) { + char *str_cmd_prev = str_cmd; + str_cmd = dap_strdup_printf("%s;%s", str_cmd, list->data); list = dap_list_next(list); + DAP_DELETE(str_cmd_prev); } - - log_it(L_INFO, "execute command = %s", str_cmd ); + if(l_cmd->overrides.log_cmd_call) + l_cmd->overrides.log_cmd_call(str_cmd); + else + log_it(L_DEBUG, "execute command=%s", str_cmd); // exec command - char **l_argv = dap_strsplit( str_cmd, ";", -1 ); + char **l_argv = dap_strsplit(str_cmd, ";", -1); // Call the command function - - if ( l_cmd && l_argv && l_cmd->func ) { + if(l_cmd && l_argv && l_cmd->func) { if (l_cmd->arg_func) { res = l_cmd->func_ex(argc, l_argv, l_cmd->arg_func, &str_reply); } else { res = l_cmd->func(argc, l_argv, &str_reply); } - } - - else if ( l_cmd ) { - log_it(L_WARNING,"NULL arguments for input for command \"%s\"", str_cmd ); + } else if (l_cmd) { + log_it(L_WARNING,"NULL arguments for input for command \"%s\"", str_cmd); }else { - log_it(L_WARNING,"No function for command \"%s\" but it registred?!", str_cmd ); + log_it(L_WARNING,"No function for command \"%s\" but it registred?!", str_cmd); } - // find '-verbose' command - l_verbose = dap_cli_server_cmd_find_option_val( l_argv, 1, argc, "-verbose", NULL ); - dap_strfreev( l_argv ); - + l_verbose = dap_cli_server_cmd_find_option_val(l_argv, 1, argc, "-verbose", NULL); + dap_strfreev(l_argv); } else { - str_reply = dap_strdup_printf("can't recognize command = %s", str_cmd ); - log_it( L_ERROR, str_reply ); + str_reply = dap_strdup_printf("can't recognize command=%s", str_cmd); + log_it(L_ERROR,"Reply string: \"%s\"", str_reply); } - char *reply_body; - if(l_verbose) reply_body = dap_strdup_printf("%d\r\nret_code: %d\r\n%s\r\n", res, res, (str_reply) ? str_reply : ""); else reply_body = dap_strdup_printf("%d\r\n%s\r\n", res, (str_reply) ? str_reply : ""); - // return the result of the command function - char *reply_str = dap_strdup_printf( "HTTP/1.1 200 OK\r\n" + char *reply_str = dap_strdup_printf("HTTP/1.1 200 OK\r\n" "Content-Length: %d\r\n\r\n" - "%s", - strlen(reply_body), reply_body ); - - int ret;// = send( newsockfd, reply_str, strlen(reply_str) ,0 ); + "%s", strlen(reply_body), reply_body); + size_t l_reply_step = 32768; + size_t l_reply_len = strlen(reply_str); + size_t l_reply_rest = l_reply_len; - WriteFile( hPipe, reply_str, strlen(reply_str), (LPDWORD)&ret, NULL ); + while(l_reply_rest) { + size_t l_send_bytes = min(l_reply_step, l_reply_rest); + int ret = send(newsockfd, reply_str + l_reply_len - l_reply_rest, l_send_bytes, 0); + if(ret<=0) + break; + l_reply_rest-=l_send_bytes; + }; DAP_DELETE(str_reply); DAP_DELETE(reply_str); @@ -778,76 +836,17 @@ static void *thread_pipe_client_func( void *args ) DAP_DELETE(str_cmd); } - dap_list_free_full(cmd_param_list, free); + dap_list_free_full(cmd_param_list, NULL); break; } } - // close connection -// int cs = closesocket(newsockfd); - - log_it( L_INFO, "close connection pipe = %p", hPipe ); - - FlushFileBuffers( hPipe ); - DisconnectNamedPipe( hPipe ); - CloseHandle( hPipe ); - - return NULL; -} - - -/** - * @brief thread_pipe_func - * main threading server function pipe win32 - * @param args - * @return void* - */ -static void* thread_pipe_func( void *args ) -{ - UNUSED(args); - BOOL fConnected = FALSE; - pthread_t threadId; - HANDLE hPipe = INVALID_HANDLE_VALUE; - static const char *cPipeName = "\\\\.\\pipe\\node_cli.pipe"; - - for (;;) - { -/// printf( "\nPipe Server: Main thread awaiting client connection on %s\n", lpszPipename ); - - hPipe = CreateNamedPipe( - cPipeName, // pipe name - PIPE_ACCESS_DUPLEX, // read/write access - PIPE_TYPE_MESSAGE | // message type pipe - PIPE_READMODE_MESSAGE | // message-read mode - PIPE_WAIT, // blocking mode - PIPE_UNLIMITED_INSTANCES, // max. instances - 4096, // output buffer size - 4096, // input buffer size - 0, // client time-out - NULL ); // default security attribute - - if ( hPipe == INVALID_HANDLE_VALUE ) { - log_it( L_ERROR, "CreateNamedPipe failed, GLE = %lu.\n", GetLastError() ); - return NULL; - } - - fConnected = ConnectNamedPipe( hPipe, NULL ) ? TRUE : ( GetLastError() == ERROR_PIPE_CONNECTED ); - - if ( fConnected ) - { - log_it( L_INFO, "Client %p connected, creating a processing thread.\n", hPipe ); - - pthread_create( &threadId, NULL, thread_pipe_client_func, hPipe ); - pthread_detach( threadId ); - } - else - CloseHandle( hPipe ); - } + int cs = closesocket(newsockfd); + if (s_debug_cli) + log_it(L_DEBUG, "close connection=%d sockfd=%"DAP_FORMAT_SOCKET, cs, newsockfd); return NULL; } -#endif - /** * @brief thread_main_func diff --git a/dap-sdk/net/server/enc_server/CMakeLists.txt b/dap-sdk/net/server/enc_server/CMakeLists.txt index 8aaba2be3c..e29d8f7368 100644 --- a/dap-sdk/net/server/enc_server/CMakeLists.txt +++ b/dap-sdk/net/server/enc_server/CMakeLists.txt @@ -20,23 +20,23 @@ target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/.. if(WIN32) target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_io dap_http_server json-c - KERNEL32 - USER32 - SHELL32 - WINMM - GDI32 - ADVAPI32 - Ole32 - Version - Imm32 - OleAut32 + kernel32 + user32 + shell32 + winmm + gdi32 + advapi32 + ole32 + version + imm32 + oleaut32 ws2_32 ntdll psapi - Shlwapi - Bcrypt - Crypt32 - Secur32 + shlwapi + bcrypt + crypt32 + secur32 ) endif() diff --git a/dap-sdk/net/server/http_server/CMakeLists.txt b/dap-sdk/net/server/http_server/CMakeLists.txt index 2af0aec59f..b2b3d166ac 100644 --- a/dap-sdk/net/server/http_server/CMakeLists.txt +++ b/dap-sdk/net/server/http_server/CMakeLists.txt @@ -27,23 +27,23 @@ endif() if(WIN32) target_link_libraries(dap_http_server dap_core dap_crypto dap_io magic regex tre intl iconv - KERNEL32 - USER32 - SHELL32 - WINMM - GDI32 - ADVAPI32 - Ole32 - Version - Imm32 - OleAut32 + kernel32 + user32 + shell32 + winmm + gdi32 + advapi32 + ole32 + version + imm32 + oleaut32 ws2_32 ntdll psapi - Shlwapi - Bcrypt - Crypt32 - Secur32 + shlwapi + bcrypt + crypt32 + secur32 ) endif() diff --git a/dap-sdk/plugin/CMakeLists.txt b/dap-sdk/plugin/CMakeLists.txt index 1406a0fc98..b403250922 100644 --- a/dap-sdk/plugin/CMakeLists.txt +++ b/dap-sdk/plugin/CMakeLists.txt @@ -12,7 +12,11 @@ add_library(${PROJECT_NAME} STATIC ${DAP_PLUGIN_SRCS} ${DAP_PLUGIN_HEADERS}) target_link_libraries(${PROJECT_NAME}) -target_link_libraries(${PROJECT_NAME} dap_core dap_cli_server dl) +target_link_libraries(${PROJECT_NAME} dap_core dap_cli_server ) + +if(NOT WIN32) + target_link_libraries(${PROJECT_NAME} dl ) +endif() target_include_directories(${PROJECT_NAME} PUBLIC include/ ) -- GitLab