Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
buracchi committed Apr 3, 2024
1 parent cd8cd3e commit dbd7263
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 61 deletions.
10 changes: 5 additions & 5 deletions network_utils/src/inet_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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);
Expand Down Expand Up @@ -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<src-addr> = %s\t<dest-addr> = %s\t<src-port> = %hu\t<dest-port> = %hu", sockaddr_str, peeraddr_str, sockaddr_port, peeraddr_port);
cmn_logger_log_trace("IP Header contains: <src-addr> = %s <dest-addr> = %s <src-port> = %hu <dest-port> = %hu", sockaddr_str, peeraddr_str, sockaddr_port, peeraddr_port);
}
88 changes: 45 additions & 43 deletions server/src/acceptor.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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");
Expand Down
8 changes: 4 additions & 4 deletions server/src/acceptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

Expand Down Expand Up @@ -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]);
2 changes: 1 addition & 1 deletion server/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
37 changes: 30 additions & 7 deletions server/test/test_acceptor.c
Original file line number Diff line number Diff line change
@@ -1,36 +1,59 @@
#include <buracchi/cutest/cutest.h>
#include <buracchi/common/logger/logger.h>

#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);
}
2 changes: 1 addition & 1 deletion vcpkg
Submodule vcpkg updated 9631 files

0 comments on commit dbd7263

Please sign in to comment.