diff --git a/cmake/OS_Detection.cmake b/cmake/OS_Detection.cmake index 32b495aa55798ba1e83d6834086ba6bde3be4e3b..ccd445ba8770d22e775b8205ea7c52f01bc0c83d 100644 --- a/cmake/OS_Detection.cmake +++ b/cmake/OS_Detection.cmake @@ -100,7 +100,7 @@ if(UNIX) set(CCOPT_SYSTEM "") set(LDOPT_SYSTEM "") if(DAP_DEBUG) - set(_CCOPT "-DDAP_DEBUG ${CFLAGS_WARNINGS} -pg -g3 -ggdb -fno-eliminate-unused-debug-symbols -fno-strict-aliasing") + set(_CCOPT "-DDAP_DEBUG ${CFLAGS_WARNINGS} -pg -g3 -ggdb -fno-eliminate-unused-debug-symbols -fno-strict-aliasing -std=gnu1x") set(_LOPT "-pg") if (DEFINED ENV{DAP_ASAN}) message("[!] Address Sanitizer enabled") diff --git a/io/dap_context.c b/io/dap_context.c index 4ab0880efe233563efa124bc47608061f846bfbf..b3b7d94d9772a70952d069462dfeb6b9e228d49c 100644 --- a/io/dap_context.c +++ b/io/dap_context.c @@ -557,11 +557,10 @@ int dap_worker_thread_loop(dap_context_t * a_context) break; } else { if (seconds == 0xFFFFFFFF) { - int l_err = 0; - tmp = 0; + int l_err = 0; tmp = 0; getsockopt(l_cur->socket, SOL_SOCKET, SO_ERROR, (char*)&l_err, (PINT)&tmp); - log_it(L_ERROR, "Connection to %s:%u failed, error %d", - l_cur->remote_addr_str, ntohs(l_cur->remote_addr.sin_port), l_err); + log_it(L_ERROR, "Connection to %s : %u failed, error %d", + l_cur->remote_addr_str, l_cur->remote_port, l_err); if ( l_cur->callbacks.error_callback ) l_cur->callbacks.error_callback(l_cur, l_err); l_cur->flags |= DAP_SOCK_SIGNAL_CLOSE; @@ -569,7 +568,7 @@ int dap_worker_thread_loop(dap_context_t * a_context) break; } else { log_it(L_INFO, "ConnectEx to %s:%u succeeded in %d seconds", - l_cur->remote_addr_str, ntohs(l_cur->remote_addr.sin_port), seconds); + l_cur->remote_addr_str, l_cur->remote_port, seconds); if (setsockopt(l_cur->socket, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0) == SOCKET_ERROR) { @@ -957,10 +956,10 @@ int dap_worker_thread_loop(dap_context_t * a_context) break; case DESCRIPTOR_TYPE_SOCKET_UDP: { l_must_read_smth = true; - socklen_t l_size = sizeof(l_cur->remote_addr); + socklen_t l_size = sizeof(l_cur->addr_storage); l_bytes_read = recvfrom(l_cur->fd, (char *) (l_cur->buf_in + l_cur->buf_in_size), l_cur->buf_in_size_max - l_cur->buf_in_size, 0, - (struct sockaddr *)&l_cur->remote_addr, &l_size); + (struct sockaddr *)&l_cur->addr_storage, &l_size); #ifdef DAP_OS_WINDOWS l_errno = WSAGetLastError(); @@ -1202,7 +1201,7 @@ int dap_worker_thread_loop(dap_context_t * a_context) case DESCRIPTOR_TYPE_SOCKET_UDP: l_bytes_sent = sendto(l_cur->socket, (const char *)l_cur->buf_out, l_cur->buf_out_size, MSG_DONTWAIT | MSG_NOSIGNAL, - (struct sockaddr *)&l_cur->remote_addr, sizeof(l_cur->remote_addr)); + (struct sockaddr *)&l_cur->addr_storage, sizeof(l_cur->addr_storage)); #ifdef DAP_OS_WINDOWS dap_events_socket_set_writable_unsafe(l_cur,false); l_errno = WSAGetLastError(); diff --git a/io/dap_events_socket.c b/io/dap_events_socket.c index 9a4b3f1d0470ec632898f34252e551e5187e5c01..c338c5986ebe1e323f41f757b032ae9c464684f1 100644 --- a/io/dap_events_socket.c +++ b/io/dap_events_socket.c @@ -1304,11 +1304,11 @@ void dap_events_socket_set_readable_unsafe( dap_events_socket_t *a_esocket, bool log_it(L_ERROR, "! Not initialized read event for es %p \"%s\"", a_esocket, dap_events_socket_get_type_str(a_esocket)); a_esocket->op_events[io_op_read] = CreateEvent(0, TRUE, FALSE, NULL); } - INT l_len = sizeof(a_esocket->remote_addr); + INT l_len = sizeof(a_esocket->addr_storage); l_ol = DAP_NEW_Z(dap_overlapped_t); l_ol->ol.hEvent = a_esocket->op_events[io_op_read]; l_res = WSARecvFrom(a_esocket->socket, &wsabuf, 1, &bytes, &flags, - (LPSOCKADDR)&a_esocket->remote_addr, &l_len, (OVERLAPPED*)l_ol, NULL); + (LPSOCKADDR)&a_esocket->addr_storage, &l_len, (OVERLAPPED*)l_ol, NULL); l_func = "WSARecvFrom"; } break; @@ -1443,7 +1443,7 @@ void dap_events_socket_set_writable_unsafe( dap_events_socket_t *a_esocket, bool log_it(L_ERROR, "Failed to create socket for accept()'ing, errno %d", WSAGetLastError()); return; } - l_res = pfn_ConnectEx(a_esocket->socket, (PSOCKADDR)&a_esocket->remote_addr, sizeof(SOCKADDR), + l_res = pfn_ConnectEx(a_esocket->socket, (PSOCKADDR)&a_esocket->addr_storage, sizeof(SOCKADDR), NULL, 0, NULL, (OVERLAPPED*)l_ol) ? 0 : SOCKET_ERROR; l_func = "ConnectEx"; } else { @@ -1464,12 +1464,12 @@ void dap_events_socket_set_writable_unsafe( dap_events_socket_t *a_esocket, bool l_ol = DAP_NEW_Z_SIZE(dap_overlapped_t, sizeof(OVERLAPPED) + a_esocket->buf_out_size); l_ol->ol.hEvent = a_esocket->op_events[io_op_write]; if (a_esocket->buf_out_size) { - INT l_len = sizeof(a_esocket->remote_addr); + INT l_len = sizeof(a_esocket->addr_storage); memcpy(l_ol->buf, a_esocket->buf_out, a_esocket->buf_out_size); l_res = WSASendTo(a_esocket->socket, &(WSABUF) { .len = a_esocket->buf_out_size, .buf = l_ol->buf - }, 1, &bytes, flags, (LPSOCKADDR)&a_esocket->remote_addr, l_len, (OVERLAPPED*)l_ol, NULL); + }, 1, &bytes, flags, (LPSOCKADDR)&a_esocket->addr_storage, l_len, (OVERLAPPED*)l_ol, NULL); a_esocket->buf_out_size = 0; l_func = "WSASendTo"; } else diff --git a/io/dap_server.c b/io/dap_server.c index dfbfedd2416be602e229f3db9b13c2f0d9bb1de1..d2e24dba8839cf2086ef34b1a8afdf9a7c8db783 100644 --- a/io/dap_server.c +++ b/io/dap_server.c @@ -236,29 +236,16 @@ int dap_server_listen_addr_add(dap_server_t *a_server, const char *a_addr, uint1 log_it(L_WARNING, "Can't set up REUSEPORT flag to the socket"); #endif - void *l_addr_ptr = NULL; - const char *l_addr = a_addr; - switch (a_server->type) { - case DAP_SERVER_TCP: - case DAP_SERVER_UDP: - l_es->listener_addr.sin_family = AF_INET; - l_es->listener_addr.sin_port = htons(l_es->listener_port); - l_addr_ptr = &l_es->listener_addr.sin_addr; - break; - case DAP_SERVER_TCP_V6: - l_es->listener_addr_v6.sin6_family = AF_INET6; - l_es->listener_addr_v6.sin6_port = htons(l_es->listener_port); - l_addr_ptr = &l_es->listener_addr_v6.sin6_addr; - default: - break; + struct addrinfo l_hints = { .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM }, *l_addr_res; + if ( getaddrinfo(a_addr, dap_itoa(l_es->listener_port), &l_hints, &l_addr_res) ) { + log_it(L_ERROR, "Wrong listen address '%s : %u'", a_addr, l_es->listener_port); + goto clean_n_quit; } + memcpy(&l_es->addr_storage, l_addr_res->ai_addr, l_addr_res->ai_addrlen); + freeaddrinfo(l_addr_res); if (a_server->type != DAP_SERVER_LOCAL) { - if (inet_pton(AF_INET, l_addr, &l_addr_ptr) <= 0) { - log_it(L_ERROR, "Can't convert address %s to digital form", l_addr); - goto clean_n_quit; - } - strncpy(l_es->listener_addr_str, l_addr, sizeof(l_es->listener_addr_str)); // If NULL we listen everything + strncpy(l_es->listener_addr_str, a_addr, sizeof(l_es->listener_addr_str)); // If NULL we listen everything } #ifdef DAP_OS_UNIX else { @@ -386,28 +373,8 @@ static int s_server_run(dap_server_t *a_server) dap_return_val_if_pass(!a_server || !a_server->es_listeners, -1); // func work dap_events_socket_t *l_es = (dap_events_socket_t *)a_server->es_listeners->data; - void *l_listener_addr = NULL; - socklen_t l_listener_addr_len = 0; - switch (a_server->type) { - case DAP_SERVER_TCP: - case DAP_SERVER_UDP: - l_listener_addr = &l_es->listener_addr; - l_listener_addr_len = sizeof(l_es->listener_addr); - break; - case DAP_SERVER_TCP_V6: - l_listener_addr = &l_es->listener_addr_v6; - l_listener_addr_len = sizeof(l_es->listener_addr_v6); - break; -#ifdef DAP_OS_UNIX - case DAP_SERVER_LOCAL: - l_listener_addr = &l_es->listener_path; - l_listener_addr_len = sizeof(l_es->listener_path); -#endif - default: - log_it(L_ERROR, "Can't run server: unsupported server type %s", dap_server_type_str(a_server->type)); - } - if (bind(l_es->socket, (struct sockaddr *)l_listener_addr, l_listener_addr_len) < 0) { + if (bind(l_es->socket, (struct sockaddr*)&l_es->addr_storage, sizeof(struct sockaddr_storage)) < 0) { #ifdef DAP_OS_WINDOWS log_it(L_ERROR, "Bind error: %d", WSAGetLastError()); closesocket(l_es->socket); @@ -520,30 +487,36 @@ static void s_es_server_accept(dap_events_socket_t *a_es_listener, SOCKET a_remo l_es_new = dap_events_socket_wrap_no_add(a_remote_socket, &l_server->client_callbacks); l_es_new->server = l_server; unsigned short int l_family = a_remote_addr->ss_family; + + l_es_new->type = DESCRIPTOR_TYPE_SOCKET_CLIENT; + l_es_new->addr_storage = *a_remote_addr; + char l_port_str[NI_MAXSERV]; switch (l_family) { #ifdef DAP_OS_UNIX case AF_UNIX: l_es_new->type = DESCRIPTOR_TYPE_SOCKET_LOCAL_CLIENT; - l_es_new->remote_path = *(struct sockaddr_un *)a_remote_addr; - strncpy(l_es_new->remote_addr_str, l_es_new->remote_path.sun_path, sizeof(l_es_new->remote_addr_str) - 1); + strncpy(l_es_new->remote_addr_str, ((struct sockaddr_un*)a_remote_addr)->sun_path, sizeof(l_es_new->remote_addr_str) - 1); break; #endif case AF_INET: - l_es_new->type = DESCRIPTOR_TYPE_SOCKET_CLIENT; - l_es_new->remote_addr = *(struct sockaddr_in *)a_remote_addr; - inet_ntop(AF_INET, &l_es_new->remote_addr.sin_addr, l_es_new->remote_addr_str, sizeof(l_es_new->remote_addr_str)); - l_es_new->remote_port = ntohs(l_es_new->remote_addr.sin_port); - break; case AF_INET6: - l_es_new->type = DESCRIPTOR_TYPE_SOCKET_CLIENT; - l_es_new->remote_addr_v6 = *(struct sockaddr_in6 *)a_remote_addr; - inet_ntop(AF_INET6, &l_es_new->remote_addr_v6.sin6_addr, l_es_new->remote_addr_str, sizeof(l_es_new->remote_addr_str)); - l_es_new->remote_port = ntohs(l_es_new->remote_addr_v6.sin6_port); + if (getnameinfo((struct sockaddr*)a_remote_addr, sizeof(*a_remote_addr), l_es_new->remote_addr_str, + sizeof(l_es_new->remote_addr_str), l_port_str, sizeof(l_port_str), NI_NUMERICHOST | NI_NUMERICSERV)) + { +#ifdef DAP_OS_WINDOWS + log_it(L_ERROR, "getnameinfo error: %d", WSAGetLastError()); +#else + log_it(L_ERROR, "getnameinfo error: %s", strerror(errno)); +#endif + return; + } + l_es_new->remote_port = strtol(l_port_str, NULL, 10); break; default: log_it(L_ERROR, "Unsupported protocol family %hu from accept()", l_family); } + log_it(L_DEBUG, "[es:%p] Accepted new connection (sock %"DAP_FORMAT_SOCKET" from %"DAP_FORMAT_SOCKET")", a_es_listener, a_remote_socket, a_es_listener->socket); log_it(L_INFO, "Connection accepted from %s : %hu", l_es_new->remote_addr_str, l_es_new->remote_port); diff --git a/io/include/dap_events_socket.h b/io/include/dap_events_socket.h index 9ec6b405a6334c03f9d78d426f58934483ba942d..982e0a974c12fca9f3b450086ee773e79038f2e4 100644 --- a/io/include/dap_events_socket.h +++ b/io/include/dap_events_socket.h @@ -265,13 +265,9 @@ typedef struct dap_events_socket { #if defined(DAP_EVENTS_CAPS_QUEUE_PIPE2) pthread_rwlock_t buf_out_lock; #endif - + struct sockaddr_storage addr_storage; // Remote address, port and others union { - struct sockaddr_in remote_addr; - struct sockaddr_in listener_addr; - struct sockaddr_in6 remote_addr_v6; - struct sockaddr_in6 listener_addr_v6; #ifdef DAP_OS_UNIX struct sockaddr_un remote_path; struct sockaddr_un listener_path; // Path to UNIX socket diff --git a/net/client/dap_client_http.c b/net/client/dap_client_http.c index 20f01e42262f7ee52e4df4b1928b2aeee06fa27e..5b7adb4850decd7834b399c0ccc6ceb44d2cbd70 100644 --- a/net/client/dap_client_http.c +++ b/net/client/dap_client_http.c @@ -625,25 +625,22 @@ dap_client_http_t * dap_client_http_request_custom ( l_client_http->worker = a_worker; l_client_http->is_over_ssl = a_over_ssl; - l_ev_socket->remote_addr = (struct sockaddr_in) { - .sin_family = AF_INET, - .sin_port = htons(a_uplink_port) - }; - inet_pton(AF_INET, a_uplink_addr, &l_ev_socket->remote_addr.sin_addr); - //Resolve addr if - if(!l_ev_socket->remote_addr.sin_addr.s_addr) { - if(dap_net_resolve_host(a_uplink_addr, AF_INET, (struct sockaddr*) &l_ev_socket->remote_addr.sin_addr) < 0) { - log_it(L_ERROR, "Wrong remote address '%s:%u'", a_uplink_addr, a_uplink_port); - s_client_http_delete( l_client_http); + struct addrinfo l_hints = { .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM }, *l_addr_res; + if ( getaddrinfo(a_uplink_addr, dap_itoa(a_uplink_port), &l_hints, &l_addr_res) ) { + log_it(L_ERROR, "Wrong remote address '%s : %u'", a_uplink_addr, a_uplink_port); + s_client_http_delete(l_client_http); l_ev_socket->_inheritor = NULL; dap_events_socket_delete_unsafe( l_ev_socket, true); if(a_error_callback) a_error_callback(errno, a_callbacks_arg); - return NULL; - } } - strncpy(l_ev_socket->remote_addr_str, a_uplink_addr, INET_ADDRSTRLEN); + memcpy(&l_ev_socket->addr_storage, l_addr_res->ai_addr, l_addr_res->ai_addrlen); + freeaddrinfo(l_addr_res); + + strncpy(l_ev_socket->remote_addr_str, a_uplink_addr, INET6_ADDRSTRLEN); + l_ev_socket->remote_port = a_uplink_port; + // connect l_ev_socket->flags |= DAP_SOCK_CONNECTING; l_ev_socket->type = DESCRIPTOR_TYPE_SOCKET_CLIENT; @@ -672,7 +669,7 @@ dap_client_http_t * dap_client_http_request_custom ( return l_client_http; #else l_ev_socket->flags |= DAP_SOCK_READY_TO_WRITE; - int l_err = connect(l_socket, (struct sockaddr *) &l_ev_socket->remote_addr, sizeof(struct sockaddr_in)); + int l_err = connect(l_socket, (struct sockaddr *) &l_ev_socket->addr_storage, sizeof(struct sockaddr_in)); if (l_err == 0){ log_it(L_DEBUG, "Connected momentaly with %s:%u!", a_uplink_addr, a_uplink_port); l_client_http->worker = a_worker ? a_worker : dap_events_worker_get_auto(); diff --git a/net/client/dap_client_pvt.c b/net/client/dap_client_pvt.c index 7dd5f85792b9d973a49f222201fed3017fe12e09..b102af2e98f7c6648d100e6348696a3d2a5075a6 100644 --- a/net/client/dap_client_pvt.c +++ b/net/client/dap_client_pvt.c @@ -33,6 +33,7 @@ #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <arpa/inet.h> +#include <netdb.h> #endif #include "json.h" @@ -357,6 +358,7 @@ int s_add_cert_sign_to_data(const dap_cert_t *a_cert, uint8_t **a_data, size_t * * @brief s_client_internal_stage_status_proc * @param a_client */ + static void s_stage_status_after(dap_client_pvt_t *a_client_pvt) { if (!a_client_pvt) @@ -513,19 +515,19 @@ static void s_stage_status_after(dap_client_pvt_t *a_client_pvt) l_es->flags |= DAP_SOCK_READY_TO_WRITE; #endif l_es->_inheritor = a_client_pvt->client; - a_client_pvt->stream_es->remote_addr = (struct sockaddr_in) { - .sin_family = AF_INET, - .sin_port = htons(a_client_pvt->client->uplink_port) - }; - l_es->remote_port = a_client_pvt->client->uplink_port; - strncpy(l_es->remote_addr_str, a_client_pvt->client->uplink_addr, INET_ADDRSTRLEN); - if(inet_pton(AF_INET, a_client_pvt->client->uplink_addr, &(l_es->remote_addr.sin_addr)) < 0) { - log_it(L_ERROR, "Wrong remote address '%s:%u'", a_client_pvt->client->uplink_addr, a_client_pvt->client->uplink_port); + struct addrinfo l_hints = (struct addrinfo){ .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM }, *l_addr_res; + if ( getaddrinfo(a_client_pvt->client->uplink_addr, dap_itoa(a_client_pvt->client->uplink_port), &l_hints, &l_addr_res) ) { + log_it(L_ERROR, "Wrong remote address '%s : %u'", a_client_pvt->client->uplink_addr, a_client_pvt->client->uplink_port); a_client_pvt->stage_status = STAGE_STATUS_ERROR; a_client_pvt->last_error = ERROR_WRONG_ADDRESS; s_stage_status_after(a_client_pvt); break; } + memcpy(&l_es->addr_storage, l_addr_res->ai_addr, l_addr_res->ai_addrlen); + freeaddrinfo(l_addr_res); + + l_es->remote_port = a_client_pvt->client->uplink_port; + strncpy(l_es->remote_addr_str, a_client_pvt->client->uplink_addr, INET_ADDRSTRLEN); a_client_pvt->stream = dap_stream_new_es_client(l_es, &a_client_pvt->stream_addr); assert(a_client_pvt->stream); @@ -558,7 +560,7 @@ static void s_stage_status_after(dap_client_pvt_t *a_client_pvt) #else int l_err = 0; - if((l_err = connect(l_es->socket, (struct sockaddr *) &l_es->remote_addr, + if((l_err = connect(l_es->socket, (struct sockaddr *) &l_es->addr_storage, sizeof(struct sockaddr_in))) ==0) { log_it(L_INFO, "Connected momentaly with %s:%u", a_client_pvt->client->uplink_addr, a_client_pvt->client->uplink_port); // add to dap_worker diff --git a/net/server/http_server/dap_http_simple.c b/net/server/http_server/dap_http_simple.c index 53395ca284ec77458f5e7b31ff0b3faf4589b306..b136033f986dcd069d3b5176695c8eeaf6922b6e 100644 --- a/net/server/http_server/dap_http_simple.c +++ b/net/server/http_server/dap_http_simple.c @@ -391,7 +391,8 @@ static void s_http_client_headers_read( dap_http_client_t *a_http_client, void U { assert(a_http_client->esocket->server); if (a_http_client->esocket->server->type == DAP_SERVER_TCP || a_http_client->esocket->server->type == DAP_SERVER_UDP) { - if (dap_http_ban_list_client_check_ipv4(a_http_client->esocket->remote_addr.sin_addr)) { + if ( dap_http_ban_list_client_check_ipv4( ((struct sockaddr_in*)&a_http_client->esocket->addr_storage)->sin_addr ) ) { + // TODO make it universal for IPv6 a_http_client->reply_status_code = Http_Status_Forbidden; return; }