From 52a821f2070d0bcc44c58560216edf797138a76f Mon Sep 17 00:00:00 2001 From: icex2 Date: Sat, 23 Jan 2021 21:35:37 +0100 Subject: [PATCH] prinet-proxy: Separate module for client communication/packet handling Move stuff from main. Will be re-used for keepalive packet sending --- .../main/pumpnet/prinet-proxy/CMakeLists.txt | 1 + src/main/pumpnet/prinet-proxy/client.c | 129 +++++++++++++++++ src/main/pumpnet/prinet-proxy/client.h | 16 +++ src/main/pumpnet/prinet-proxy/main.c | 136 +----------------- 4 files changed, 153 insertions(+), 129 deletions(-) create mode 100644 src/main/pumpnet/prinet-proxy/client.c create mode 100644 src/main/pumpnet/prinet-proxy/client.h diff --git a/cmake/src/main/pumpnet/prinet-proxy/CMakeLists.txt b/cmake/src/main/pumpnet/prinet-proxy/CMakeLists.txt index e48fd2b..9283a6c 100644 --- a/cmake/src/main/pumpnet/prinet-proxy/CMakeLists.txt +++ b/cmake/src/main/pumpnet/prinet-proxy/CMakeLists.txt @@ -7,6 +7,7 @@ add_resources(PRI_PRIVATE_KEY ${SRC} prime.private.key) add_resources(PRI_PUBLIC_KEY ${SRC} prime.public.key) set(SOURCE_FILES + ${SRC}/client.c ${SRC}/main.c ${SRC}/options.c ${SRC}/packet.c) diff --git a/src/main/pumpnet/prinet-proxy/client.c b/src/main/pumpnet/prinet-proxy/client.c new file mode 100644 index 0000000..b7e32ae --- /dev/null +++ b/src/main/pumpnet/prinet-proxy/client.c @@ -0,0 +1,129 @@ +#include "pumpnet/prinet-proxy/client.h" + +#include "util/log.h" +#include "util/mem.h" +#include "util/sock-tcp.h" + +static bool _pumpnet_prinet_proxy_client_recv_packet_length(int handle, uint32_t* length) +{ + uint32_t packet_length; + + while (true) { + ssize_t read = util_sock_tcp_recv_block(handle, &packet_length, sizeof(uint32_t)); + + if (read == 0) { + log_error("Unexpected remote close and no data"); + return NULL; + } + + if (read != sizeof(uint32_t)) { + return false; + } + + break; + } + + *length = packet_length; + + return true; +} + +struct pumpnet_prinet_proxy_packet* pumpnet_prinet_proxy_client_recv_request(int handle) +{ + uint32_t packet_length; + + if (!_pumpnet_prinet_proxy_client_recv_packet_length(handle, &packet_length)) { + log_error("Receiving length field for request from source failed"); + return NULL; + } + + log_debug("Received length source request (%X): %d", handle, packet_length); + + struct pumpnet_prinet_proxy_packet* packet = util_xmalloc(packet_length); + packet->length = packet_length; + + size_t data_len = pumpnet_prinet_proxy_packet_get_data_len(packet); + + size_t read_pos = 0; + + while (true) { + size_t remaining_size = packet->length - sizeof(uint32_t) - read_pos; + + ssize_t read = util_sock_tcp_recv_block( + handle, + ((uint8_t*) packet) + sizeof(uint32_t) + read_pos, + remaining_size); + + if (read == 0) { + log_error("Unexpected remote close and no data"); + return NULL; + } + + if (read == -1) { + log_error("Receiving length field for request from source failed: %d", read); + return NULL; + } + + read_pos += read; + + if (read_pos >= data_len) { + break; + } + } + + return packet; +} + +bool pumpnet_prinet_proxy_client_send_response(int handle, const struct pumpnet_prinet_proxy_packet* packet) +{ + log_debug("Sending source response (%X): %d", handle, packet->length); + + if (util_sock_tcp_send_block(handle, packet, packet->length) != packet->length) { + log_error("Sending response, len %d, to source failed", packet->length); + return false; + } else { + return true; + } +} + +bool pumpnet_prinet_proxy_client_unpack_data_request(const struct pumpnet_prinet_proxy_packet* packet, struct util_iobuf* dec_data) +{ + size_t enc_data_len = pumpnet_prinet_proxy_packet_get_data_len(packet); + + size_t dec_data_len = sec_prinet_decrypt( + packet->nounce, + sizeof(packet->nounce), + packet->data, + enc_data_len, + dec_data->bytes); + + if (dec_data_len < 0) { + log_error("Decrypting data failed"); + return false; + } + + dec_data->pos = dec_data_len; + + return true; +} + +bool pumpnet_prinet_proxy_client_pack_data_response(const struct pumpnet_prinet_proxy_packet* req_packet, const struct util_iobuf* dec_data, struct pumpnet_prinet_proxy_packet* resp_packet) +{ + size_t enc_data_len = sec_prinet_encrypt( + req_packet->nounce, + sizeof(req_packet->nounce), + dec_data->bytes, + dec_data->pos, + resp_packet->data); + + if (enc_data_len < 0) { + log_error("Encrypting data failed"); + return false; + } + + memcpy(resp_packet->nounce, req_packet->nounce, sizeof(resp_packet->nounce)); + + resp_packet->length = pumpnet_prinet_proxy_packet_get_header_len() + enc_data_len; + + return true; +} \ No newline at end of file diff --git a/src/main/pumpnet/prinet-proxy/client.h b/src/main/pumpnet/prinet-proxy/client.h new file mode 100644 index 0000000..50b9a3f --- /dev/null +++ b/src/main/pumpnet/prinet-proxy/client.h @@ -0,0 +1,16 @@ +#pragma once + +#include +#include + +#include "pumpnet/prinet-proxy/packet.h" + +#include "util/iobuf.h" + +struct pumpnet_prinet_proxy_packet* pumpnet_prinet_proxy_client_recv_request(int handle); + +bool pumpnet_prinet_proxy_client_send_response(int handle, const struct pumpnet_prinet_proxy_packet* packet); + +bool pumpnet_prinet_proxy_client_unpack_data_request(const struct pumpnet_prinet_proxy_packet* packet, struct util_iobuf* dec_data); + +bool pumpnet_prinet_proxy_client_pack_data_response(const struct pumpnet_prinet_proxy_packet* req_packet, const struct util_iobuf* dec_data, struct pumpnet_prinet_proxy_packet* resp_packet); \ No newline at end of file diff --git a/src/main/pumpnet/prinet-proxy/main.c b/src/main/pumpnet/prinet-proxy/main.c index 40f6cf9..76f1656 100644 --- a/src/main/pumpnet/prinet-proxy/main.c +++ b/src/main/pumpnet/prinet-proxy/main.c @@ -3,8 +3,10 @@ #include #include "pumpnet/lib/prinet.h" -#include "pumpnet/prinet-proxy/options.h" +#include "pumpnet/prinet-proxy/client.h" +#include "pumpnet/prinet-proxy/keepalive.h" #include "pumpnet/prinet-proxy/packet.h" +#include "pumpnet/prinet-proxy/options.h" #include "sec/prinet/prinet.h" #include "util/iobuf.h" @@ -26,130 +28,6 @@ extern const uint8_t _binary_prime_private_key_end[]; extern const uint8_t _binary_prime_public_key_start[]; extern const uint8_t _binary_prime_public_key_end[]; -static bool _transform_data_request(const struct pumpnet_prinet_proxy_packet* packet, struct util_iobuf* dec_data) -{ - size_t enc_data_len = pumpnet_prinet_proxy_packet_get_data_len(packet); - - size_t dec_data_len = sec_prinet_decrypt( - packet->nounce, - sizeof(packet->nounce), - packet->data, - enc_data_len, - dec_data->bytes); - - if (dec_data_len < 0) { - log_error("Decrypting data failed"); - return false; - } - - dec_data->pos = dec_data_len; - - return true; -} - -static bool _transform_data_response(const struct pumpnet_prinet_proxy_packet* req_packet, const struct util_iobuf* dec_data, struct pumpnet_prinet_proxy_packet* resp_packet) -{ - size_t enc_data_len = sec_prinet_encrypt( - req_packet->nounce, - sizeof(req_packet->nounce), - dec_data->bytes, - dec_data->pos, - resp_packet->data); - - if (enc_data_len < 0) { - log_error("Encrypting data failed"); - return false; - } - - memcpy(resp_packet->nounce, req_packet->nounce, sizeof(resp_packet->nounce)); - - resp_packet->length = pumpnet_prinet_proxy_packet_get_header_len() + enc_data_len; - - return true; -} - -static bool _recv_packet_length(int handle, uint32_t* length) -{ - uint32_t packet_length; - - while (true) { - ssize_t read = util_sock_tcp_recv_block(handle, &packet_length, sizeof(uint32_t)); - - if (read == 0) { - log_error("Unexpected remote close and no data"); - return NULL; - } - - if (read != sizeof(uint32_t)) { - return false; - } - - break; - } - - *length = packet_length; - - return true; -} - -static struct pumpnet_prinet_proxy_packet* _recv_request_source(int handle) -{ - uint32_t packet_length; - - if (!_recv_packet_length(handle, &packet_length)) { - log_error("Receiving length field for request from source failed"); - return NULL; - } - - log_debug("Received length source request (%X): %d", handle, packet_length); - - struct pumpnet_prinet_proxy_packet* packet = util_xmalloc(packet_length); - packet->length = packet_length; - - size_t data_len = pumpnet_prinet_proxy_packet_get_data_len(packet); - - size_t read_pos = 0; - - while (true) { - size_t remaining_size = packet->length - sizeof(uint32_t) - read_pos; - - ssize_t read = util_sock_tcp_recv_block( - handle, - ((uint8_t*) packet) + sizeof(uint32_t) + read_pos, - remaining_size); - - if (read == 0) { - log_error("Unexpected remote close and no data"); - return NULL; - } - - if (read == -1) { - log_error("Receiving length field for request from source failed: %d", read); - return NULL; - } - - read_pos += read; - - if (read_pos >= data_len) { - break; - } - } - - return packet; -} - -static bool _send_response_source(int handle, const struct pumpnet_prinet_proxy_packet* packet) -{ - log_debug("Sending source response (%X): %d", handle, packet->length); - - if (util_sock_tcp_send_block(handle, packet, packet->length) != packet->length) { - log_error("Sending response, len %d, to source failed", packet->length); - return false; - } else { - return true; - } -} - static void _sigint_handler(int sig) { log_info("SIGINT, exiting"); @@ -246,7 +124,7 @@ int main(int argc, char** argv) struct util_iobuf pumpnet_data_resp; struct pumpnet_prinet_proxy_packet* source_resp = NULL; - source_req = _recv_request_source(source_con); + source_req = pumpnet_prinet_proxy_client_recv_request(source_con); if (!source_req) { log_error("Receiving request from source failed"); @@ -257,7 +135,7 @@ int main(int argc, char** argv) size_t source_data_len = pumpnet_prinet_proxy_packet_get_data_len(source_req); util_iobuf_alloc(&pumpnet_data_req, source_data_len); - if (!_transform_data_request(source_req, &pumpnet_data_req)) { + if (!pumpnet_prinet_proxy_client_unpack_data_request(source_req, &pumpnet_data_req)) { log_error("Transforming data request for destination failed"); inner_loop = false; goto cleanup_iteration; @@ -289,13 +167,13 @@ int main(int argc, char** argv) source_resp = pumpnet_prinet_proxy_packet_alloc_response(pumpnet_data_resp.pos); - if (!_transform_data_response(source_req, &pumpnet_data_resp, source_resp)) { + if (!pumpnet_prinet_proxy_client_pack_data_response(source_req, &pumpnet_data_resp, source_resp)) { log_error("Transforming data response for source failed"); inner_loop = false; goto cleanup_iteration; } - if (!_send_response_source(source_con, source_resp)) { + if (!pumpnet_prinet_proxy_client_send_response(source_con, source_resp)) { log_error("Sending response to source failed"); inner_loop = false; goto cleanup_iteration;