From 76f11a2defa6e30ebd19ff0f68b6f51d948e08e7 Mon Sep 17 00:00:00 2001 From: Quentin Dufour Date: Mon, 11 Mar 2019 11:25:34 +0100 Subject: [PATCH] Working TCP echo --- src/tor_echo.c | 71 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 52 insertions(+), 19 deletions(-) diff --git a/src/tor_echo.c b/src/tor_echo.c index d07d2bc..6457576 100644 --- a/src/tor_echo.c +++ b/src/tor_echo.c @@ -5,8 +5,9 @@ #include "tor_ctl.h" #include "evt_core.h" #include "net_tools.h" +#include "url.h" -void create_onion_services(struct tor_os_str* tos, struct tor_ctl* tctl, uint16_t* ports, int ports_count) { +void te_create_onion_services(struct tor_os_str* tos, struct tor_ctl* tctl, uint16_t* ports, int ports_count) { tor_os_create (tos, "onion_services.pub", "onion_services.txt", ports_count); tor_os_read (tos); @@ -23,24 +24,54 @@ void create_onion_services(struct tor_os_str* tos, struct tor_ctl* tctl, uint16_ } } -int on_tcp(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) { +int te_on_tcp_co(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) { + int conn_sock1, conn_sock2; + struct sockaddr_in addr; + socklen_t in_len; + char url[1024], port[6]; + struct evt_core_cat local_cat = {0}; + struct evt_core_fdinfo to_fdinfo = {0}; + to_fdinfo.cat = &local_cat; + to_fdinfo.url = url; + + in_len = sizeof(addr); + conn_sock1 = accept(fdinfo->fd, (struct sockaddr*)&addr, &in_len); + + if (conn_sock1 == -1) goto co_error; + + url_get_port(port, fdinfo->url); + + to_fdinfo.fd = conn_sock1; + to_fdinfo.cat->name = "tcp-all"; + sprintf(to_fdinfo.url, "tcp:all:127.0.0.1:%s", port); + evt_core_add_fd (ctx, &to_fdinfo); + + return 1; + +co_error: + perror("Failed to handle new connection"); + exit(EXIT_FAILURE); +} + +int te_on_tcp(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) { char buffer[1500]; ssize_t nread, nwritten; struct sockaddr_in addr; socklen_t addrlen = sizeof(addr); - nread = recvfrom(fdinfo->fd, buffer, sizeof(buffer), MSG_TRUNC, (struct sockaddr*)&addr, &addrlen); + nread = recv(fdinfo->fd, buffer, sizeof(buffer), 0); if (nread == -1 && errno == EAGAIN) return 1; // Read done - if (nread <= 0 || nread > sizeof(buffer)) { + if (nread == 0) { fprintf(stderr, "WARN! Read 0 bytes.\n"); return 1; } + if (nread < 0 || nread > sizeof(buffer)) { fprintf(stderr, "Message is either truncated or an error occured. nread=%ld\n", nread); perror("read errno"); exit(EXIT_FAILURE); } - nwritten = sendto(fdinfo->fd, buffer, nread, 0, (struct sockaddr*)&addr, addrlen); + nwritten = send(fdinfo->fd, buffer, nread, 0); // @FIXME don't support EAGAIN on write. Could be intended, you don't think so? if (nwritten != nread) { - fprintf(stderr, "Didn't write the same number of bytes as read. nread=%ld, nwritten=%ld\n", nread, nwritten); + fprintf(stderr, "Didn't write the same number of bytes as read - not supported. nread=%ld, nwritten=%ld\n", nread, nwritten); perror("write errno"); exit(EXIT_FAILURE); } @@ -51,30 +82,31 @@ int main(int argc, char** argv) { setvbuf(stdout, NULL, _IONBF, 0); printf("~ torecho ~\n"); - int tcp_serv_sock = 0; + int tcp_serv_sock = 0, err; struct evt_core_ctx evts = {0}; - uint16_t ports = {7500}; - int port_count = sizeof(ports[0]) / sizeof(ports); + uint16_t ports[] = {7500}; + int ports_count = sizeof(ports[0]) / sizeof(ports); struct tor_os_str tos; struct tor_ctl tctl; + char url[1024]; // 1. Register categories struct evt_core_cat tcp_co = { .app_ctx = NULL, .free_app_ctx = NULL, - .cb = on_tcp_co, + .cb = te_on_tcp_co, .err_cb = NULL, - .name = "tcp-all", + .name = "tcp-co", .flags = EPOLLIN, .socklist = NULL }; struct evt_core_cat tcp_all = { .app_ctx = NULL, .free_app_ctx = NULL, - .cb = on_tcp, + .cb = te_on_tcp, .err_cb = NULL, .name = "tcp-all", - .flags = EPOLLIN | EPOLLOUT | EPOLLET, + .flags = EPOLLIN | EPOLLOUT | EPOLLET | EPOLLRDHUP, .socklist = NULL }; evt_core_init(&evts); @@ -83,21 +115,22 @@ int main(int argc, char** argv) { printf("--- Categories created\n"); // 2. Create or load onion services - create_onion_services (&tos, &tctl, ports, ports_count); + te_create_onion_services (&tos, &tctl, ports, ports_count); printf("--- Onion services created\n"); // 3. Create TCP server - tcp_serv_sock = create_tcp_server ("127.0.0.1", ports[0]); + sprintf(url, "%d", ports[0]); + tcp_serv_sock = create_tcp_server ("0.0.0.0", url); + err = listen(tcp_serv_sock, SOMAXCONN); - char url[1024]; struct evt_core_cat cat = {0}; struct evt_core_fdinfo fdinfo = {0}; fdinfo.cat = &cat; fdinfo.url = url; - fdinfo.fd = udp_sock; - sprintf(url, "tcp:all:127.0.0.1:%s", port); - fdinfo.cat->name = "tcp-all"; + fdinfo.fd = tcp_serv_sock; + sprintf(url, "tcp:co:127.0.0.1:%d", ports[0]); + fdinfo.cat->name = "tcp-co"; evt_core_add_fd(&evts, &fdinfo); printf("--- TCP server is listening\n");