tor_multipath_voip/src/tor_echo.c

173 lines
4.7 KiB
C
Raw Normal View History

2019-03-11 09:45:21 +00:00
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include "tor_ctl.h"
#include "evt_core.h"
#include "net_tools.h"
2019-03-11 10:25:34 +00:00
#include "url.h"
2019-09-23 15:19:03 +00:00
#include "measure.h"
struct torecho_ctx {
uint8_t is_measlat;
struct measure_conf mc;
};
2019-03-11 09:45:21 +00:00
void te_create_onion_services(struct tor_os_str* tos, struct tor_ctl* tctl, uint16_t* ports, int ports_count, enum TOR_ONION_FLAGS tof) {
2020-02-01 22:33:45 +00:00
tor_os_create (tos, "onion_services.pub", "onion_services.txt", 1);
2019-03-11 09:45:21 +00:00
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);
}
2020-02-01 22:33:45 +00:00
err = tor_ctl_add_onion (tctl, tos, ports, ports_count, tof);
2019-03-11 09:45:21 +00:00
if (err != 0) {
fprintf(stderr, "Unable to create Onion Services (error: %d)\n", err);
exit(EXIT_FAILURE);
}
}
2019-03-11 10:25:34 +00:00
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);
2019-03-25 16:33:08 +00:00
if (conn_sock1 == -1 && errno == EAGAIN) return 1;
2019-03-11 10:25:34 +00:00
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);
2019-03-25 16:33:08 +00:00
return 0;
2019-03-11 10:25:34 +00:00
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) {
2019-03-11 09:45:21 +00:00
ssize_t nread, nwritten;
struct sockaddr_in addr;
socklen_t addrlen = sizeof(addr);
2019-09-23 15:19:03 +00:00
struct torecho_ctx *tctx = fdinfo->cat->app_ctx;
2019-03-11 09:45:21 +00:00
2019-09-23 15:19:03 +00:00
nread = recv(fdinfo->fd, tctx->mc.payload, tctx->mc.payload_size, 0);
2019-03-11 09:45:21 +00:00
if (nread == -1 && errno == EAGAIN) return 1; // Read done
2019-03-11 10:25:34 +00:00
if (nread == 0) { fprintf(stderr, "WARN! Read 0 bytes.\n"); return 1; }
2019-09-23 15:19:03 +00:00
if (nread < 0 || nread > tctx->mc.payload_size) {
fprintf(stderr, "Message is either truncated or an error occured. nread=%ld, expected=%ld\n", nread, tctx->mc.payload_size);
2019-03-11 09:45:21 +00:00
perror("read errno");
exit(EXIT_FAILURE);
}
2019-09-23 15:19:03 +00:00
if (tctx->is_measlat) measure_parse (nread, &tctx->mc);
nwritten = send(fdinfo->fd, tctx->mc.payload, nread, 0);
2019-03-11 09:45:21 +00:00
// @FIXME don't support EAGAIN on write. Could be intended, you don't think so?
if (nwritten != nread) {
2019-03-11 10:25:34 +00:00
fprintf(stderr, "Didn't write the same number of bytes as read - not supported. nread=%ld, nwritten=%ld\n", nread, nwritten);
2019-03-11 09:45:21 +00:00
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, err, opt;
2019-03-11 09:45:21 +00:00
struct evt_core_ctx evts = {0};
2019-03-11 10:25:34 +00:00
uint16_t ports[] = {7500};
int ports_count = sizeof(ports[0]) / sizeof(ports);
2019-03-11 09:45:21 +00:00
struct tor_os_str tos;
struct tor_ctl tctl;
enum TOR_ONION_FLAGS tof = TOR_ONION_FLAG_NONE;
2019-03-11 10:25:34 +00:00
char url[1024];
2019-09-23 15:19:03 +00:00
struct torecho_ctx tctx = {0};
2019-09-24 13:37:12 +00:00
tctx.mc.is_server = 1;
2019-09-23 15:19:03 +00:00
tctx.mc.payload_size = 1500;
2019-03-11 09:45:21 +00:00
2019-09-23 15:19:03 +00:00
while ((opt = getopt(argc, argv, "ns:m")) != -1) {
switch(opt) {
case 'n':
tof |= TOR_ONION_FLAG_NON_ANONYMOUS;
break;
2019-09-23 15:19:03 +00:00
case 'm':
tctx.is_measlat = 1;
break;
case 's':
tctx.mc.payload_size = atoi(optarg);
break;
default:
break;
}
}
2019-03-11 09:45:21 +00:00
// 1. Register categories
struct evt_core_cat tcp_co = {
2019-09-23 15:19:03 +00:00
.app_ctx = &tctx,
2019-03-11 09:45:21 +00:00
.free_app_ctx = NULL,
2019-03-11 10:25:34 +00:00
.cb = te_on_tcp_co,
2019-03-11 09:45:21 +00:00
.err_cb = NULL,
2019-03-11 10:25:34 +00:00
.name = "tcp-co",
2019-03-11 09:45:21 +00:00
.flags = EPOLLIN,
.socklist = NULL
};
struct evt_core_cat tcp_all = {
2019-09-24 13:37:12 +00:00
.app_ctx = &tctx ,
2019-03-11 09:45:21 +00:00
.free_app_ctx = NULL,
2019-03-11 10:25:34 +00:00
.cb = te_on_tcp,
2019-03-11 09:45:21 +00:00
.err_cb = NULL,
.name = "tcp-all",
2019-03-11 10:25:34 +00:00
.flags = EPOLLIN | EPOLLOUT | EPOLLET | EPOLLRDHUP,
2019-03-11 09:45:21 +00:00
.socklist = NULL
};
2019-09-23 15:19:03 +00:00
measure_prepare (&tctx.mc);
2019-04-01 12:16:41 +00:00
evt_core_init(&evts, 0);
2019-03-11 09:45:21 +00:00
evt_core_add_cat(&evts, &tcp_co);
evt_core_add_cat(&evts, &tcp_all);
printf("--- Categories created\n");
// 2. Create or load onion services
te_create_onion_services (&tos, &tctl, ports, ports_count, tof);
2019-03-11 09:45:21 +00:00
printf("--- Onion services created\n");
// 3. Create TCP server
2019-03-11 10:25:34 +00:00
sprintf(url, "%d", ports[0]);
tcp_serv_sock = create_tcp_server ("0.0.0.0", url);
err = listen(tcp_serv_sock, SOMAXCONN);
2019-03-11 09:45:21 +00:00
struct evt_core_cat cat = {0};
struct evt_core_fdinfo fdinfo = {0};
fdinfo.cat = &cat;
fdinfo.url = url;
2019-03-11 10:25:34 +00:00
fdinfo.fd = tcp_serv_sock;
sprintf(url, "tcp:co:127.0.0.1:%d", ports[0]);
fdinfo.cat->name = "tcp-co";
2019-03-11 09:45:21 +00:00
evt_core_add_fd(&evts, &fdinfo);
printf("--- TCP server is listening\n");
// 4. Start main loop
evt_core_loop (&evts);
return 0;
}