TCP branch now ready for start of real testing.

Friends can now exchange TCP relay addresses so that they can
connect together.

Currently all bootstrap nodes are treated as TCP relays.
This commit is contained in:
irungentoo 2014-05-18 10:55:38 -04:00
parent 9d4947ffa5
commit e87929e869
No known key found for this signature in database
GPG Key ID: 10349DC9BED89E98
8 changed files with 139 additions and 5 deletions

View File

@ -195,6 +195,21 @@ void getaddress(Messenger *m, uint8_t *address)
memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(nospam), &checksum, sizeof(checksum)); 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. * Add a friend.
* Set the data that will be sent along with friend request. * Set the data that will be sent along with friend request.
@ -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].message_id = 0;
m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */ m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */
memcpy(&(m->friendlist[i].friendrequest_nospam), address + crypto_box_PUBLICKEYBYTES, sizeof(uint32_t)); 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) if (m->numfriends == i)
++m->numfriends; ++m->numfriends;
@ -322,6 +338,7 @@ int32_t m_addfriend_norequest(Messenger *m, uint8_t *client_id)
m->friendlist[i].is_typing = 0; m->friendlist[i].is_typing = 0;
m->friendlist[i].message_id = 0; m->friendlist[i].message_id = 0;
m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */ 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) if (m->numfriends == i)
++m->numfriends; ++m->numfriends;

View File

@ -372,6 +372,7 @@ TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, uint8_t *public_key,
temp->status = TCP_CLIENT_CONNECTING; temp->status = TCP_CLIENT_CONNECTING;
temp->sock = sock; temp->sock = sock;
memcpy(temp->public_key, public_key, crypto_box_PUBLICKEYBYTES); 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) { if (generate_handshake(temp, self_public_key, self_secret_key) == -1) {
kill_sock(sock); kill_sock(sock);

View File

@ -40,6 +40,7 @@ typedef struct {
uint8_t status; uint8_t status;
sock_t sock; sock_t sock;
uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* public key of the server */ 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 recv_nonce[crypto_box_NONCEBYTES]; /* Nonce of received packets. */
uint8_t sent_nonce[crypto_box_NONCEBYTES]; /* Nonce of sent packets. */ uint8_t sent_nonce[crypto_box_NONCEBYTES]; /* Nonce of sent packets. */
uint8_t shared_key[crypto_box_BEFORENMBYTES]; uint8_t shared_key[crypto_box_BEFORENMBYTES];

View File

@ -1823,6 +1823,41 @@ int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, uint8_t *public_key)
return -1; 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. /* Add a connected tcp connection to the tcp_connections array.
* *
* return 0 if it was added. * return 0 if it was added.

View File

@ -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); 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. /* Kill a crypto connection.
* *
* return -1 on failure. * return -1 on failure.

View File

@ -505,7 +505,7 @@ static int handle_fakeid_announce(void *object, uint8_t *source_pubkey, uint8_t
if (len_nodes != 0) { if (len_nodes != 0) {
Node_format nodes[MAX_SENT_NODES]; Node_format nodes[MAX_SENT_NODES];
int num_nodes = unpack_nodes(nodes, MAX_SENT_NODES, 0, data + 1 + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES, 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) if (num_nodes <= 0)
return 1; return 1;
@ -513,7 +513,17 @@ static int handle_fakeid_announce(void *object, uint8_t *source_pubkey, uint8_t
int i; int i;
for (i = 0; i < num_nodes; ++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);
}
}
} }
} }
@ -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, &no_replay, sizeof(no_replay));
memcpy(data + 1 + sizeof(uint64_t), onion_c->dht->self_public_key, crypto_box_PUBLICKEYBYTES); memcpy(data + 1 + sizeof(uint64_t), onion_c->dht->self_public_key, crypto_box_PUBLICKEYBYTES);
Node_format nodes[MAX_SENT_NODES]; 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; int nodes_len = 0;
if (num_nodes != 0) { if (num_nodes != 0) {
@ -800,6 +811,26 @@ int onion_delfriend(Onion_Client *onion_c, int friend_num)
return 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. /* Set a friends DHT public key.
* timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to * timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to
* the other peer. * the other peer.

View File

@ -102,6 +102,10 @@ typedef struct {
Last_Pinged last_pinged[MAX_STORED_PINGED_NODES]; Last_Pinged last_pinged[MAX_STORED_PINGED_NODES];
uint8_t last_pinged_index; 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; } Onion_Friend;
typedef int (*oniondata_handler_callback)(void *object, uint8_t *source_pubkey, uint8_t *data, uint32_t len); typedef int (*oniondata_handler_callback)(void *object, uint8_t *source_pubkey, uint8_t *data, uint32_t len);
@ -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); 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. /* Set a friends DHT public key.
* timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to * timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to
* the other peer. * the other peer.

View File

@ -739,12 +739,38 @@ uint64_t tox_file_data_remaining(Tox *tox, int32_t friendnumber, uint8_t filenum
/***************END OF FILE SENDING FUNCTIONS******************/ /***************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, int tox_bootstrap_from_address(Tox *tox, const char *address,
uint8_t ipv6enabled, uint16_t port, uint8_t *public_key) uint8_t ipv6enabled, uint16_t port, uint8_t *public_key)
{ {
Messenger *m = tox; 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 DHT_bootstrap_from_address(m->dht, address, ipv6enabled, port, public_key);
}; }
/* return 0 if we are not connected to the DHT. /* return 0 if we are not connected to the DHT.
* return 1 if we are. * return 1 if we are.