tor_multipath_voip/src/donar_client.c

166 lines
5.5 KiB
C
Raw Normal View History

#include "donar_client.h"
void load_onion_services(struct donar_client_ctx* ctx, char* onion_file, int ports_count) {
tor_os_create (&(ctx->tos), onion_file, NULL, ports_count);
tor_os_read (&(ctx->tos));
}
2019-02-15 14:45:56 +00:00
void init_tcp_client(struct donar_client_ctx* ctx, int i) {
2019-02-18 13:35:09 +00:00
struct evt_core_cat cat = {0};
struct evt_core_fdinfo fdinfo = {0};
char url_buf[255];
int err;
2019-02-15 14:45:56 +00:00
ctx->ports[i] = 7500 + i;
2019-02-18 13:35:09 +00:00
cat.name = "configure-socks5";
fdinfo.cat = &cat;
fdinfo.url = url_buf;
2019-02-12 20:45:15 +00:00
2019-02-15 14:45:56 +00:00
while (1) {
2019-02-18 13:35:09 +00:00
fdinfo.fd = create_tcp_client("127.0.0.1", "9050");
if (fdinfo.fd < 0) goto failed_socks5;
ctx->client_sock[i].fd = fdinfo.fd;
2019-02-15 14:45:56 +00:00
ctx->client_sock[i].state = SOCKS5_STATE_NEW;
2019-02-18 13:35:09 +00:00
sprintf(url_buf, "socks5:dist:%d", i);
evt_core_add_fd (&(ctx->evts), &fdinfo);
//@FIXME: We suppose that we will be able to do the whole write at once which is wrong
err = socks5_handshake_syn(fdinfo.fd);
2019-02-15 14:45:56 +00:00
if (err) goto failed_socks5;
2019-02-12 20:45:15 +00:00
2019-02-15 14:45:56 +00:00
break;
2019-02-12 20:45:15 +00:00
failed_socks5:
fprintf(stderr, "Failed connection for socket %d/%d. Sleeping 2 seconds...\n",i+1, CLIENT_PORT_SIZE);
2019-02-18 13:35:09 +00:00
close(fdinfo.fd);
2019-02-12 20:45:15 +00:00
sleep(2);
}
}
2019-02-20 16:50:01 +00:00
int configure_tcp_clients(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
2019-02-15 14:45:56 +00:00
int err, pos;
struct donar_client_ctx* app_ctx = (struct donar_client_ctx*) fdinfo->cat->app_ctx;
2019-02-15 14:45:56 +00:00
pos = -1;
for (int i = 0; i < CLIENT_PORT_SIZE; i++) {
if (app_ctx->client_sock[i].fd == fdinfo->fd) {
2019-02-15 14:45:56 +00:00
pos = i;
}
}
char target_host[255];
if (strlen(app_ctx->tos.keys[pos].pub) > 254) {
fprintf(stderr, "Domain name is too long\n");
exit(EXIT_FAILURE);
}
sprintf(target_host, "%s.onion", app_ctx->tos.keys[pos].pub);
switch (app_ctx->client_sock[pos].state) {
case SOCKS5_STATE_NEW:
//@FIXME: We suppose that we will be able to do the whole read at once which is wrong
err = socks5_handshake_ack (fdinfo->fd);
2019-02-15 14:45:56 +00:00
if (err < 0) goto on_socks5_err;
//@FIXME: We suppose that we will be able to do the whole write at once which is wrong too
err = socks5_connect_dns(fdinfo->fd, target_host, app_ctx->ports[pos]);
2019-02-15 14:45:56 +00:00
if (err < 0) goto on_socks5_err;
app_ctx->client_sock[pos].state = SOCKS5_STATE_ACK;
2019-03-05 15:32:01 +00:00
printf("Socket %d/%d %s:%d is connecting...\n", pos+1, CLIENT_PORT_SIZE, target_host, app_ctx->ports[pos]);
2019-02-15 14:45:56 +00:00
break;
case SOCKS5_STATE_ACK:
//@FIXME: We suppose that we will be able to do the whole read at once which is wrong too
err = socks5_reply (fdinfo->fd);
if (err == -SOCKS5_REP_GENERAL_FAILURE || err == -SOCKS5_REP_TTLEXP || err == -SOCKS5_REP_HOSTUNREACH) {
fprintf(stderr, "%s is not ready, received %s\n", fdinfo->url, socks5_rep(-err));
goto on_socks5_err;
} else if (err < 0) {
fprintf(stderr, "An other error occured on %s\n", fdinfo->url);
exit(EXIT_FAILURE);
}
2019-02-15 14:45:56 +00:00
app_ctx->client_sock[pos].state = SOCKS5_STATE_RDY;
int sock1, sock2;
sock1 = dup(fdinfo->fd);
sock2 = dup(fdinfo->fd);
if (sock1 < 0 || sock2 < 0) {
exit(EXIT_FAILURE);
}
void* fdcat = evt_core_rm_fd (ctx, fdinfo->fd);
2019-03-05 15:57:14 +00:00
if (fdcat == NULL) {
exit(EXIT_FAILURE);
}
2019-02-18 13:35:09 +00:00
struct evt_core_fdinfo fdinfo = {0};
struct evt_core_cat cat = {0};
char url[1024];
fdinfo.cat = &cat;
fdinfo.url = url;
fdinfo.cat->name = "tcp-write";
fdinfo.fd = sock1;
sprintf(fdinfo.url, "tcp:write:127.0.0.1:%d", app_ctx->ports[pos]);
evt_core_add_fd (ctx, &fdinfo);
fdinfo.cat->name = "tcp-read";
fdinfo.fd = sock2;
sprintf(fdinfo.url, "tcp:read:127.0.0.1:%d", app_ctx->ports[pos]);
evt_core_add_fd (ctx, &fdinfo);
2019-02-15 14:45:56 +00:00
printf("Socket %d/%d %s:%d has been added to the pool!\n", pos+1, CLIENT_PORT_SIZE, target_host, app_ctx->ports[pos]);
break;
case SOCKS5_STATE_RDY:
goto on_socks5_err;
break;
case SOCKS5_STATE_ERR:
goto on_socks5_err;
break;
}
2019-02-20 16:50:01 +00:00
return 1;
2019-02-15 14:45:56 +00:00
on_socks5_err:
//perror("An error occured while connecting to an Onion Service");
2019-02-15 14:45:56 +00:00
app_ctx->client_sock[pos].state = SOCKS5_STATE_ERR;
evt_core_rm_fd (ctx, fdinfo->fd);
2019-02-20 08:34:10 +00:00
sleep(2);
2019-02-15 14:45:56 +00:00
init_tcp_client (app_ctx, pos);
2019-02-22 15:01:22 +00:00
return 1;
2019-02-15 14:45:56 +00:00
}
2019-03-19 16:09:42 +00:00
void donar_client(struct donar_client_ctx* ctx, char* algoname,
2019-02-19 18:15:37 +00:00
char* onion_file, GPtrArray* exposed_ports, GPtrArray* remote_ports) {
2019-03-19 16:09:42 +00:00
struct algo_skel algo = {0};
evt_core_init (&(ctx->evts));
2019-03-19 16:09:42 +00:00
init_algo(&ctx->evts, &algo, algoname);
2019-02-15 14:45:56 +00:00
struct evt_core_cat init_socks5 = {
.app_ctx = ctx,
.free_app_ctx = NULL,
.cb = configure_tcp_clients,
2019-03-05 15:57:14 +00:00
.err_cb = NULL,
2019-02-15 14:45:56 +00:00
.name = "configure-socks5",
.flags = EPOLLIN | EPOLLET,
.socklist = NULL
};
evt_core_add_cat (&(ctx->evts), &init_socks5);
2019-03-19 16:09:42 +00:00
evt_core_add_cat (&(ctx->evts), &(algo.on_tcp_co));
evt_core_add_cat (&(ctx->evts), &(algo.on_udp_read));
evt_core_add_cat (&(ctx->evts), &(algo.on_tcp_read));
evt_core_add_cat (&(ctx->evts), &(algo.on_udp_write));
evt_core_add_cat (&(ctx->evts), &(algo.on_tcp_write));
printf("--- Categories created\n");
load_onion_services (ctx, onion_file, CLIENT_PORT_SIZE);
printf("--- Onion services loaded\n");
2019-02-14 14:40:05 +00:00
2019-02-15 14:45:56 +00:00
for (int i = 0; i < CLIENT_PORT_SIZE; i++) {
init_tcp_client(ctx, i);
}
2019-02-12 20:45:15 +00:00
printf("--- TCP Clients Connected\n");
2019-02-14 14:40:05 +00:00
2019-02-19 18:15:37 +00:00
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));
tor_os_free (&(ctx->tos));
}