Skip to content

Commit

Permalink
Introduce local forward ID
Browse files Browse the repository at this point in the history
  • Loading branch information
gjedeer committed Mar 14, 2023
1 parent 0250be7 commit 71f125f
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 22 deletions.
34 changes: 31 additions & 3 deletions client.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,21 +123,46 @@ int local_bind() {
int handle_acktunnel_frame(protocol_frame *rcvd_frame)
{
tunnel *tun;
uint32_t local_forward_id;
local_port_forward *forward;

if(!client_mode)
{
log_printf(L_WARNING, "Got ACK tunnel frame when not in client mode!?\n");
return -1;
}

tun = tunnel_create(
client_tunnel.sockfd,
if(rcvd_frame->data_length < 3)
{
log_printf(L_WARNING, "Got ACK tunnel frame with not enough data");
return -1;
}

if(rcvd_frame->data_length > PROTOCOL_MAX_PACKET_SIZE) {
log_printf(L_WARNING, "Got ACK tunnel with wrong data length");
return -1;
}

local_forward_id = INT32_AT((rcvd_frame->data), 0);

forward = find_pending_forward_by_id(local_forward_id);
if(!forward)
{
log_printf(L_WARNING, "Got ACK tunnel with wrong forward ID %ld", local_forward_id);
return -1;
}
LL_DELETE(pending_port_forwards, forward);
/* TODO bind here? */
LL_APPEND(local_port_forwards, forward);

client_tunnel = tunnel_create(
0, /* sockfd */
rcvd_frame->connid,
rcvd_frame->friendnumber
);

/* Mark that we can accept() another connection */
client_tunnel.sockfd = -1;
client_tunnel->sockfd = -1;

// printf("New tunnel ID: %d\n", tun->connid);

Expand Down Expand Up @@ -481,6 +506,7 @@ int do_client_loop(uint8_t *tox_id_str)
send_tunnel_request_packet(
port_forward->remote_host,
port_forward->remote_port,
port_forward->forward_id,
friendnumber
);
}
Expand All @@ -492,13 +518,15 @@ int do_client_loop(uint8_t *tox_id_str)
send_tunnel_request_packet(
port_forward->remote_host,
port_forward->remote_port,
port_forward->forward_id,
friendnumber
);
}
state = CLIENT_STATE_WAIT_FOR_ACKTUNNEL;
break;
case CLIENT_STATE_WAIT_FOR_ACKTUNNEL:
client_tunnel.sockfd = 0;
/* TODO REMOTE_L */
send_tunnel_request_packet(
remote_host,
remote_port,
Expand Down
2 changes: 1 addition & 1 deletion gitversion.h
Original file line number Diff line number Diff line change
@@ -1 +1 @@
#define GITVERSION "2e9e79947ecb9b62add1ff957d6b71a448d1d87b"
#define GITVERSION "0250be7b29cceeaa0dd7b86ebcbf8f86b062b239"
67 changes: 50 additions & 17 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ rule *rules = NULL;

/* Ports and hostname for port forwarding */
local_port_forward *local_port_forwards = NULL;
/* Non-acknowledged local port forwards */
local_port_forward *pending_port_forwards = NULL;
uint32_t last_forward_id;

/* Whether to daemonize/fork after startup */
int daemonize = 0;
Expand Down Expand Up @@ -174,6 +177,7 @@ int tunnel_in_delete_queue(tunnel *t)
return 0;
}

/* Delete the tunnel at the end of main loop */
void tunnel_queue_delete(tunnel *t)
{
tunnel_list *tunnel_list_entry = NULL;
Expand All @@ -191,6 +195,18 @@ void tunnel_queue_delete(tunnel *t)
LL_APPEND(tunnels_to_delete, tunnel_list_entry);
}

local_port_forward *local_port_forward_create()
{
local_port_forward *forward = calloc(sizeof(local_port_forward), 1);
if(!forward)
{
return NULL;
}

forward->forward_id = ++last_forward_id;
forward->created = time();
}

/* bootstrap to dht with bootstrap_nodes */
/* From uTox/tox.c */
static void do_bootstrap(Tox *tox)
Expand Down Expand Up @@ -238,6 +254,7 @@ void *get_in_addr(struct sockaddr *sa)
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

/* Connect to an endpoint, return sockfd */
int get_client_socket(char *hostname, int port)
{
int sockfd;
Expand Down Expand Up @@ -383,7 +400,7 @@ int send_frame(protocol_frame *frame, uint8_t *data)
return rv;
}

int send_tunnel_ack_frame(tunnel *tun, char *remote_hostname, int remote_port)
int send_tunnel_ack_frame(tunnel *tun, uint32_t remote_forward_id)
{
protocol_frame frame_st;
protocol_frame *frame;
Expand All @@ -394,13 +411,14 @@ int send_tunnel_ack_frame(tunnel *tun, char *remote_hostname, int remote_port)

frame->packet_type = PACKET_TYPE_ACKTUNNEL;
frame->connid = tun->connid;
frame->data_length = strlen(remote_hostname) + 3;
frame->data_length = 4;
frame->friendnumber = tun->friendnumber;

data = calloc(PROTOCOL_BUFFER_OFFSET + frame->data_length, 1);
data[PROTOCOL_BUFFER_OFFSET + 0] = BYTE1(remote_port);
data[PROTOCOL_BUFFER_OFFSET + 1] = BYTE2(remote_port);
strncpy(data + PROTOCOL_BUFFER_OFFSET + 2, remote_hostname, frame->data_length-2);
data[PROTOCOL_BUFFER_OFFSET+3] = BYTE1(remote_forward_id);
data[PROTOCOL_BUFFER_OFFSET+2] = BYTE2(remote_forward_id);
data[PROTOCOL_BUFFER_OFFSET+1] = BYTE3(remote_forward_id);
data[PROTOCOL_BUFFER_OFFSET] = BYTE4(remote_forward_id);

return send_frame(frame, data);
}
Expand Down Expand Up @@ -430,6 +448,8 @@ int handle_request_tunnel_frame(protocol_frame *rcvd_frame)
int port = -1;
int sockfd = 0;
uint16_t tunnel_id;
/* Client-side ID of the tunnel */
uint32_t remote_forward_id;

if(client_mode)
{
Expand All @@ -445,7 +465,9 @@ int handle_request_tunnel_frame(protocol_frame *rcvd_frame)
return -1;
}

strncpy(hostname, (char *)rcvd_frame->data, rcvd_frame->data_length);
remote_forward_id = UINT32_AT(rcvd_frame->data, 0);

strncpy(hostname, ((char *)rcvd_frame->data) + 4, rcvd_frame->data_length - 4);
hostname[rcvd_frame->data_length] = '\0';

log_printf(L_INFO, "Got a request to forward data from %s:%d\n", hostname, port);
Expand Down Expand Up @@ -490,7 +512,7 @@ int handle_request_tunnel_frame(protocol_frame *rcvd_frame)
FD_SET(sockfd, &master_server_fds);
update_select_nfds(sockfd);
log_printf(L_DEBUG, "Created tunnel, yay!\n");
send_tunnel_ack_frame(tun, hostname, port);
send_tunnel_ack_frame(tun, remote_forward_id);
}
else
{
Expand Down Expand Up @@ -687,14 +709,18 @@ void parse_lossless_packet(Tox *tox, uint32_t friendnumber, const uint8_t *data,
free(frame);
}

int send_tunnel_request_packet(char *remote_host, int remote_port, int friend_number)
int send_tunnel_request_packet(char *remote_host, int remote_port, uint32_t local_forward_id, int friend_number)
{
int packet_length = 0;
protocol_frame frame_i, *frame;
uint8_t *data = NULL;

log_printf(L_INFO, "Sending packet to friend #%d to forward %s:%d\n", friend_number, remote_host, remote_port);
packet_length = PROTOCOL_BUFFER_OFFSET + strlen(remote_host);
packet_length = PROTOCOL_BUFFER_OFFSET + strlen(remote_host) + 4;
if(packet_length > TOX_MAX_CUSTOM_PACKET_SIZE)
{
log_printf(L_WARNING, "Not requesting port forward - host name %s is too long", remote_host);
}
frame = &frame_i;

data = calloc(1, packet_length);
Expand All @@ -703,12 +729,17 @@ int send_tunnel_request_packet(char *remote_host, int remote_port, int friend_nu
log_printf(L_ERROR, "Could not allocate memory for tunnel request packet\n");
exit(1);
}
memcpy((char *)data+PROTOCOL_BUFFER_OFFSET, remote_host, strlen(remote_host));
data[PROTOCOL_BUFFER_OFFSET+3] = BYTE1(local_forward_id);
data[PROTOCOL_BUFFER_OFFSET+2] = BYTE2(local_forward_id);
data[PROTOCOL_BUFFER_OFFSET+1] = BYTE3(local_forward_id);
data[PROTOCOL_BUFFER_OFFSET] = BYTE4(local_forward_id);

memcpy((char *)data+PROTOCOL_BUFFER_OFFSET+4, remote_host, strlen(remote_host));

frame->friendnumber = friend_number;
frame->packet_type = PACKET_TYPE_REQUESTTUNNEL;
frame->connid = remote_port;
frame->data_length = strlen(remote_host);
frame->data_length = strlen(remote_host) + 4;

send_frame(frame, data);

Expand Down Expand Up @@ -1266,10 +1297,12 @@ int main(int argc, char *argv[])
uint8_t *save_data = NULL;
allowed_toxid *allowed_toxid_obj = NULL;

srand(time(NULL));
tcp_relay_port = 1024 + (rand() % 64511);
udp_start_port = 1024 + (rand() % 64500);
udp_end_port = udp_start_port + 10;
srand(time(NULL));
tcp_relay_port = 1024 + (rand() % 64511);
udp_start_port = 1024 + (rand() % 64500);
udp_end_port = udp_start_port + 10;

last_forward_id = rand();

log_init();

Expand All @@ -1278,7 +1311,7 @@ int main(int argc, char *argv[])
switch(oc)
{
case 'L':
local_port_forward *port_forward = calloc(sizeof(local_port_forward), 1);
local_port_forward *port_forward = local_port_forward_create();

if(!port_forward) {
log_printf(L_ERROR, "Could not allocate memory for port forward\n");
Expand All @@ -1296,7 +1329,7 @@ int main(int argc, char *argv[])
exit(1);
}

LL_APPEND(local_port_forwards, port_forward);
LL_APPEND(pending_port_forwards, port_forward);

if(min_log_level == L_UNSET)
{
Expand Down
14 changes: 13 additions & 1 deletion main.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,11 @@
#define PACKET_TYPE_TCP_FIN 0x0601

#define INT16_AT(array,pos) ( (*((array)+(pos)))*256 + (*((array)+(pos)+1)) )
#define BYTE2(number) (((number) / 256) & 0xff)
#define INT32_AT(array,pos) ( (*((array)+(pos)))*256*256*256 + (*((array)+(pos)+1))*256*256 +(*((array)+(pos)+2))*256 + (*((array)+(pos)+3)) )
#define BYTE1(number) ((number)&0xff)
#define BYTE2(number) (((number) / 256) & 0xff)
#define BYTE3(number) (((number) / (256*256)) & 0xff)
#define BYTE4(number) (((number) / (256*256*256)) & 0xff)

/* Offset of the data buffer in the packet */
#define PROTOCOL_BUFFER_OFFSET 8
Expand Down Expand Up @@ -91,6 +94,12 @@ typedef struct local_port_forward_t {
/* Client mode tunnel object for this port forward */
tunnel *tun;

/* When the forward has been created - used in ack timeouts */
time_t created;

/* ID - used to identify the ack frame */
uint32_t forward_id;

struct local_port_forward_t *next;
} local_port_forward;

Expand Down Expand Up @@ -127,6 +136,9 @@ extern char shared_secret[TOX_MAX_FRIEND_REQUEST_LENGTH];
extern int select_nfds;
extern tunnel *by_id;

extern local_port_forward *local_port_forwards;
extern local_port_forward *pending_port_forwards;

void parse_lossless_packet(Tox *tox, uint32_t friendnumber, const uint8_t *data, size_t len, void *tmp);
tunnel *tunnel_create(int sockfd, int connid, uint32_t friendnumber);
void tunnel_delete(tunnel *t);
Expand Down

0 comments on commit 71f125f

Please sign in to comment.