Skip to content

Commit

Permalink
TCP server now has onion functionality.
Browse files Browse the repository at this point in the history
All the IP/Port related structs now have __attribute__ ((__packed__))
  • Loading branch information
irungentoo committed Mar 30, 2014
1 parent 8aaa5fe commit 98cba88
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 19 deletions.
4 changes: 2 additions & 2 deletions auto_tests/TCP_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ START_TEST(test_basic)
uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
crypto_box_keypair(self_public_key, self_secret_key);
TCP_Server *tcp_s = new_TCP_server(1, NUM_PORTS, ports, self_public_key, self_secret_key);
TCP_Server *tcp_s = new_TCP_server(1, NUM_PORTS, ports, self_public_key, self_secret_key, NULL);
ck_assert_msg(tcp_s != NULL, "Failed to create TCP relay server");

sock_t sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
Expand Down Expand Up @@ -202,7 +202,7 @@ START_TEST(test_some)
uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
crypto_box_keypair(self_public_key, self_secret_key);
TCP_Server *tcp_s = new_TCP_server(1, NUM_PORTS, ports, self_public_key, self_secret_key);
TCP_Server *tcp_s = new_TCP_server(1, NUM_PORTS, ports, self_public_key, self_secret_key, NULL);
ck_assert_msg(tcp_s != NULL, "Failed to create TCP relay server");

struct sec_TCP_con *con1 = new_TCP_con(tcp_s);
Expand Down
52 changes: 46 additions & 6 deletions toxcore/TCP_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ static int add_accepted(TCP_Server *TCP_server, TCP_Secure_Connection *con)
memcpy(&TCP_server->accepted_connection_array[index], con, sizeof(TCP_Secure_Connection));
TCP_server->accepted_connection_array[index].status = TCP_STATUS_CONFIRMED;
++TCP_server->num_accepted_connections;
TCP_server->accepted_connection_array[index].identifier = ++TCP_server->counter;
return index;
}

Expand Down Expand Up @@ -580,6 +581,29 @@ static int disconnect_conection_index(TCP_Server *TCP_server, TCP_Secure_Connect
}
}

static int handle_onion_recv_1(void *object, IP_Port dest, uint8_t *data, uint16_t length)
{
TCP_Server *TCP_server = object;
uint32_t index = dest.ip.ip6.uint32[0];

if (index >= TCP_server->size_accepted_connections)
return 1;

TCP_Secure_Connection *con = &TCP_server->accepted_connection_array[index];

if (con->identifier != dest.ip.ip6.uint64[1])
return 1;

uint8_t packet[1 + length];
memcpy(packet + 1, data, length);
packet[0] = TCP_PACKET_ONION_RESPONSE;

if (write_packet_TCP_secure_connection(con, packet, sizeof(packet)) != 1)
return 1;

return 0;
}

/* return 0 on success
* return -1 on failure
*/
Expand Down Expand Up @@ -627,16 +651,23 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, uint8_t *d
}

case TCP_PACKET_ONION_REQUEST: {
//if (length <= 1 + crypto_box_NONCEBYTES + ONION_SEND_BASE*2)
// return -1;
if (TCP_server->onion) {
if (length <= 1 + crypto_box_NONCEBYTES + ONION_SEND_BASE * 2)
return -1;

IP_Port source;
source.ip.family = TCP_ONION_FAMILY;
source.ip.ip6.uint32[0] = con_id;
source.ip.ip6.uint64[1] = con->identifier;
onion_send_1(TCP_server->onion, data + 1 + crypto_box_NONCEBYTES, length - (1 + crypto_box_NONCEBYTES), source,
data + 1);
}

//TODO onion_send_1(Onion *onion, data + 1 + crypto_box_NONCEBYTES, length - (1 + crypto_box_NONCEBYTES), IP_Port source, data + 1);
return 0;
}

case TCP_PACKET_ONION_RESPONSE: {

break;
return -1;
}

default: {
Expand Down Expand Up @@ -741,7 +772,7 @@ static sock_t new_listening_TCP_socket(int family, uint16_t port)
}

TCP_Server *new_TCP_server(uint8_t ipv6_enabled, uint16_t num_sockets, uint16_t *ports, uint8_t *public_key,
uint8_t *secret_key)
uint8_t *secret_key, Onion *onion)
{
if (num_sockets == 0 || ports == NULL)
return NULL;
Expand All @@ -751,6 +782,11 @@ TCP_Server *new_TCP_server(uint8_t ipv6_enabled, uint16_t num_sockets, uint16_t
if (temp == NULL)
return NULL;

if (onion) {
temp->onion = onion;
set_callback_handle_recv_1(onion, &handle_onion_recv_1, temp);
}

temp->socks_listening = calloc(num_sockets, sizeof(sock_t));

if (temp->socks_listening == NULL) {
Expand Down Expand Up @@ -898,6 +934,10 @@ void kill_TCP_server(TCP_Server *TCP_server)
kill_sock(TCP_server->socks_listening[i]);
}

if (TCP_server->onion) {
set_callback_handle_recv_1(TCP_server->onion, NULL, NULL);
}

free(TCP_server->socks_listening);
free(TCP_server);
}
10 changes: 9 additions & 1 deletion toxcore/TCP_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*/

#include "net_crypto.h"
#include "onion.h"

#define MAX_INCOMMING_CONNECTIONS 32

Expand All @@ -46,6 +47,8 @@

#define ARRAY_ENTRY_SIZE 6

#define TCP_ONION_FAMILY (AF_INET6 + 1)

enum {
TCP_STATUS_NO_STATUS,
TCP_STATUS_CONNECTED,
Expand All @@ -70,10 +73,13 @@ typedef struct TCP_Secure_Connection {
uint8_t last_packet[2 + MAX_PACKET_SIZE];
uint16_t last_packet_length;
uint16_t last_packet_sent;

uint64_t identifier;
} TCP_Secure_Connection;


typedef struct {
Onion *onion;
sock_t *socks_listening;
unsigned int num_listening_socks;

Expand All @@ -87,12 +93,14 @@ typedef struct {
TCP_Secure_Connection *accepted_connection_array;
uint32_t size_accepted_connections;
uint32_t num_accepted_connections;

uint64_t counter;
} TCP_Server;

/* Create new TCP server instance.
*/
TCP_Server *new_TCP_server(uint8_t ipv6_enabled, uint16_t num_sockets, uint16_t *ports, uint8_t *public_key,
uint8_t *secret_key);
uint8_t *secret_key, Onion *onion);

/* Run the TCP_server
*/
Expand Down
31 changes: 22 additions & 9 deletions toxcore/network.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,43 +161,56 @@ typedef int sock_t;
#define TOX_PORTRANGE_TO 33545
#define TOX_PORT_DEFAULT TOX_PORTRANGE_FROM

typedef union {

/* TODO: remove padding bytes next time we need to break compatibility with old versions of core. */

typedef union __attribute__ ((__packed__))
{
uint8_t uint8[4];
uint16_t uint16[2];
uint32_t uint32;
struct in_addr in_addr;
} IP4;
}
IP4;

typedef union {
typedef union __attribute__ ((__packed__))
{
uint8_t uint8[16];
uint16_t uint16[8];
uint32_t uint32[4];
uint64_t uint64[2];
struct in6_addr in6_addr;
} IP6;
}
IP6;

typedef struct {
typedef struct __attribute__ ((__packed__))
{
uint8_t family;
/* Not used for anything right now. */
uint8_t padding[3];
union {
IP4 ip4;
IP6 ip6;
};
} IP;
}
IP;

typedef union {
typedef union __attribute__ ((__packed__))
{
struct {
IP4 ip;
uint16_t port;
/* Not used for anything right now. */
uint16_t padding;
};
uint8_t uint8[8];
} IP4_Port;
}
IP4_Port;

typedef struct IP_Port {
typedef struct __attribute__ ((__packed__)) IP_Port {
IP ip;
uint16_t port;
uint16_t padding;
} IP_Port;

#define TOX_ENABLE_IPV6_DEFAULT 1
Expand Down
9 changes: 8 additions & 1 deletion toxcore/onion.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,13 +398,20 @@ static int handle_recv_1(void *object, IP_Port source, uint8_t *packet, uint32_t

uint32_t data_len = length - (1 + RETURN_1);

if (onion->recv_1_function && send_to.ip.family != AF_INET && send_to.ip.family != AF_INET6)
return onion->recv_1_function(onion->callback_object, send_to, packet + (1 + RETURN_1), data_len);

if ((uint32_t)sendpacket(onion->net, send_to, packet + (1 + RETURN_1), data_len) != data_len)
return 1;

return 0;
}


void set_callback_handle_recv_1(Onion *onion, int (*function)(void *, IP_Port, uint8_t *, uint16_t), void *object)
{
onion->recv_1_function = function;
onion->callback_object = object;
}

Onion *new_onion(DHT *dht)
{
Expand Down
12 changes: 12 additions & 0 deletions toxcore/onion.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ typedef struct {
Shared_Keys shared_keys_1;
Shared_Keys shared_keys_2;
Shared_Keys shared_keys_3;

int (*recv_1_function)(void *, IP_Port, uint8_t *, uint16_t);
void *callback_object;
} Onion;

#define ONION_RETURN_1 (crypto_secretbox_NONCEBYTES + sizeof(IP_Port) + crypto_secretbox_MACBYTES)
Expand Down Expand Up @@ -92,9 +95,18 @@ int send_onion_response(Networking_Core *net, IP_Port dest, uint8_t *data, uint3
* return 1 on failure.
*
* Used to handle these packets that are received in a non traditional way (by TCP for example).
*
* Source family must be set to something else than AF_INET6 or AF_INET so that the callback gets called
* when the response is received.
*/
int onion_send_1(Onion *onion, uint8_t *plain, uint32_t len, IP_Port source, uint8_t *nonce);

/* Set the callback to be called when the dest ip_port doesn't have AF_INET6 or AF_INET as the family.
*
* Format: function(void *object, IP_Port dest, uint8_t *data, uint32_t length)
*/
void set_callback_handle_recv_1(Onion *onion, int (*function)(void *, IP_Port, uint8_t *, uint16_t), void *object);

Onion *new_onion(DHT *dht);

void kill_onion(Onion *onion);
Expand Down

0 comments on commit 98cba88

Please sign in to comment.