diff --git a/CMakeLists.txt b/CMakeLists.txt index 5adfd64..f2b545b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,6 +26,7 @@ list(APPEND CSOURCES src/donar_init.h src/donar_init.c src/algo_rr.c + src/algo_dup2.c src/algo_utils.h src/algo_utils.c src/proxy.h diff --git a/src/algo_dup2.c b/src/algo_dup2.c new file mode 100644 index 0000000..42de116 --- /dev/null +++ b/src/algo_dup2.c @@ -0,0 +1,79 @@ +#include "proxy.h" +#include "algo_utils.h" + +struct dup2_ctx { + uint16_t recv_id; + uint16_t emit_id; +}; + +void algo_dup2_init(struct evt_core_ctx* ctx, struct algo_ctx* app_ctx, struct algo_params* ap) { + app_ctx->misc = malloc(sizeof(struct dup2_ctx)); + if (app_ctx->misc == NULL) { + perror("malloc failed in algo dup2 init"); + exit(EXIT_FAILURE); + } + memset(app_ctx->misc, 0, sizeof(struct dup2_ctx)); +} + +int algo_dup2_on_stream(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo, struct buffer_packet* bp) { + char url[256]; + struct evt_core_fdinfo *to_fdinfo = NULL; + struct algo_ctx* app_ctx = fdinfo->cat->app_ctx; + + // Check that we didn't already received the packet + struct dup2_ctx* dup2c = app_ctx->misc; + if (ring_ge(dup2c->recv_id, bp->ip.ap.str.id)) + return 0; + dup2c->recv_id = bp->ip.ap.str.id; + + // 1. Find destination + sprintf(url, "udp:write:127.0.0.1:%d", bp->ip.ap.str.port); + to_fdinfo = evt_core_get_from_url (ctx, url); + if (to_fdinfo == NULL) { + fprintf(stderr, "No fd for URL %s in tcp-read. Dropping packet :( \n", url); + mv_buffer_wtof (app_ctx, fdinfo); + return 1; + } + + // 2. Move buffer + mv_buffer_rtow (app_ctx, fdinfo, to_fdinfo); + main_on_udp_write(ctx, to_fdinfo); + return 0; +} + +int algo_dup2_on_datagram(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo, struct buffer_packet* bp) { + char* url[] = { "tcp:write:127.0.0.1:7500", "tcp:write:127.0.0.1:7501" }; + struct evt_core_fdinfo *to_fdinfo = NULL; + struct algo_ctx* app_ctx = fdinfo->cat->app_ctx; + + struct dup2_ctx* dup2c = app_ctx->misc; + bp->ip.ap.str.id = dup2c->emit_id; + dup2c->emit_id = dup2c->emit_id + 1; + + for (int i = 0; i < 2; i++) { + // 1. A whole packet has been read, we will find someone to write it + to_fdinfo = evt_core_get_from_url (ctx, url[i]); + if (to_fdinfo == NULL) { + fprintf(stderr, "No fd for URL %s in udp-read. Dropping packet :( \n", url[i]); + mv_buffer_wtof (app_ctx, fdinfo); + break; + } + + // 2. We move the buffer and notify the target + if (i == 0) dup_buffer_tow (app_ctx, bp, to_fdinfo); + else mv_buffer_rtow (app_ctx, fdinfo, to_fdinfo); + main_on_tcp_write(ctx, to_fdinfo); + } + + return 0; +} + +int algo_dup2_on_timer(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) { + // We do nothing + return 0; +} + +int algo_dup2_on_err(struct evt_core_ctx *ctx, struct evt_core_fdinfo *fdinfo) { + // We do nothing + return 1; +}