Reimplement UDP client + fix cb signature

This commit is contained in:
Quentin Dufour 2019-02-19 10:32:33 +01:00
parent 5e291f21a7
commit fc039b6045
6 changed files with 35 additions and 20 deletions

View file

@ -23,6 +23,8 @@ list(APPEND CSOURCES
src/utils.c src/utils.c
src/packet.h src/packet.h
src/packet.c src/packet.c
src/url.h
src/url.c
) )
add_executable(donar ${CSOURCES} src/donar.c) add_executable(donar ${CSOURCES} src/donar.c)

View file

@ -25,11 +25,6 @@ void free_naive(void* app_ctx) {
free(ctx); free(ctx);
} }
char* get_port(char* out, char* in) {
sscanf(in, "%*[a-z]:%*[a-z]:%*[a-zA-Z0-9.]:%[0-9]", out);
return out;
}
void on_tcp_co(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) { void on_tcp_co(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
int conn_sock1, conn_sock2; int conn_sock1, conn_sock2;
struct sockaddr_in addr; struct sockaddr_in addr;
@ -48,7 +43,7 @@ void on_tcp_co(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
if (conn_sock2 == -1) goto co_error; if (conn_sock2 == -1) goto co_error;
//printf("fd=%d accepts, creating fds=%d,%d\n", fd, conn_sock1, conn_sock2); //printf("fd=%d accepts, creating fds=%d,%d\n", fd, conn_sock1, conn_sock2);
get_port(port, fdinfo->url); url_get_port(port, fdinfo->url);
to_fdinfo.fd = conn_sock1; to_fdinfo.fd = conn_sock1;
to_fdinfo.cat->name = "tcp-read"; to_fdinfo.cat->name = "tcp-read";

View file

@ -6,6 +6,7 @@
#include "packet.h" #include "packet.h"
#include "evt_core.h" #include "evt_core.h"
#include "utils.h" #include "utils.h"
#include "url.h"
struct algo_skel { struct algo_skel {
struct evt_core_cat on_udp_read; struct evt_core_cat on_udp_read;

View file

@ -35,13 +35,13 @@ failed_socks5:
} }
} }
void configure_tcp_clients(struct evt_core_ctx* ctx, struct evt_core_cat* cat, int fd) { void configure_tcp_clients(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
int err, pos; int err, pos;
struct donar_client_ctx* app_ctx = (struct donar_client_ctx*) cat->app_ctx; struct donar_client_ctx* app_ctx = (struct donar_client_ctx*) fdinfo->cat->app_ctx;
pos = -1; pos = -1;
for (int i = 0; i < CLIENT_PORT_SIZE; i++) { for (int i = 0; i < CLIENT_PORT_SIZE; i++) {
if (app_ctx->client_sock[i].fd == fd) { if (app_ctx->client_sock[i].fd == fdinfo->fd) {
pos = i; pos = i;
} }
} }
@ -56,24 +56,24 @@ void configure_tcp_clients(struct evt_core_ctx* ctx, struct evt_core_cat* cat, i
switch (app_ctx->client_sock[pos].state) { switch (app_ctx->client_sock[pos].state) {
case SOCKS5_STATE_NEW: case SOCKS5_STATE_NEW:
//@FIXME: We suppose that we will be able to do the whole read at once which is wrong //@FIXME: We suppose that we will be able to do the whole read at once which is wrong
err = socks5_handshake_ack (fd); err = socks5_handshake_ack (fdinfo->fd);
if (err < 0) goto on_socks5_err; 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 //@FIXME: We suppose that we will be able to do the whole write at once which is wrong too
err = socks5_connect_dns(fd, target_host, app_ctx->ports[pos]); err = socks5_connect_dns(fdinfo->fd, target_host, app_ctx->ports[pos]);
if (err < 0) goto on_socks5_err; if (err < 0) goto on_socks5_err;
app_ctx->client_sock[pos].state = SOCKS5_STATE_ACK; 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]); printf("Socket %d/%d %s:%d is connecting...\n", pos+1, CLIENT_PORT_SIZE, target_host, app_ctx->ports[pos]);
break; break;
case SOCKS5_STATE_ACK: case SOCKS5_STATE_ACK:
//@FIXME: We suppose that we will be able to do the whole read at once which is wrong too //@FIXME: We suppose that we will be able to do the whole read at once which is wrong too
err = socks5_reply (fd); err = socks5_reply (fdinfo->fd);
if (err < 0) goto on_socks5_err; if (err < 0) goto on_socks5_err;
app_ctx->client_sock[pos].state = SOCKS5_STATE_RDY; app_ctx->client_sock[pos].state = SOCKS5_STATE_RDY;
int sock1, sock2; int sock1, sock2;
sock1 = dup(fd); sock1 = dup(fdinfo->fd);
sock2 = dup(fd); sock2 = dup(fdinfo->fd);
if (sock1 < 0 || sock2 < 0) goto on_socks5_err; if (sock1 < 0 || sock2 < 0) goto on_socks5_err;
void* fdcat = evt_core_rm_fd (ctx, fd); void* fdcat = evt_core_rm_fd (ctx, fdinfo->fd);
if (fdcat == NULL) goto on_socks5_err; if (fdcat == NULL) goto on_socks5_err;
struct evt_core_fdinfo fdinfo = {0}; struct evt_core_fdinfo fdinfo = {0};
@ -106,7 +106,7 @@ void configure_tcp_clients(struct evt_core_ctx* ctx, struct evt_core_cat* cat, i
on_socks5_err: on_socks5_err:
perror("An error occured while connecting to an Onion Service"); perror("An error occured while connecting to an Onion Service");
app_ctx->client_sock[pos].state = SOCKS5_STATE_ERR; app_ctx->client_sock[pos].state = SOCKS5_STATE_ERR;
evt_core_rm_fd (ctx, fd); evt_core_rm_fd (ctx, fdinfo->fd);
init_tcp_client (app_ctx, pos); init_tcp_client (app_ctx, pos);
} }
@ -118,7 +118,7 @@ void init_udp_socket(char* port, struct donar_client_ctx* ctx) {
fdinfo.cat = &cat; fdinfo.cat = &cat;
fdinfo.url = url; fdinfo.url = url;
sock1 = create_udp_client ("127.0.0.1", port); sock1 = create_udp_server (port);
if (sock1 < 0) goto socket_failed; if (sock1 < 0) goto socket_failed;
sock2 = dup(sock1); sock2 = dup(sock1);
if (sock2 < 0) goto socket_failed; if (sock2 < 0) goto socket_failed;

View file

@ -48,14 +48,22 @@ enum FD_STATE write_packet_to_udp(int fd, struct buffer_packet* bp) {
ssize_t nwrite; ssize_t nwrite;
size_t bytes_to_send; size_t bytes_to_send;
size_t pkt_header_size = sizeof(bp->ip.ap.str) - sizeof(char); size_t pkt_header_size = sizeof(bp->ip.ap.str) - sizeof(char);
struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_port = htons(bp->ip.ap.str.port),
};
inet_aton("127.0.0.1", &addr.sin_addr);
socklen_t addr_len = sizeof(addr);
if (bp->mode != BP_WRITING) return FDS_ERR; if (bp->mode != BP_WRITING) return FDS_ERR;
bytes_to_send = bp->ip.ap.str.size - pkt_header_size; bytes_to_send = bp->ip.ap.str.size - pkt_header_size;
nwrite = send(fd, nwrite = sendto(fd,
&(bp->ip.ap.str.payload), &(bp->ip.ap.str.payload),
bytes_to_send, bytes_to_send,
0); 0,
(struct sockaddr*)&addr,
addr_len);
if (nwrite == -1 && errno == EAGAIN) return FDS_AGAIN; if (nwrite == -1 && errno == EAGAIN) return FDS_AGAIN;
if (nwrite != bytes_to_send) return FDS_ERR; if (nwrite != bytes_to_send) return FDS_ERR;
@ -70,15 +78,23 @@ enum FD_STATE read_packet_from_udp (int fd, struct buffer_packet* bp) {
ssize_t nread; ssize_t nread;
if (bp->mode != BP_READING) return FDS_ERR; if (bp->mode != BP_READING) return FDS_ERR;
struct sockaddr_in addr = {0};
socklen_t addr_len = sizeof(addr);
size_t pkt_header_size = sizeof(bp->ip.ap.str) - sizeof(char); // We remove the payload size_t pkt_header_size = sizeof(bp->ip.ap.str) - sizeof(char); // We remove the payload
size_t udp_packet_size = sizeof(struct internet_packet) - pkt_header_size; size_t udp_packet_size = sizeof(struct internet_packet) - pkt_header_size;
nread = recv(fd, &(bp->ip.ap.str.payload), udp_packet_size, MSG_TRUNC); nread = recvfrom(fd,
&(bp->ip.ap.str.payload),
udp_packet_size,
MSG_TRUNC,
(struct sockaddr*)&addr,
&addr_len);
if ((int)nread > (int)udp_packet_size) return FDS_ERR; if ((int)nread > (int)udp_packet_size) return FDS_ERR;
if (nread == -1 && errno == EAGAIN) return FDS_AGAIN; if (nread == -1 && errno == EAGAIN) return FDS_AGAIN;
if (nread == -1) return FDS_ERR; if (nread == -1) return FDS_ERR;
bp->ip.ap.str.port = ntohs(addr.sin_port);
bp->ip.ap.str.size = nread + pkt_header_size; bp->ip.ap.str.size = nread + pkt_header_size;
bp->mode = BP_WRITING; bp->mode = BP_WRITING;

View file

@ -7,6 +7,7 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <errno.h> #include <errno.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h>
/* /*
* man 7 udp about receive operation on UDP sockets: * man 7 udp about receive operation on UDP sockets: