#include #include #include #include #include "tor_ctl.h" #include "evt_core.h" #include "net_tools.h" void 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); int err = 0; err = tor_ctl_connect (tctl, "127.0.0.1", "9051"); if (err < 0) { fprintf(stderr, "Unable to open Tor Socket\n"); exit(EXIT_FAILURE); } err = tor_ctl_add_onion (tctl, tos, ports); if (err != 0) { fprintf(stderr, "Unable to create Onion Services (error: %d)\n", err); exit(EXIT_FAILURE); } } int 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); if (nread == -1 && errno == EAGAIN) return 1; // Read done 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); // @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); perror("write errno"); exit(EXIT_FAILURE); } return 0; } int main(int argc, char** argv) { setvbuf(stdout, NULL, _IONBF, 0); printf("~ torecho ~\n"); int tcp_serv_sock = 0; struct evt_core_ctx evts = {0}; uint16_t ports = {7500}; int port_count = sizeof(ports[0]) / sizeof(ports); struct tor_os_str tos; struct tor_ctl tctl; // 1. Register categories struct evt_core_cat tcp_co = { .app_ctx = NULL, .free_app_ctx = NULL, .cb = on_tcp_co, .err_cb = NULL, .name = "tcp-all", .flags = EPOLLIN, .socklist = NULL }; struct evt_core_cat tcp_all = { .app_ctx = NULL, .free_app_ctx = NULL, .cb = on_tcp, .err_cb = NULL, .name = "tcp-all", .flags = EPOLLIN | EPOLLOUT | EPOLLET, .socklist = NULL }; evt_core_init(&evts); evt_core_add_cat(&evts, &tcp_co); evt_core_add_cat(&evts, &tcp_all); printf("--- Categories created\n"); // 2. Create or load onion services 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]); 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"; evt_core_add_fd(&evts, &fdinfo); printf("--- TCP server is listening\n"); // 4. Start main loop evt_core_loop (&evts); return 0; }