Skip to content

Commit

Permalink
TCP branch now ready for start of real testing.
Browse files Browse the repository at this point in the history
Friends can now exchange TCP relay addresses so that they can
connect together.

Currently all bootstrap nodes are treated as TCP relays.
  • Loading branch information
irungentoo committed May 18, 2014
1 parent 9d4947f commit e87929e
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 5 deletions.
17 changes: 17 additions & 0 deletions toxcore/Messenger.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,21 @@ void getaddress(Messenger *m, uint8_t *address)
memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(nospam), &checksum, sizeof(checksum));
}

/* callback for recv TCP relay nodes. */
static int tcp_relay_node_callback(void *object, uint32_t number, IP_Port ip_port, uint8_t *public_key)
{
Messenger *m = object;

if (friend_not_valid(m, number))
return -1;

if (m->friendlist[number].crypt_connection_id != -1) {
return add_tcp_relay_peer(m->net_crypto, m->friendlist[number].crypt_connection_id, ip_port, public_key);
} else {
return add_tcp_relay(m->net_crypto, ip_port, public_key);
}
}

/*
* Add a friend.
* Set the data that will be sent along with friend request.
Expand Down Expand Up @@ -277,6 +292,7 @@ int32_t m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t leng
m->friendlist[i].message_id = 0;
m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */
memcpy(&(m->friendlist[i].friendrequest_nospam), address + crypto_box_PUBLICKEYBYTES, sizeof(uint32_t));
recv_tcp_relay_handler(m->onion_c, onion_friendnum, &tcp_relay_node_callback, m, i);

if (m->numfriends == i)
++m->numfriends;
Expand Down Expand Up @@ -322,6 +338,7 @@ int32_t m_addfriend_norequest(Messenger *m, uint8_t *client_id)
m->friendlist[i].is_typing = 0;
m->friendlist[i].message_id = 0;
m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */
recv_tcp_relay_handler(m->onion_c, onion_friendnum, &tcp_relay_node_callback, m, i);

if (m->numfriends == i)
++m->numfriends;
Expand Down
1 change: 1 addition & 0 deletions toxcore/TCP_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@ TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, uint8_t *public_key,
temp->status = TCP_CLIENT_CONNECTING;
temp->sock = sock;
memcpy(temp->public_key, public_key, crypto_box_PUBLICKEYBYTES);
temp->ip_port = ip_port;

if (generate_handshake(temp, self_public_key, self_secret_key) == -1) {
kill_sock(sock);
Expand Down
1 change: 1 addition & 0 deletions toxcore/TCP_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ typedef struct {
uint8_t status;
sock_t sock;
uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* public key of the server */
IP_Port ip_port; /* The ip and port of the server */
uint8_t recv_nonce[crypto_box_NONCEBYTES]; /* Nonce of received packets. */
uint8_t sent_nonce[crypto_box_NONCEBYTES]; /* Nonce of sent packets. */
uint8_t shared_key[crypto_box_BEFORENMBYTES];
Expand Down
35 changes: 35 additions & 0 deletions toxcore/net_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -1823,6 +1823,41 @@ int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, uint8_t *public_key)
return -1;
}

/* Copy a maximum of num TCP relays we are connected to to tcp_relays.
* NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6.
*
* return number of relays copied to tcp_relays on success.
* return 0 on failure.
*/
unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, uint16_t num)
{
if (num == 0)
return 0;

uint32_t i;
uint16_t copied = 0;

for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
if (c->tcp_connections[i] != NULL) {
memcpy(tcp_relays[copied].client_id, c->tcp_connections[i]->public_key, crypto_box_PUBLICKEYBYTES);
tcp_relays[copied].ip_port = c->tcp_connections[i]->ip_port;

if (tcp_relays[copied].ip_port.ip.family == AF_INET) {
tcp_relays[copied].ip_port.ip.family = TCP_INET;
} else if (tcp_relays[copied].ip_port.ip.family == AF_INET6) {
tcp_relays[copied].ip_port.ip.family = TCP_INET6;
}

++copied;

if (copied == num)
return copied;
}
}

return copied;
}

/* Add a connected tcp connection to the tcp_connections array.
*
* return 0 if it was added.
Expand Down
8 changes: 8 additions & 0 deletions toxcore/net_crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,14 @@ int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port,
*/
int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, uint8_t *public_key);

/* Copy a maximum of num TCP relays we are connected to to tcp_relays.
* NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6.
*
* return number of relays copied to tcp_relays on success.
* return 0 on failure.
*/
unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, uint16_t num);

/* Kill a crypto connection.
*
* return -1 on failure.
Expand Down
39 changes: 35 additions & 4 deletions toxcore/onion_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -505,15 +505,25 @@ static int handle_fakeid_announce(void *object, uint8_t *source_pubkey, uint8_t
if (len_nodes != 0) {
Node_format nodes[MAX_SENT_NODES];
int num_nodes = unpack_nodes(nodes, MAX_SENT_NODES, 0, data + 1 + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES,
len_nodes, 0);
len_nodes, 1);

if (num_nodes <= 0)
return 1;

int i;

for (i = 0; i < num_nodes; ++i) {
DHT_getnodes(onion_c->dht, &nodes[i].ip_port, nodes[i].client_id, onion_c->friends_list[friend_num].fake_client_id);
uint8_t family = nodes[i].ip_port.ip.family;

if (family == AF_INET || family == AF_INET6) {
DHT_getnodes(onion_c->dht, &nodes[i].ip_port, nodes[i].client_id, onion_c->friends_list[friend_num].fake_client_id);
} else if (family == TCP_INET || family == TCP_INET6) {
if (onion_c->friends_list[friend_num].tcp_relay_node_callback) {
void *obj = onion_c->friends_list[friend_num].tcp_relay_node_callback_object;
uint32_t number = onion_c->friends_list[friend_num].tcp_relay_node_callback_number;
onion_c->friends_list[friend_num].tcp_relay_node_callback(obj, number, nodes[i].ip_port, nodes[i].client_id);
}
}
}
}

Expand Down Expand Up @@ -664,8 +674,9 @@ static int send_fakeid_announce(Onion_Client *onion_c, uint16_t friend_num, uint
memcpy(data + 1, &no_replay, sizeof(no_replay));
memcpy(data + 1 + sizeof(uint64_t), onion_c->dht->self_public_key, crypto_box_PUBLICKEYBYTES);
Node_format nodes[MAX_SENT_NODES];
uint16_t num_nodes = closelist_nodes(onion_c->dht, nodes, MAX_SENT_NODES);

uint16_t num_relays = copy_connected_tcp_relays(onion_c->c, nodes, (MAX_SENT_NODES / 2));
uint16_t num_nodes = closelist_nodes(onion_c->dht, &nodes[num_relays], MAX_SENT_NODES - num_relays);
num_nodes += num_relays;
int nodes_len = 0;

if (num_nodes != 0) {
Expand Down Expand Up @@ -800,6 +811,26 @@ int onion_delfriend(Onion_Client *onion_c, int friend_num)
return friend_num;
}

/* Set the function for this friend that will be callbacked with object and number
* when that friends gives us one of the TCP relays he is connected to.
*
* object and number will be passed as argument to this function.
*
* return -1 on failure.
* return 0 on success.
*/
int recv_tcp_relay_handler(Onion_Client *onion_c, int friend_num, int (*tcp_relay_node_callback)(void *object,
uint32_t number, IP_Port ip_port, uint8_t *public_key), void *object, uint32_t number)
{
if ((uint32_t)friend_num >= onion_c->num_friends)
return -1;

onion_c->friends_list[friend_num].tcp_relay_node_callback = tcp_relay_node_callback;
onion_c->friends_list[friend_num].tcp_relay_node_callback_object = object;
onion_c->friends_list[friend_num].tcp_relay_node_callback_number = number;
return 0;
}

/* Set a friends DHT public key.
* timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to
* the other peer.
Expand Down
15 changes: 15 additions & 0 deletions toxcore/onion_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ typedef struct {

Last_Pinged last_pinged[MAX_STORED_PINGED_NODES];
uint8_t last_pinged_index;

int (*tcp_relay_node_callback)(void *object, uint32_t number, IP_Port ip_port, uint8_t *public_key);
void *tcp_relay_node_callback_object;
uint32_t tcp_relay_node_callback_number;
} Onion_Friend;

typedef int (*oniondata_handler_callback)(void *object, uint8_t *source_pubkey, uint8_t *data, uint32_t len);
Expand Down Expand Up @@ -176,6 +180,17 @@ int onion_set_friend_online(Onion_Client *onion_c, int friend_num, uint8_t is_on
*/
int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port);

/* Set the function for this friend that will be callbacked with object and number
* when that friends gives us one of the TCP relays he is connected to.
*
* object and number will be passed as argument to this function.
*
* return -1 on failure.
* return 0 on success.
*/
int recv_tcp_relay_handler(Onion_Client *onion_c, int friend_num, int (*tcp_relay_node_callback)(void *object,
uint32_t number, IP_Port ip_port, uint8_t *public_key), void *object, uint32_t number);

/* Set a friends DHT public key.
* timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to
* the other peer.
Expand Down
28 changes: 27 additions & 1 deletion toxcore/tox.c
Original file line number Diff line number Diff line change
Expand Up @@ -739,12 +739,38 @@ uint64_t tox_file_data_remaining(Tox *tox, int32_t friendnumber, uint8_t filenum

/***************END OF FILE SENDING FUNCTIONS******************/

/* TODO: expose this properly. */
static int tox_add_tcp_relay(Tox *tox, const char *address, uint8_t ipv6enabled, uint16_t port, uint8_t *public_key)
{
Messenger *m = tox;
IP_Port ip_port_v64;
IP *ip_extra = NULL;
IP_Port ip_port_v4;
ip_init(&ip_port_v64.ip, ipv6enabled);

if (ipv6enabled) {
/* setup for getting BOTH: an IPv6 AND an IPv4 address */
ip_port_v64.ip.family = AF_UNSPEC;
ip_reset(&ip_port_v4.ip);
ip_extra = &ip_port_v4.ip;
}

if (addr_resolve_or_parse_ip(address, &ip_port_v64.ip, ip_extra)) {
ip_port_v64.port = port;
add_tcp_relay(m->net_crypto, ip_port_v64, public_key);
return 1;
} else {
return 0;
}
}

int tox_bootstrap_from_address(Tox *tox, const char *address,
uint8_t ipv6enabled, uint16_t port, uint8_t *public_key)
{
Messenger *m = tox;
tox_add_tcp_relay(tox, address, ipv6enabled, port, public_key);
return DHT_bootstrap_from_address(m->dht, address, ipv6enabled, port, public_key);
};
}

/* return 0 if we are not connected to the DHT.
* return 1 if we are.
Expand Down

0 comments on commit e87929e

Please sign in to comment.