From 9d4947ffa5bb176628528887f46bcd0b405a9edd Mon Sep 17 00:00:00 2001 From: irungentoo Date: Sat, 17 May 2014 21:30:52 -0400 Subject: add_tcp_relay_peer() can be used to add relays that we know that peer is connected to. Some cleanups/fixes. --- toxcore/Messenger.c | 20 +++++------ toxcore/TCP_client.c | 3 ++ toxcore/net_crypto.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++---- toxcore/net_crypto.h | 20 +++++++++-- toxcore/onion_client.c | 1 + 5 files changed, 115 insertions(+), 20 deletions(-) diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index b0d5a2e5..472c2ae4 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -2203,17 +2203,15 @@ void do_friends(Messenger *m) } if (m->friendlist[i].crypt_connection_id != -1) { - uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES]; - uint64_t timestamp = onion_getfriend_DHT_pubkey(m->onion_c, m->friendlist[i].onion_friendnum, dht_public_key); - - if (timestamp != 0) { - set_connection_dht_public_key(m->net_crypto, m->friendlist[i].crypt_connection_id, dht_public_key, timestamp); - } - - timestamp = get_connection_dht_key(m->net_crypto, m->friendlist[i].crypt_connection_id, dht_public_key); - - if (timestamp != 0) { - onion_set_friend_DHT_pubkey(m->onion_c, m->friendlist[i].onion_friendnum, dht_public_key, timestamp); + uint8_t dht_public_key1[crypto_box_PUBLICKEYBYTES]; + uint64_t timestamp1 = onion_getfriend_DHT_pubkey(m->onion_c, m->friendlist[i].onion_friendnum, dht_public_key1); + uint8_t dht_public_key2[crypto_box_PUBLICKEYBYTES]; + uint64_t timestamp2 = get_connection_dht_key(m->net_crypto, m->friendlist[i].crypt_connection_id, dht_public_key2); + + if (timestamp1 > timestamp2) { + set_connection_dht_public_key(m->net_crypto, m->friendlist[i].crypt_connection_id, dht_public_key1, timestamp1); + } else if (timestamp1 < timestamp2) { + onion_set_friend_DHT_pubkey(m->onion_c, m->friendlist[i].onion_friendnum, dht_public_key2, timestamp2); } uint8_t direct_connected; diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c index 9091900f..5abb7232 100644 --- a/toxcore/TCP_client.c +++ b/toxcore/TCP_client.c @@ -604,6 +604,9 @@ void do_TCP_connection(TCP_Client_Connection *TCP_connection) */ void kill_TCP_connection(TCP_Client_Connection *TCP_connection) { + if (TCP_connection == NULL) + return; + kill_sock(TCP_connection->sock); memset(TCP_connection, 0, sizeof(TCP_Client_Connection)); free(TCP_connection); diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 1e3456c3..b47460bc 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -424,12 +424,18 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t i; for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { - if (conn->status_tcp[i] == 2) {/* friend is connected to this relay. */ + if (conn->status_tcp[i] == STATUS_TCP_ONLINE) {/* friend is connected to this relay. */ if (send_data(c->tcp_connections[i], conn->con_number_tcp[i], data, length) == 1) return 0; } } + for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { + if (conn->status_tcp[i] == STATUS_TCP_INVISIBLE) { + if (send_oob_packet(c->tcp_connections[i], conn->dht_public_key, data, length) == 1) + return 0; + } + } return -1; } @@ -1461,9 +1467,9 @@ static int disconnect_peer_tcp(Net_Crypto *c, int crypt_connection_id) uint32_t i; for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { - if (conn->status_tcp[i]) { + if (conn->status_tcp[i] != STATUS_TCP_NULL) { send_disconnect_request(c->tcp_connections[i], conn->con_number_tcp[i]); - conn->status_tcp[i] = 0; + conn->status_tcp[i] = STATUS_TCP_NULL; conn->con_number_tcp[i] = 0; } } @@ -1575,9 +1581,10 @@ int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port) if (!ipport_equal(&ip_port, &conn->ip_port)) { conn->ip_port = ip_port; conn->direct_lastrecv_time = 0; + return 0; } - return 0; + return -1; } static int tcp_response_callback(void *object, uint8_t connection_id, uint8_t *public_key) @@ -1605,8 +1612,17 @@ static int tcp_response_callback(void *object, uint8_t connection_id, uint8_t *p if (c->tcp_connections[location] != TCP_con) return -1; - conn->status_tcp[location] = 1; conn->con_number_tcp[location] = connection_id; + uint32_t i; + + for (i = 0; i < conn->num_tcp_relays; ++i) { + if (memcmp(TCP_con->public_key, conn->tcp_relays[i].client_id, crypto_box_PUBLICKEYBYTES) == 0) { + conn->status_tcp[location] = STATUS_TCP_INVISIBLE; + return 0; + } + } + + conn->status_tcp[location] = STATUS_TCP_OFFLINE; return 0; } @@ -1628,13 +1644,19 @@ static int tcp_status_callback(void *object, uint32_t number, uint8_t connection if (c->tcp_connections[location] != TCP_con) return -1; - conn->status_tcp[location] = status; + if (status == 1) { + conn->status_tcp[location] = STATUS_TCP_OFFLINE; + } else if (status == 2) { + conn->status_tcp[location] = STATUS_TCP_ONLINE; + } + conn->con_number_tcp[location] = connection_id; return 0; } static int tcp_data_callback(void *object, uint32_t number, uint8_t connection_id, uint8_t *data, uint16_t length) { + if (length == 0) return -1; @@ -1729,6 +1751,56 @@ static int tcp_connection_check(Net_Crypto *c, uint8_t *public_key) return 0; } +/* Add a tcp relay, associating it to a crypt_connection_id. + * + * return 0 if it was added. + * return -1 if it wasn't. + */ +int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port, uint8_t *public_key) +{ + Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); + + if (conn == 0) + return -1; + + if (ip_port.ip.family == TCP_INET) { + ip_port.ip.family = AF_INET; + } else if (ip_port.ip.family == TCP_INET6) { + ip_port.ip.family = AF_INET6; + } + + uint32_t i; + + for (i = 0; i < conn->num_tcp_relays; ++i) { + if (memcmp(conn->tcp_relays[i].client_id, public_key, crypto_box_PUBLICKEYBYTES) == 0) { + conn->tcp_relays[i].ip_port = ip_port; + return 0; + } + } + + if (conn->num_tcp_relays == MAX_TCP_RELAYS_PEER) { + uint16_t index = rand() % MAX_TCP_RELAYS_PEER; + conn->tcp_relays[index].ip_port = ip_port; + memcpy(conn->tcp_relays[index].client_id, public_key, crypto_box_PUBLICKEYBYTES); + } else { + conn->tcp_relays[conn->num_tcp_relays].ip_port = ip_port; + memcpy(conn->tcp_relays[conn->num_tcp_relays].client_id, public_key, crypto_box_PUBLICKEYBYTES); + ++conn->num_tcp_relays; + } + + for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { + if (c->tcp_connections[i] == NULL) + continue; + + if (memcmp(c->tcp_connections[i]->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) { + if (conn->status_tcp[i] == STATUS_TCP_OFFLINE) + conn->status_tcp[i] = STATUS_TCP_INVISIBLE; + } + } + + return add_tcp_relay(c, ip_port, public_key); +} + /* Add a tcp relay to the array. * * return 0 if it was added. @@ -1834,7 +1906,7 @@ static void clear_disconnected_tcp_peer(Crypto_Connection *conn, uint32_t number if (number >= MAX_TCP_CONNECTIONS) return; - conn->status_tcp[number] = 0; + conn->status_tcp[number] = STATUS_TCP_NULL; conn->con_number_tcp[number] = 0; } @@ -2255,6 +2327,11 @@ void kill_net_crypto(Net_Crypto *c) crypto_kill(c, i); } + for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { + kill_TCP_connection(c->tcp_connections_new[i]); + kill_TCP_connection(c->tcp_connections[i]); + } + networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_REQUEST, NULL, NULL); networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_RESPONSE, NULL, NULL); networking_registerhandler(c->dht->net, NET_PACKET_CRYPTO_HS, NULL, NULL); diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index e41e7e1d..14b14229 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -61,7 +61,13 @@ #define CRYPTO_RESERVED_PACKETS 16 -#define MAX_TCP_CONNECTIONS 8 +#define MAX_TCP_CONNECTIONS 32 +#define MAX_TCP_RELAYS_PEER 4 + +#define STATUS_TCP_NULL 0 +#define STATUS_TCP_OFFLINE 1 +#define STATUS_TCP_INVISIBLE 2 /* we know the other peer is connected to this relay but he isn't appearing online */ +#define STATUS_TCP_ONLINE 3 typedef struct { uint64_t time; @@ -127,8 +133,11 @@ typedef struct { uint8_t killed; /* set to 1 to kill the connection. */ - uint8_t status_tcp[MAX_TCP_CONNECTIONS]; + uint8_t status_tcp[MAX_TCP_CONNECTIONS]; /* set to one of STATUS_TCP_* */ uint8_t con_number_tcp[MAX_TCP_CONNECTIONS]; + + Node_format tcp_relays[MAX_TCP_RELAYS_PEER]; + uint16_t num_tcp_relays; } Crypto_Connection; typedef struct { @@ -244,6 +253,13 @@ uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id) */ int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length); +/* Add a tcp relay, associating it to a crypt_connection_id. + * + * return 0 if it was added. + * return -1 if it wasn't. + */ +int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port, uint8_t *public_key); + /* Add a tcp relay to the array. * * return 0 if it was added. diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c index be4d12aa..7fab76a7 100644 --- a/toxcore/onion_client.c +++ b/toxcore/onion_client.c @@ -830,6 +830,7 @@ int onion_set_friend_DHT_pubkey(Onion_Client *onion_c, int friend_num, uint8_t * return -1; } + onion_c->friends_list[friend_num].last_seen = unix_time(); onion_c->friends_list[friend_num].is_fake_clientid = 1; onion_c->friends_list[friend_num].fake_client_id_timestamp = timestamp; memcpy(onion_c->friends_list[friend_num].fake_client_id, dht_key, crypto_box_PUBLICKEYBYTES); -- cgit v1.2.3