From c1af786a704eae21a5c71a39c78cf7de07324a30 Mon Sep 17 00:00:00 2001 From: Thomas Kolb Date: Sun, 10 Nov 2024 23:13:31 +0100 Subject: [PATCH] WIP: handle packets from the TUN device in digipeater This is only a backup commit. --- impl/setup_tundev.sh | 2 +- impl/src/layer2/connection_list.c | 21 ++++++++ impl/src/layer2/connection_list.h | 6 +++ impl/src/layer2/digipeater.c | 54 +++++++++++++++++++- impl/test/layer2_over_udp/l2udptest_client.c | 3 ++ 5 files changed, 84 insertions(+), 2 deletions(-) diff --git a/impl/setup_tundev.sh b/impl/setup_tundev.sh index d16ac01..d6f7dd8 100755 --- a/impl/setup_tundev.sh +++ b/impl/setup_tundev.sh @@ -13,7 +13,7 @@ HOSTID="$1" DEV=hamnet70 -sudo ip tuntap add dev $DEV mode tun user $(whoami) +sudo ip tuntap add dev $DEV mode tun pi user $(whoami) sudo ip link set dev $DEV txqueuelen 16 # default is 500 sudo ip link set dev $DEV up sudo ip address add dev $DEV fd73::$HOSTID/64 diff --git a/impl/src/layer2/connection_list.c b/impl/src/layer2/connection_list.c index 5015de2..814a2f1 100644 --- a/impl/src/layer2/connection_list.c +++ b/impl/src/layer2/connection_list.c @@ -3,6 +3,7 @@ #include "connection_list.h" +#include "layer2/connection.h" #include "results.h" #define SEQ_NR_MASK 0xF @@ -177,3 +178,23 @@ result_t connection_list_delete_closed(connection_list_t *list) return OK; } + + +bool connection_list_can_enqueue_packet(connection_list_t *list) +{ + if(!list->head) { + return false; // no entries -> no free space + } + + connection_list_entry_t *entry = list->head; + + while(entry) { + if(!connection_can_enqueue_packet(&entry->connection)) { + return false; + } + + entry = entry->next; + } + + return true; +} diff --git a/impl/src/layer2/connection_list.h b/impl/src/layer2/connection_list.h index b3636c6..5f0154b 100644 --- a/impl/src/layer2/connection_list.h +++ b/impl/src/layer2/connection_list.h @@ -83,4 +83,10 @@ result_t connection_list_delete_head(connection_list_t *list); */ result_t connection_list_delete_closed(connection_list_t *list); +/*!\brief Determine if a packet can be enqueued in all queues. + * + * \returns False if any queue is full, true otherwise. + */ +bool connection_list_can_enqueue_packet(connection_list_t *list); + #endif // CONNECTION_LIST_H diff --git a/impl/src/layer2/digipeater.c b/impl/src/layer2/digipeater.c index 792b7fe..b1c289a 100644 --- a/impl/src/layer2/digipeater.c +++ b/impl/src/layer2/digipeater.c @@ -1,4 +1,7 @@ -#include "layer2/packet_queue.h" +#include +#include +#include +#include #define LOGGER_MODULE_NAME "digi" #include "logger.h" @@ -10,6 +13,7 @@ #include "layer2/connection_list.h" #include "layer2/ham64.h" #include "layer2/packet_structs.h" +#include "layer2/packet_queue.h" #include "results.h" #include "utils.h" @@ -175,6 +179,54 @@ result_t digipeater_handle_packet(digipeater_ctx_t *ctx, const uint8_t *buf, siz } +result_t digipeater_fill_packet_queues_from_tundev(digipeater_ctx_t *ctx, int tun_fd) +{ + // first check if any queue is already full, so we don't have to drop packets + // from the TUN device queue. + if(!connection_list_can_enqueue_packet(&ctx->conn_list)) { + LOG(LVL_DEBUG, "No free space in queues."); + return OK; // do nothing + } + + struct pollfd pfd_tun; + memset(&pfd_tun, 0, sizeof(pfd_tun)); + + pfd_tun.fd = tun_fd; + pfd_tun.events = POLLIN; + + while(true) { + int ret = poll(&pfd_tun, 1, 0 /* timeout */); + if(ret < 0) { + LOG(LVL_ERR, "poll: %s", strerror(errno)); + return ERR_SYSCALL; + } else if(ret == 0) { + // no more packets + break; + } else { + // a packet is available -> read it + static const size_t packetbuf_size = 2048; + uint8_t packetbuf[packetbuf_size]; + ret = read(tun_fd, packetbuf, packetbuf_size); + if(ret < 0) { + LOG(LVL_ERR, "read: %s", strerror(errno)); + return ERR_SYSCALL; + } else if(ret == 0) { + // no more data, should not happen + break; + } + + LOG(LVL_DUMP, "TUN Flags: 0x%04x", *(uint16_t*)packetbuf); + LOG(LVL_DUMP, "TUN Proto: 0x%04x", *((uint16_t*)packetbuf + 1)); + + // FIXME: + //ERR_CHECK(connection_list_enqueue_packet(entry->connection, packetbuf, ret)); + } + } + + return OK; +} + + size_t digipeater_encode_next_packet(digipeater_ctx_t *ctx, uint8_t *buf, size_t buf_len, bool *end_burst) { uint64_t now = get_hires_time(); diff --git a/impl/test/layer2_over_udp/l2udptest_client.c b/impl/test/layer2_over_udp/l2udptest_client.c index ff2be6a..1f40fab 100644 --- a/impl/test/layer2_over_udp/l2udptest_client.c +++ b/impl/test/layer2_over_udp/l2udptest_client.c @@ -260,6 +260,9 @@ int main(int argc, char **argv) break; } + LOG(LVL_DUMP, "TUN Flags: 0x%04x", *(uint16_t*)packetbuf); + LOG(LVL_DUMP, "TUN Proto: 0x%04x", *((uint16_t*)packetbuf + 1)); + RESULT_CHECK(connection_enqueue_packet(&l2conn, packetbuf, ret)); } }