From 603c67b1d9ff551fd67fac8e3ce54756b37bbd8b Mon Sep 17 00:00:00 2001 From: Quentin Dufour Date: Tue, 19 Feb 2019 19:15:37 +0100 Subject: [PATCH] Refactor how UDP ports are handled --- CMakeLists.txt | 2 ++ src/donar.c | 33 ++++++++++------- src/donar_client.c | 58 ++++-------------------------- src/donar_client.h | 4 ++- src/donar_init.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++ src/donar_init.h | 10 ++++++ src/donar_server.c | 58 ++++-------------------------- src/donar_server.h | 4 ++- 8 files changed, 141 insertions(+), 117 deletions(-) create mode 100644 src/donar_init.c create mode 100644 src/donar_init.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 4def587..25996eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,8 @@ list(APPEND CSOURCES src/packet.c src/url.h src/url.c + src/donar_init.h + src/donar_init.c ) add_executable(donar ${CSOURCES} src/donar.c) diff --git a/src/donar.c b/src/donar.c index 7dfe2fe..6aa704a 100644 --- a/src/donar.c +++ b/src/donar.c @@ -22,17 +22,23 @@ int main(int argc, char** argv) { is_server = 0; is_client = 0; errored = 0; - GPtrArray* ports = g_ptr_array_new_with_free_func (free_port); + GPtrArray* remote_ports = g_ptr_array_new_with_free_func (free_port); + GPtrArray* exposed_ports = g_ptr_array_new_with_free_func (free_port); - while ((opt = getopt(argc, argv, "csh:p:o:a:")) != -1) { + while ((opt = getopt(argc, argv, "csh:e:r:o:a:")) != -1) { switch(opt) { case 's': is_server = 1; break; - case 'p': + case 'e': port = strdup(optarg); if (port == NULL) goto terminate; - g_ptr_array_add (ports, port); + g_ptr_array_add (exposed_ports, port); + break; + case 'r': + port = strdup(optarg); + if (port == NULL) goto terminate; + g_ptr_array_add (remote_ports, port); break; case 'o': onion_file = strdup(optarg); @@ -56,26 +62,27 @@ int main(int argc, char** argv) { if (is_server) { struct donar_server_ctx ctx; - if (ports->len < 1) goto in_error; - donar_server(&ctx, &as, ports); + if (exposed_ports->len < 1 && remote_ports->len) goto in_error; + donar_server(&ctx, &as, exposed_ports, remote_ports); } else if (is_client) { struct donar_client_ctx ctx; - if (ports->len < 1 || onion_file == NULL) goto in_error; - donar_client(&ctx, &as, onion_file, ports); + if ((exposed_ports->len < 1 && remote_ports->len) || onion_file == NULL) goto in_error; + donar_client(&ctx, &as, onion_file, exposed_ports, remote_ports); } goto terminate; in_error: errored = 1; - fprintf(stderr, "Usage as client : %s -c -a -p -p -o \n", argv[0]); - fprintf(stderr, "Usage as server : %s -s -a -p -p \n\n", argv[0]); - fprintf(stderr, "Passed parameters: client=%d, server=%d, algo=%s, registered_ports=%d, onion_file=%s\n", - is_client, is_server, algo, ports->len, onion_file); + fprintf(stderr, "Usage as client : %s -c -a -o -e -r \n", argv[0]); + fprintf(stderr, "Usage as server : %s -s -a -e -r \n\n", argv[0]); + fprintf(stderr, "Passed parameters: client=%d, server=%d, algo=%s, exposed_ports=%d, remote_ports=%d, onion_file=%s\n", + is_client, is_server, algo, exposed_ports->len, remote_ports->len, onion_file); terminate: if (onion_file != NULL) free(onion_file); if (algo != NULL) free(algo); - g_ptr_array_free(ports, TRUE); + g_ptr_array_free(exposed_ports, TRUE); + g_ptr_array_free(remote_ports, TRUE); return errored; } diff --git a/src/donar_client.c b/src/donar_client.c index 0b845d8..29f053c 100644 --- a/src/donar_client.c +++ b/src/donar_client.c @@ -110,55 +110,8 @@ on_socks5_err: init_tcp_client (app_ctx, pos); } -void free_udp_t(void* v) { - struct udp_target* udp_t = v; - udp_t->ref_count--; - if (udp_t <= 0) { - free(udp_t); - } -} - -void init_udp_socket(char* port, struct donar_client_ctx* ctx) { - int sock1, sock2; - char url[1024]; - struct evt_core_cat cat = {0}; - struct evt_core_fdinfo fdinfo = {0}; - - // 1. Init shared parameters for the fdinfo structure - struct udp_target* udp_t = malloc(sizeof(struct udp_target)); - if (udp_t == NULL) goto socket_failed; - memset(udp_t, 0, sizeof(struct udp_target)); - udp_t->ref_count = 2; - - fdinfo.cat = &cat; - fdinfo.url = url; - fdinfo.free_other = free_udp_t; - fdinfo.other = udp_t; - - // 2. Duplicate sockets - sock1 = create_udp_server (port); - if (sock1 < 0) goto socket_failed; - sock2 = dup(sock1); - if (sock2 < 0) goto socket_failed; - - // 3. Register them - fdinfo.cat->name = "udp-read"; - fdinfo.fd = sock1; - sprintf(fdinfo.url, "udp:read:127.0.0.1:%s", port); - evt_core_add_fd (&(ctx->evts), &fdinfo); - - fdinfo.cat->name = "udp-write"; - fdinfo.fd = sock2; - sprintf(fdinfo.url, "udp:write:127.0.0.1:%s", port); - evt_core_add_fd (&(ctx->evts), &fdinfo); - return; - -socket_failed: - fprintf(stderr, "UDP socket init failed\n"); - exit(EXIT_FAILURE); -} - -void donar_client(struct donar_client_ctx* ctx, struct algo_skel* algo, char* onion_file, GPtrArray* ports) { +void donar_client(struct donar_client_ctx* ctx, struct algo_skel* algo, + char* onion_file, GPtrArray* exposed_ports, GPtrArray* remote_ports) { evt_core_init (&(ctx->evts)); struct evt_core_cat init_socks5 = { .app_ctx = ctx, @@ -184,8 +137,11 @@ void donar_client(struct donar_client_ctx* ctx, struct algo_skel* algo, char* on } printf("--- TCP Clients Connected\n"); - g_ptr_array_foreach (ports, (void(*)(void*, void*))init_udp_socket, ctx); - printf("--- UDP Sockets are configured\n"); + g_ptr_array_foreach (remote_ports, (void(*)(void*, void*))init_udp_remote, &(ctx->evts)); + printf("--- Remote ports are binded locally\n"); + + g_ptr_array_foreach (exposed_ports, (void(*)(void*, void*))init_udp_exposed, &(ctx->evts)); + printf("--- Local UDP services are exposed\n"); evt_core_loop(&(ctx->evts)); diff --git a/src/donar_client.h b/src/donar_client.h index 5f44fba..248bdb1 100644 --- a/src/donar_client.h +++ b/src/donar_client.h @@ -5,6 +5,7 @@ #include "algo_skel.h" #include "tor_os.h" #include "socks5.h" +#include "donar_init.h" #define CLIENT_PORT_SIZE 10 @@ -18,4 +19,5 @@ struct donar_client_ctx { } client_sock[CLIENT_PORT_SIZE]; }; -void donar_client(struct donar_client_ctx* ctx, struct algo_skel* as, char* onion_file, GPtrArray* ports); +void donar_client(struct donar_client_ctx* ctx, struct algo_skel* as, + char* onion_file, GPtrArray* exposed_ports, GPtrArray* remote_ports); diff --git a/src/donar_init.c b/src/donar_init.c new file mode 100644 index 0000000..8a7c79b --- /dev/null +++ b/src/donar_init.c @@ -0,0 +1,89 @@ +#include "donar_init.h" + +void free_udp_t(void* v) { + struct udp_target* udp_t = v; + udp_t->ref_count--; + if (udp_t <= 0) { + free(udp_t); + } +} + +void init_udp_remote(char* port, struct evt_core_ctx* evts) { + int sock1, sock2; + char url[1024]; + struct evt_core_cat cat = {0}; + struct evt_core_fdinfo fdinfo = {0}; + + // 1. Init shared parameters for the fdinfo structure + struct udp_target* udp_t = malloc(sizeof(struct udp_target)); + if (udp_t == NULL) goto socket_failed; + memset(udp_t, 0, sizeof(struct udp_target)); + udp_t->ref_count = 2; + + fdinfo.cat = &cat; + fdinfo.url = url; + fdinfo.free_other = free_udp_t; + fdinfo.other = udp_t; + + // 2. Duplicate sockets + sock1 = create_udp_server (port); + if (sock1 < 0) goto socket_failed; + sock2 = dup(sock1); + if (sock2 < 0) goto socket_failed; + + // 3. Register them + fdinfo.cat->name = "udp-read"; + fdinfo.fd = sock1; + sprintf(fdinfo.url, "udp:read:127.0.0.1:%s", port); + evt_core_add_fd (evts, &fdinfo); + + fdinfo.cat->name = "udp-write"; + fdinfo.fd = sock2; + sprintf(fdinfo.url, "udp:write:127.0.0.1:%s", port); + evt_core_add_fd (evts, &fdinfo); + return; + +socket_failed: + fprintf(stderr, "UDP socket init failed\n"); + exit(EXIT_FAILURE); +} + +void init_udp_exposed(char* port, struct evt_core_ctx* evts) { + int sock1, sock2; + char url[1024]; + + struct evt_core_cat cat = {0}; + struct evt_core_fdinfo fdinfo = {0}; + + // 1. Init shared parameters for the fdinfo structure + struct udp_target* udp_t = malloc(sizeof(struct udp_target)); + if (udp_t == NULL) goto socket_failed; + memset(udp_t, 0, sizeof(struct udp_target)); + udp_t->ref_count = 2; + + fdinfo.cat = &cat; + fdinfo.url = url; + fdinfo.free_other = free_udp_t; + fdinfo.other = udp_t; + + sock1 = create_udp_client ("127.0.0.1", port); + if (sock1 < 0) goto socket_failed; + sock2 = dup(sock1); + if (sock2 < 0) goto socket_failed; + + fdinfo.fd = sock1; + fdinfo.cat->name = "udp-read"; + sprintf(fdinfo.url, "udp:read:127.0.0.1:%s", port); + evt_core_add_fd (evts, &fdinfo); + + fdinfo.fd = sock2; + fdinfo.cat->name = "udp-write"; + sprintf(fdinfo.url, "udp:write:127.0.0.1:%s", port); + evt_core_add_fd (evts, &fdinfo); + + return; + +socket_failed: + fprintf(stderr, "UDP socket init failed\n"); + exit(EXIT_FAILURE); +} diff --git a/src/donar_init.h b/src/donar_init.h new file mode 100644 index 0000000..bb6fe6c --- /dev/null +++ b/src/donar_init.h @@ -0,0 +1,10 @@ +#pragma once +#include +#include +#include +#include "net_tools.h" +#include "evt_core.h" +#include "packet.h" + +void init_udp_remote(char* port, struct evt_core_ctx* evts); +void init_udp_exposed(char* port, struct evt_core_ctx* evts); diff --git a/src/donar_server.c b/src/donar_server.c index d062d27..7ac07b9 100644 --- a/src/donar_server.c +++ b/src/donar_server.c @@ -50,55 +50,8 @@ socket_create_err: exit(EXIT_FAILURE); } -void free_udp_ts(void* v) { - struct udp_target* udp_t = v; - udp_t->ref_count--; - if (udp_t <= 0) { - free(udp_t); - } -} - -void serv_init_udp_socket(char* port, struct donar_server_ctx* ctx) { - int sock1, sock2; - char url[1024]; - - struct evt_core_cat cat = {0}; - struct evt_core_fdinfo fdinfo = {0}; - - // 1. Init shared parameters for the fdinfo structure - struct udp_target* udp_t = malloc(sizeof(struct udp_target)); - if (udp_t == NULL) goto socket_failed; - memset(udp_t, 0, sizeof(struct udp_target)); - udp_t->ref_count = 2; - - fdinfo.cat = &cat; - fdinfo.url = url; - fdinfo.free_other = free_udp_ts; - fdinfo.other = udp_t; - - sock1 = create_udp_client ("127.0.0.1", port); - if (sock1 < 0) goto socket_failed; - sock2 = dup(sock1); - if (sock2 < 0) goto socket_failed; - - fdinfo.fd = sock1; - fdinfo.cat->name = "udp-read"; - sprintf(fdinfo.url, "udp:read:127.0.0.1:%s", port); - evt_core_add_fd (&(ctx->evts), &fdinfo); - - fdinfo.fd = sock2; - fdinfo.cat->name = "udp-write"; - sprintf(fdinfo.url, "udp:write:127.0.0.1:%s", port); - evt_core_add_fd (&(ctx->evts), &fdinfo); - - return; - -socket_failed: - fprintf(stderr, "UDP socket init failed\n"); - exit(EXIT_FAILURE); -} - -void donar_server(struct donar_server_ctx* ctx, struct algo_skel* algo, GPtrArray* ports) { +void donar_server(struct donar_server_ctx* ctx, struct algo_skel* algo, + GPtrArray* exposed_ports, GPtrArray* remote_ports) { evt_core_init (&(ctx->evts)); evt_core_add_cat (&(ctx->evts), &(algo->on_tcp_co)); evt_core_add_cat (&(ctx->evts), &(algo->on_udp_read)); @@ -113,12 +66,15 @@ void donar_server(struct donar_server_ctx* ctx, struct algo_skel* algo, GPtrArra } create_onion_services (&(ctx->tos), &(ctx->tctl), ctx->ports, PORT_SIZE); printf("--- Onion services created\n"); + init_tcp_servers(ctx); printf("--- TCP servers are listening\n"); - g_ptr_array_foreach (ports, (void(*)(void*, void*))serv_init_udp_socket, ctx); - printf("--- UDP Sockets are configured\n"); + g_ptr_array_foreach (remote_ports, (void(*)(void*, void*))init_udp_remote, &(ctx->evts)); + printf("--- Remote ports are binded locally\n"); + g_ptr_array_foreach (exposed_ports, (void(*)(void*, void*))init_udp_exposed, &(ctx->evts)); + printf("--- Local UDP services are exposed\n"); evt_core_loop (&(ctx->evts)); destroy_resources (&(ctx->tos), &(ctx->tctl)); diff --git a/src/donar_server.h b/src/donar_server.h index 728a2bb..d021d8f 100644 --- a/src/donar_server.h +++ b/src/donar_server.h @@ -9,6 +9,7 @@ #include "tor_ctl.h" #include "evt_core.h" #include "algo_skel.h" +#include "donar_init.h" #define PORT_SIZE 10 @@ -19,4 +20,5 @@ struct donar_server_ctx { uint16_t ports[PORT_SIZE]; }; -void donar_server(struct donar_server_ctx* ctx, struct algo_skel* algo, GPtrArray* ports); +void donar_server(struct donar_server_ctx* ctx, struct algo_skel* algo, + GPtrArray* exposed_ports, GPtrArray* remote_ports);