From dbd726316c67c6709bafd048d38a852873f5a7e3 Mon Sep 17 00:00:00 2001 From: Fabio Buracchi <45599613+buracchi@users.noreply.github.com> Date: Wed, 3 Apr 2024 22:55:01 +0200 Subject: [PATCH] Update --- network_utils/src/inet_utils.c | 10 ++-- server/src/acceptor.c | 88 +++++++++++++++++----------------- server/src/acceptor.h | 8 ++-- server/src/main.c | 2 +- server/test/test_acceptor.c | 37 +++++++++++--- vcpkg | 2 +- 6 files changed, 86 insertions(+), 61 deletions(-) diff --git a/network_utils/src/inet_utils.c b/network_utils/src/inet_utils.c index 8bcc28e..8b95676 100644 --- a/network_utils/src/inet_utils.c +++ b/network_utils/src/inet_utils.c @@ -22,7 +22,7 @@ const char *inet_ntop_address(const struct sockaddr address[static 1], char addr break; default: // SET ERRNO - return NULL; + return nullptr; } return evutil_inet_ntop(address->sa_family, client_addr, address_str, INET6_ADDRSTRLEN); } @@ -37,9 +37,9 @@ int inet_addr_in_to_in6(struct sockaddr_in const src[restrict static 1], struct .ai_socktype = SOCK_DGRAM, .ai_protocol = 0, .ai_addrlen = 0, - .ai_addr = NULL, - .ai_canonname = NULL, - .ai_next = NULL + .ai_addr = nullptr, + .ai_canonname = nullptr, + .ai_next = nullptr }; int gai_ret; gai_ret = getnameinfo((const struct sockaddr *)src, sizeof *src, host, sizeof host, serv, sizeof serv, NI_DGRAM | NI_NUMERICSERV | NI_NUMERICHOST); @@ -70,5 +70,5 @@ void print_inet_address_detail(int fd) { getpeername(fd, (struct sockaddr *)&peeraddr, &sockpeer_len); inet_ntop_address((struct sockaddr *)&sockaddr, sockaddr_str, &sockaddr_port); inet_ntop_address((struct sockaddr *)&peeraddr, peeraddr_str, &peeraddr_port); - cmn_logger_log_trace("IP Header contains\t = %s\t = %s\t = %hu\t = %hu", sockaddr_str, peeraddr_str, sockaddr_port, peeraddr_port); + cmn_logger_log_trace("IP Header contains: = %s = %s = %hu = %hu", sockaddr_str, peeraddr_str, sockaddr_port, peeraddr_port); } diff --git a/server/src/acceptor.c b/server/src/acceptor.c index f4cd8eb..e86a6dd 100644 --- a/server/src/acceptor.c +++ b/server/src/acceptor.c @@ -5,7 +5,7 @@ #include "inet_utils.h" -static ssize_t recv_packet(evutil_socket_t sockfd, struct addrinfo *receiver_addrinfo, struct acceptor_packet *packet); +static ssize_t recv_packet(evutil_socket_t sockfd, struct addrinfo receiver_addrinfo[static 1], struct acceptor_packet packet[static 1]); static struct evutil_addrinfo *get_accepting_addrinfo_list(char const *service); @@ -52,33 +52,36 @@ int acceptor_init(struct acceptor acceptor[static 1], char const *port) { } int acceptor_destroy(struct acceptor acceptor[static 1]) { - try(evutil_closesocket(acceptor->peer_acceptor), -1, fail); + if (evutil_closesocket(acceptor->peer_acceptor) == -1) { + cmn_logger_log_error("close: %s", evutil_socket_error_to_string(evutil_socket_geterror(acceptor->peer_acceptor))); + return 1; + } return 0; -fail: - return 1; } -void acceptor_accept(struct acceptor acceptor[static 1], evutil_socket_t socket[static 1], struct acceptor_packet packet[static 1]) { - try(recv_packet(acceptor->peer_acceptor, &acceptor->addrinfo, packet), -1, recv_packet_fail); - char client_address_str[INET6_ADDRSTRLEN] = { 0 }; +bool acceptor_accept(struct acceptor acceptor[static 1], evutil_socket_t socket[static 1], struct acceptor_packet packet[static 1]) { + char client_address_str[INET6_ADDRSTRLEN] = {}; uint16_t client_address_port; - char rbuff_hex[sizeof packet->payload] = { 0 }; - packet->payload[packet->payload_size] = '\0'; - try(inet_ntop_address(packet->src_addrinfo.ai_addr, client_address_str, &client_address_port), nullptr, inet_ntop_address_fail); + char rbuff_hex[sizeof packet->data] = {}; + if (recv_packet(acceptor->peer_acceptor, &acceptor->addrinfo, packet) == -1) { + cmn_logger_log_debug("Acceptor: Unable to receive the request packet correctly, denying connection."); + return false; + } + if (inet_ntop_address(packet->src_addrinfo.ai_addr, client_address_str, &client_address_port) == nullptr) { + cmn_logger_log_error("inet_ntop_address failed"); + return false; + } for (ssize_t i = 0; i < packet->payload_size; i++) { - sprintf(rbuff_hex + 2 * i, "%02x", packet->payload[i]); + sprintf(rbuff_hex + 2 * i, "%02x", packet->data[i]); } - cmn_logger_log_debug("Acceptor: Got packet from host %s on port %hu of %zu bytes, packet content is \"%s\"", client_address_str, client_address_port, packet->payload_size, rbuff_hex); - try(*socket = create_client_transport_endpoint(packet), EVUTIL_INVALID_SOCKET, create_client_transport_endpoint_fail); - return; -recv_packet_fail: - cmn_logger_log_debug("Acceptor: Unable to receive the request packet correctly, denying connection."); - return; -inet_ntop_address_fail: - cmn_logger_log_error("inet_ntop_address failed"); - return; -create_client_transport_endpoint_fail: - cmn_logger_log_error("Acceptor: Unable to create an endpoint to the client, denying connection."); + cmn_logger_log_debug("Acceptor: Got packet from host %s on port %hu of %zu bytes, packet content is \"%s\"", + client_address_str, client_address_port, packet->payload_size, rbuff_hex); + *socket = create_client_transport_endpoint(packet); + if (*socket == EVUTIL_INVALID_SOCKET) { + cmn_logger_log_error("Acceptor: Unable to create an endpoint to the client, denying connection."); + return false; + } + return true; } // Resolves the specified service and returns a list of addrinfo @@ -196,21 +199,21 @@ static evutil_socket_t create_client_transport_endpoint(struct acceptor_packet * return EVUTIL_INVALID_SOCKET; } -static ssize_t recv_packet(evutil_socket_t sockfd, struct addrinfo *receiver_addrinfo, struct acceptor_packet *packet) { - struct acceptor_packet result = { - .src_addrinfo = { .ai_addr = (struct sockaddr *)&result.src_addr_storage, .ai_addrlen = sizeof result.src_addr_storage}, - .dest_addrinfo = {.ai_addr = (struct sockaddr *)&result.dest_addr_storage, .ai_addrlen = sizeof result.dest_addr_storage} - }; +static ssize_t recv_packet(evutil_socket_t sockfd, struct addrinfo receiver_addrinfo[static 1], struct acceptor_packet packet[static 1]) { ssize_t bytes_recv; char *msg_control = nullptr; size_t msg_control_size = 128; try(msg_control = calloc(1, msg_control_size), nullptr, msg_control_calloc_fail); struct iovec iovec[1] = { - {.iov_base = result.payload, .iov_len = sizeof result.payload} + {.iov_base = packet->data, .iov_len = sizeof packet->data} }; + *packet = (struct acceptor_packet) { + .src_addrinfo = { .ai_addr = (struct sockaddr *)&packet->src_addr_storage, .ai_addrlen = sizeof packet->src_addr_storage}, + .dest_addrinfo = {.ai_addr = (struct sockaddr *)&packet->dest_addr_storage, .ai_addrlen = sizeof packet->dest_addr_storage} + }; struct msghdr msghdr = { - .msg_name = result.src_addrinfo.ai_addr, - .msg_namelen = result.src_addrinfo.ai_addrlen, + .msg_name = packet->src_addrinfo.ai_addr, + .msg_namelen = packet->src_addrinfo.ai_addrlen, .msg_iov = iovec, .msg_iovlen = (sizeof iovec) / (sizeof *iovec), .msg_control = msg_control, @@ -241,34 +244,33 @@ static ssize_t recv_packet(evutil_socket_t sockfd, struct addrinfo *receiver_add cmn_logger_log_debug("Acceptor: request packet read was truncated, denying connection."); return -1; } - result.src_addrinfo.ai_family = result.src_addrinfo.ai_addr->sa_family; + packet->src_addrinfo.ai_family = packet->src_addrinfo.ai_addr->sa_family; for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msghdr); cmsg != nullptr; cmsg = CMSG_NXTHDR(&msghdr, cmsg)) { if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_ORIGDSTADDR) { struct sockaddr_in6 addr; try(inet_addr_in_to_in6((struct sockaddr_in *)CMSG_DATA(cmsg), &addr), -1, inet_addr_in_to_in6_fail); - memcpy(result.dest_addrinfo.ai_addr, &addr, sizeof addr); - result.dest_addrinfo.ai_addrlen = sizeof addr; - result.dest_addrinfo.ai_family = addr.sin6_family; - result.dest_addrinfo.ai_protocol = IPPROTO_IP; + memcpy(packet->dest_addrinfo.ai_addr, &addr, sizeof addr); + packet->dest_addrinfo.ai_addrlen = sizeof addr; + packet->dest_addrinfo.ai_family = addr.sin6_family; + packet->dest_addrinfo.ai_protocol = IPPROTO_IP; break; } if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_ORIGDSTADDR) { struct sockaddr_in6 *addr = (struct sockaddr_in6 *)CMSG_DATA(cmsg); - memcpy(result.dest_addrinfo.ai_addr, addr, sizeof *addr); - result.dest_addrinfo.ai_addrlen = sizeof *addr; - result.dest_addrinfo.ai_family = addr->sin6_family; - result.dest_addrinfo.ai_protocol = IPPROTO_IPV6; + memcpy(packet->dest_addrinfo.ai_addr, addr, sizeof *addr); + packet->dest_addrinfo.ai_addrlen = sizeof *addr; + packet->dest_addrinfo.ai_family = addr->sin6_family; + packet->dest_addrinfo.ai_protocol = IPPROTO_IPV6; break; } } free(msg_control); - if (!memcmp(&result.dest_addr_storage, &(struct sockaddr_storage){ 0 }, sizeof result.dest_addr_storage)) { + if (!memcmp(&packet->dest_addr_storage, &(struct sockaddr_storage){ 0 }, sizeof packet->dest_addr_storage)) { cmn_logger_log_debug("Acceptor: no IP control messages were included in the packet header. " "Using the acceptor address as the packet destination address."); - memcpy(&result.dest_addrinfo, receiver_addrinfo, sizeof result.dest_addrinfo); + memcpy(&packet->dest_addrinfo, receiver_addrinfo, sizeof packet->dest_addrinfo); } - result.payload_size = bytes_recv; - memcpy(packet, &result, sizeof *packet); + packet->payload_size = bytes_recv; return bytes_recv; inet_addr_in_to_in6_fail: cmn_logger_log_error("inet_addr_in_to_in6 failed"); diff --git a/server/src/acceptor.h b/server/src/acceptor.h index dc338cc..34ffe4a 100644 --- a/server/src/acceptor.h +++ b/server/src/acceptor.h @@ -12,9 +12,9 @@ struct acceptor_packet { struct sockaddr_storage src_addr_storage; // should not be directly accessed struct sockaddr_storage dest_addr_storage; // should not be directly accessed - struct addrinfo src_addrinfo; - struct addrinfo dest_addrinfo; - char payload[512]; + struct evutil_addrinfo src_addrinfo; + struct evutil_addrinfo dest_addrinfo; + char data[512]; ssize_t payload_size; }; @@ -42,4 +42,4 @@ int acceptor_destroy(struct acceptor acceptor[static 1]); * @param socket * @param packet */ -void acceptor_accept(struct acceptor acceptor[static 1], evutil_socket_t socket[static 1], struct acceptor_packet packet[static 1]); +bool acceptor_accept(struct acceptor acceptor[static 1], evutil_socket_t socket[static 1], struct acceptor_packet packet[static 1]); diff --git a/server/src/main.c b/server/src/main.c index 6cfe446..06f4034 100644 --- a/server/src/main.c +++ b/server/src/main.c @@ -72,7 +72,7 @@ static void event_accept(evutil_socket_t peer_acceptor, short event, void *arg) acceptor_accept(acceptor, &socket, &packet); struct connection_details connection_details = { .peer_stream = socket, - .request = (uint8_t *)packet.payload, + .request = (uint8_t *)packet.data, .request_size = packet.payload_size }; //service_handler_factory_create(factory, dispatcher, connection_details); diff --git a/server/test/test_acceptor.c b/server/test/test_acceptor.c index 7a96fcb..b9d57f4 100644 --- a/server/test/test_acceptor.c +++ b/server/test/test_acceptor.c @@ -1,36 +1,59 @@ #include +#include #include "acceptor.h" +#define STR_(s) #s +#define STR(s) STR_(s) +#define DEFAULT_PORT 1234 +#define DATA_PKT_SIZE 512 + TEST(acceptor, bound_to_host) { + cmn_logger_set_default_level(CMN_LOGGER_LOG_LEVEL_OFF); int result = 0; struct acceptor acceptor = {}; - result |= acceptor_init(&acceptor, "1234"); + result |= acceptor_init(&acceptor, STR(DEFAULT_PORT)); result |= acceptor_destroy(&acceptor); ASSERT_EQ(result, 0); } TEST(acceptor, receive_packet) { + cmn_logger_set_default_level(CMN_LOGGER_LOG_LEVEL_OFF); struct acceptor acceptor = {}; - acceptor_init(&acceptor, "1234"); + if (acceptor_init(&acceptor, STR(DEFAULT_PORT))) { + cutest_test_fail_(__func__, __FILE__, __LINE__, "Acceptor initialization failed."); + return; + } // Send a message to the acceptor + const char* message_sent = "Hello, acceptor!"; evutil_socket_t s = socket(AF_INET, SOCK_DGRAM, 0); + if (s == EVUTIL_INVALID_SOCKET) { + cutest_test_fail_(__func__, __FILE__, __LINE__, "Socket initialization failed.."); + return; + } struct sockaddr_in server_addr = { .sin_family = AF_INET, .sin_addr = { .s_addr = htonl(INADDR_LOOPBACK), }, - .sin_port = htons((1234)), + .sin_port = htons((DEFAULT_PORT)), }; - const char* message = "Hello, acceptor!"; - sendto(s, message, strlen(message), 0, (struct sockaddr*)&server_addr, sizeof(server_addr)); + if (sendto(s, message_sent, strlen(message_sent), 0, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) { + cutest_test_fail_(__func__, __FILE__, __LINE__, "Failed to send message."); + return; + } // receive message + char message_recv[DATA_PKT_SIZE + 1] = {0}; evutil_socket_t client_socket = EVUTIL_INVALID_SOCKET; struct acceptor_packet packet = {}; - acceptor_accept(&acceptor, &client_socket, &packet); + if (!acceptor_accept(&acceptor, &client_socket, &packet)) { + cutest_test_fail_(__func__, __FILE__, __LINE__, "Failed to accept message."); + return; + } acceptor_destroy(&acceptor); - ASSERT_EQ(1, 1); + memcpy(message_recv, packet.data, packet.payload_size); + ASSERT_STREQ(message_sent, message_recv); } diff --git a/vcpkg b/vcpkg index 8b14e7e..a34c873 160000 --- a/vcpkg +++ b/vcpkg @@ -1 +1 @@ -Subproject commit 8b14e7e8729c532b7c2be9e603b7ee886b62db6b +Subproject commit a34c873a9717a888f58dc05268dea15592c2f0ff