WIP socks5 - refactor socks5
This commit is contained in:
parent
1437f48042
commit
9d4aae315e
4 changed files with 110 additions and 133 deletions
|
@ -5,121 +5,69 @@ void load_onion_services(struct donar_client_ctx* ctx, char* onion_file, int por
|
|||
tor_os_read (&(ctx->tos));
|
||||
}
|
||||
|
||||
void init_tcp_client(struct donar_client_ctx* ctx, int i) {
|
||||
struct evt_core_cat cat = {0};
|
||||
struct evt_core_fdinfo fdinfo = {0};
|
||||
char url_buf[255];
|
||||
int err;
|
||||
|
||||
ctx->ports[i] = 7500 + i;
|
||||
cat.name = "configure-socks5";
|
||||
fdinfo.cat = &cat;
|
||||
fdinfo.url = url_buf;
|
||||
|
||||
while (1) {
|
||||
fdinfo.fd = create_tcp_client("127.0.0.1", "9050");
|
||||
if (fdinfo.fd < 0) goto failed_socks5;
|
||||
ctx->client_sock[i].fd = fdinfo.fd;
|
||||
ctx->client_sock[i].state = SOCKS5_STATE_NEW;
|
||||
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);
|
||||
if (err) goto failed_socks5;
|
||||
|
||||
break;
|
||||
failed_socks5:
|
||||
fprintf(stderr, "Failed connection for socket %d/%d. Sleeping 2 seconds...\n",i+1, CLIENT_PORT_SIZE);
|
||||
close(fdinfo.fd);
|
||||
sleep(2);
|
||||
}
|
||||
}
|
||||
|
||||
int configure_tcp_clients(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
|
||||
int err, pos;
|
||||
struct donar_client_ctx* app_ctx = (struct donar_client_ctx*) fdinfo->cat->app_ctx;
|
||||
|
||||
pos = -1;
|
||||
for (int i = 0; i < CLIENT_PORT_SIZE; i++) {
|
||||
if (app_ctx->client_sock[i].fd == fdinfo->fd) {
|
||||
pos = i;
|
||||
}
|
||||
}
|
||||
|
||||
char target_host[255];
|
||||
void init_socks5_client(struct donar_client_ctx* app_ctx, int pos) {
|
||||
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);
|
||||
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]);
|
||||
if (err < 0) goto on_socks5_err;
|
||||
app_ctx->client_sock[pos].state = SOCKS5_STATE_ACK;
|
||||
printf("Socket %d/%d %s:%d is connecting...\n", pos+1, CLIENT_PORT_SIZE, target_host, app_ctx->ports[pos]);
|
||||
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);
|
||||
}
|
||||
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);
|
||||
if (fdcat == NULL) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
struct evt_core_fdinfo fdinfo = {0};
|
||||
struct evt_core_cat cat = {0};
|
||||
char url[1024];
|
||||
fdinfo.cat = &cat;
|
||||
fdinfo.url = url;
|
||||
app_ctx->ports[pos] = 7500 + pos;
|
||||
socks5_create_dns_client (&app_ctx->evts, "127.0.0.1", "9050", target_host, app_ctx->ports[pos]);
|
||||
}
|
||||
|
||||
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);
|
||||
int on_socks5_success(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
|
||||
struct evt_core_fdinfo fdinfo_n = {0};
|
||||
struct evt_core_cat cat_n = {0};
|
||||
struct socks5_ctx* s5ctx = fdinfo->other;
|
||||
fdinfo_n.cat = &cat_n;
|
||||
int ret = 0;
|
||||
|
||||
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);
|
||||
fdinfo_n.fd = dup(fdinfo->fd);
|
||||
fdinfo_n.cat->name = "tcp-write";
|
||||
ret = asprintf(&fdinfo_n.url, "tcp:write:127.0.0.1:%d", s5ctx->port);
|
||||
if (ret < 0) goto failed;
|
||||
evt_core_add_fd (ctx, &fdinfo_n);
|
||||
|
||||
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;
|
||||
}
|
||||
fdinfo_n.fd = dup(fdinfo->fd);
|
||||
fdinfo_n.cat->name = "tcp-read";
|
||||
ret = asprintf(&fdinfo_n.url, "tcp:read:127.0.0.1:%d", s5ctx->port);
|
||||
if (ret < 0) goto failed;
|
||||
evt_core_add_fd (ctx, &fdinfo_n);
|
||||
|
||||
return 1;
|
||||
on_socks5_err:
|
||||
//perror("An error occured while connecting to an Onion Service");
|
||||
app_ctx->client_sock[pos].state = SOCKS5_STATE_ERR;
|
||||
evt_core_rm_fd (ctx, fdinfo->fd);
|
||||
sleep(2);
|
||||
init_tcp_client (app_ctx, pos);
|
||||
return 1;
|
||||
evt_core_rm_fd (ctx, fdinfo->fd);
|
||||
return 1;
|
||||
|
||||
failed:
|
||||
fprintf(stderr, "Memory allocation failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
int on_socks5_failed(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
|
||||
struct donar_client_ctx* app_ctx = fdinfo->cat->app_ctx;
|
||||
struct socks5_ctx* s5ctx = fdinfo->other;
|
||||
int pos = 7500 - s5ctx->port;
|
||||
|
||||
evt_core_rm_fd (ctx, fdinfo->fd);
|
||||
init_socks5_client (app_ctx, pos);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void init_socks5_sinks(struct donar_client_ctx* app_ctx) {
|
||||
struct evt_core_cat template = { 0 };
|
||||
|
||||
template.cb = on_socks5_success;
|
||||
template.name = "socks5-success";
|
||||
template.flags = EPOLLET;
|
||||
evt_core_add_cat(&app_ctx->evts, &template);
|
||||
|
||||
template.cb = on_socks5_failed;
|
||||
template.app_ctx = app_ctx;
|
||||
template.name = "socks5-failed";
|
||||
template.flags = EPOLLET;
|
||||
evt_core_add_cat(&app_ctx->evts, &template);
|
||||
}
|
||||
|
||||
void donar_client(struct donar_client_ctx* ctx, char* algoname,
|
||||
|
@ -128,16 +76,8 @@ void donar_client(struct donar_client_ctx* ctx, char* algoname,
|
|||
|
||||
evt_core_init (&(ctx->evts));
|
||||
init_algo(&ctx->evts, &algo, algoname);
|
||||
struct evt_core_cat init_socks5 = {
|
||||
.app_ctx = ctx,
|
||||
.free_app_ctx = NULL,
|
||||
.cb = configure_tcp_clients,
|
||||
.err_cb = NULL,
|
||||
.name = "configure-socks5",
|
||||
.flags = EPOLLIN | EPOLLET,
|
||||
.socklist = NULL
|
||||
};
|
||||
evt_core_add_cat (&(ctx->evts), &init_socks5);
|
||||
socks5_init (&ctx->evts);
|
||||
init_socks5_sinks(ctx);
|
||||
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));
|
||||
|
@ -149,7 +89,7 @@ void donar_client(struct donar_client_ctx* ctx, char* algoname,
|
|||
printf("--- Onion services loaded\n");
|
||||
|
||||
for (int i = 0; i < CLIENT_PORT_SIZE; i++) {
|
||||
init_tcp_client(ctx, i);
|
||||
init_socks5_client(ctx, i);
|
||||
}
|
||||
printf("--- TCP Clients Connected\n");
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmodule.h>
|
||||
|
|
51
src/socks5.c
51
src/socks5.c
|
@ -1,26 +1,11 @@
|
|||
#include "socks5.h"
|
||||
|
||||
struct socks5_ctx {
|
||||
struct client_handshake ch;
|
||||
struct server_handshake sh;
|
||||
struct client_request cr;
|
||||
struct server_reply sr;
|
||||
uint64_t ch_cursor;
|
||||
uint64_t sh_cursor;
|
||||
uint64_t cr_cursor;
|
||||
uint64_t sr_cursor;
|
||||
char cr_buffer[262];
|
||||
size_t ch_size;
|
||||
size_t cr_size;
|
||||
uint8_t sr_host_read;
|
||||
};
|
||||
|
||||
void socks5_free_ctx(void* elem) {
|
||||
struct socks5_ctx* ctx = elem;
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
void create_socks5_dns_client(struct evt_core_ctx* ctx, char* proxy_host, char* proxy_port, char* addr, uint16_t port) {
|
||||
void socks5_create_dns_client(struct evt_core_ctx* ctx, char* proxy_host, char* proxy_port, char* addr, uint16_t port) {
|
||||
struct evt_core_fdinfo fdinfo;
|
||||
struct evt_core_cat cat;
|
||||
struct socks5_ctx* s5ctx;
|
||||
|
@ -57,6 +42,7 @@ void create_socks5_dns_client(struct evt_core_ctx* ctx, char* proxy_host, char*
|
|||
|
||||
// 3. Fill socks5_ctx structures
|
||||
s5ctx = fdinfo.other;
|
||||
s5ctx->port = port;
|
||||
|
||||
// 3.1 Client handshake to send
|
||||
s5ctx->ch.ver = VER_SOCKS5;
|
||||
|
@ -292,6 +278,39 @@ move_to_failed:
|
|||
return 1;
|
||||
}
|
||||
|
||||
int on_socks5_err(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
|
||||
evt_core_mv_fd2 (ctx, fdinfo, "socks5-failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
void socks5_init(struct evt_core_ctx* ctx) {
|
||||
struct evt_core_cat template = {0};
|
||||
|
||||
template.cb = on_socks5_send_handshake;
|
||||
template.err_cb = on_socks5_err;
|
||||
template.name = "socks5-send-handshake";
|
||||
template.flags = EPOLLOUT | EPOLLET;
|
||||
evt_core_add_cat (ctx, &template);
|
||||
|
||||
template.cb = on_socks5_recv_handshake;
|
||||
template.err_cb = on_socks5_err;
|
||||
template.name = "socks5-recv-handshake";
|
||||
template.flags = EPOLLIN | EPOLLET;
|
||||
evt_core_add_cat (ctx, &template);
|
||||
|
||||
template.cb = on_socks5_send_client_req;
|
||||
template.err_cb = on_socks5_err;
|
||||
template.name = "socks5-send-client-req";
|
||||
template.flags = EPOLLOUT | EPOLLET;
|
||||
evt_core_add_cat(ctx, &template);
|
||||
|
||||
template.cb = on_socks5_recv_server_reply;
|
||||
template.err_cb = on_socks5_err;
|
||||
template.name = "socks5-recv-server-reply";
|
||||
template.flags = EPOLLIN | EPOLLET;
|
||||
evt_core_add_cat(ctx, &template);
|
||||
}
|
||||
|
||||
char* socks5_rep (enum socks5_rep rep) {
|
||||
return rep_msg[rep];
|
||||
}
|
||||
|
|
21
src/socks5.h
21
src/socks5.h
|
@ -107,6 +107,23 @@ struct server_reply {
|
|||
uint16_t port;
|
||||
};
|
||||
|
||||
void init_socks5(struct evt_core_ctx* ctx);
|
||||
void create_socks5_dns_client(struct evt_core_ctx* ctx, char* proxy_host, char* proxy_port, char* addr, uint16_t port);
|
||||
struct socks5_ctx {
|
||||
uint16_t port;
|
||||
|
||||
struct client_handshake ch;
|
||||
struct server_handshake sh;
|
||||
struct client_request cr;
|
||||
struct server_reply sr;
|
||||
uint64_t ch_cursor;
|
||||
uint64_t sh_cursor;
|
||||
uint64_t cr_cursor;
|
||||
uint64_t sr_cursor;
|
||||
char cr_buffer[262];
|
||||
size_t ch_size;
|
||||
size_t cr_size;
|
||||
uint8_t sr_host_read;
|
||||
};
|
||||
|
||||
void socks5_init(struct evt_core_ctx* ctx);
|
||||
void socks5_create_dns_client(struct evt_core_ctx* ctx, char* proxy_host, char* proxy_port, char* addr, uint16_t port);
|
||||
char* socks5_rep (enum socks5_rep rep);
|
||||
|
|
Loading…
Reference in a new issue