From 5a78cdf7f6aaba9db93c103fd292a048d37ba5e5 Mon Sep 17 00:00:00 2001 From: icex2 Date: Sat, 23 Jan 2021 22:53:41 +0100 Subject: [PATCH] prinet-proxy: Add keepalive module Starts a separate thread that sends the keepalive packet to the client in defined intervals --- .../main/pumpnet/prinet-proxy/CMakeLists.txt | 3 +- src/main/pumpnet/prinet-proxy/keepalive.c | 84 +++++++++++++++++++ src/main/pumpnet/prinet-proxy/keepalive.h | 9 ++ 3 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 src/main/pumpnet/prinet-proxy/keepalive.c create mode 100644 src/main/pumpnet/prinet-proxy/keepalive.h diff --git a/cmake/src/main/pumpnet/prinet-proxy/CMakeLists.txt b/cmake/src/main/pumpnet/prinet-proxy/CMakeLists.txt index 9283a6c..c072ff3 100644 --- a/cmake/src/main/pumpnet/prinet-proxy/CMakeLists.txt +++ b/cmake/src/main/pumpnet/prinet-proxy/CMakeLists.txt @@ -8,10 +8,11 @@ add_resources(PRI_PUBLIC_KEY ${SRC} prime.public.key) set(SOURCE_FILES ${SRC}/client.c + ${SRC}/keepalive.c ${SRC}/main.c ${SRC}/options.c ${SRC}/packet.c) add_executable(${PROJECT_NAME} ${SOURCE_FILES} ${PRI_PRIVATE_KEY} ${PRI_PUBLIC_KEY}) -target_link_libraries(${PROJECT_NAME} pumpnet-lib sec-prinet util) \ No newline at end of file +target_link_libraries(${PROJECT_NAME} pumpnet-lib sec-prinet util pthread) \ No newline at end of file diff --git a/src/main/pumpnet/prinet-proxy/keepalive.c b/src/main/pumpnet/prinet-proxy/keepalive.c new file mode 100644 index 0000000..ef401ea --- /dev/null +++ b/src/main/pumpnet/prinet-proxy/keepalive.c @@ -0,0 +1,84 @@ +#include +#include + +#include "pumpnet/prinet-proxy/client.h" +#include "pumpnet/prinet-proxy/keepalive.h" +#include "pumpnet/prinet-proxy/packet.h" + +#include "util/log.h" +#include "util/mem.h" +#include "util/time.h" + +static struct pumpnet_prinet_proxy_client_connection* _pumpnet_prinet_proxy_client_connection; +static uint32_t _pumpnet_prinet_proxy_keepalive_poll_ms; +static pthread_t _pumpnet_prinet_proxy_keepalive_thread; +static atomic_bool _pumpnet_prinet_proxy_keepalive_thread_run; + +static void* _pumpnet_prinet_proxy_keepalive_proc(void* ctx) +{ + struct pumpnet_prinet_proxy_packet* keepalive_packet; + + log_debug("Keepalive thread started"); + + while (_pumpnet_prinet_proxy_keepalive_thread_run) { + // TODO we need to get the current CPU time and check if we have to do the below again + // reduce the sleep at the end of the loop to ensure this loop can exit easily + + if (pumpnet_prinet_proxy_client_connection_is_active(_pumpnet_prinet_proxy_client_connection)) { + log_debug("Sending keepalive"); + + keepalive_packet = pumpnet_prinet_proxy_packet_create_keepalive(); + + size_t enc_data_len = sec_prinet_encrypt( + keepalive_packet->nounce, + sizeof(keepalive_packet->nounce), + keepalive_packet->data, + pumpnet_prinet_proxy_packet_get_data_len(keepalive_packet), + keepalive_packet->data); + + keepalive_packet->length = pumpnet_prinet_proxy_packet_get_header_len() + enc_data_len; + + if (!pumpnet_prinet_proxy_client_send_response(_pumpnet_prinet_proxy_client_connection, keepalive_packet)) { + log_error("Sending keepalive packet failed"); + } + + util_xfree((void**) &keepalive_packet); + } else { + log_debug("Skipped keepalive, no connection active"); + } + + //util_time_sleep_ms(500); + util_time_sleep_ms(_pumpnet_prinet_proxy_keepalive_poll_ms); + } + + log_debug("Keep alive thread finished"); + + return NULL; +} + +void pumpnet_prinet_proxy_keepalive_init(struct pumpnet_prinet_proxy_client_connection* connection, uint32_t poll_ms) +{ + _pumpnet_prinet_proxy_client_connection = connection; + _pumpnet_prinet_proxy_keepalive_poll_ms = poll_ms; + + _pumpnet_prinet_proxy_keepalive_thread_run = true; + + int result = pthread_create( + &_pumpnet_prinet_proxy_keepalive_thread, + NULL, + _pumpnet_prinet_proxy_keepalive_proc, + NULL); + + if (result != 0) { + log_error("Creating keepalive thread failed: %s", strerror(result)); + } + + log_info("Started keepalive thread with polling every %d ms", poll_ms); +} + +void pumpnet_prinet_proxy_keepalive_shutdown() +{ + _pumpnet_prinet_proxy_keepalive_thread_run = false; + + pthread_join(_pumpnet_prinet_proxy_keepalive_thread, NULL); +} \ No newline at end of file diff --git a/src/main/pumpnet/prinet-proxy/keepalive.h b/src/main/pumpnet/prinet-proxy/keepalive.h new file mode 100644 index 0000000..69804b5 --- /dev/null +++ b/src/main/pumpnet/prinet-proxy/keepalive.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +#include "pumpnet/prinet-proxy/client.h" + +void pumpnet_prinet_proxy_keepalive_init(struct pumpnet_prinet_proxy_client_connection* connection, uint32_t poll_ms); + +void pumpnet_prinet_proxy_keepalive_shutdown(); \ No newline at end of file