summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2015-12-11 16:48:10 -0500
committerirungentoo <irungentoo@gmail.com>2015-12-11 16:48:10 -0500
commit22b1ebb46e5470d919e1f6896c99a82c29b443d3 (patch)
tree474a3b52421e5a889dea85501f61e6f0d082dabf
parentae801b3257ccd2c13b18c013619674bee229dcae (diff)
DHT improvements.
Feed better nodes to onion, bootstrap off close clients when DHT friend is added.
-rw-r--r--toxcore/DHT.c94
-rw-r--r--toxcore/DHT.h20
-rw-r--r--toxcore/onion_client.c15
3 files changed, 74 insertions, 55 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c
index ae1ef8b1..3b7d2da5 100644
--- a/toxcore/DHT.c
+++ b/toxcore/DHT.c
@@ -1253,37 +1253,7 @@ int DHT_addfriend(DHT *dht, const uint8_t *public_key, void (*ip_callback)(void
1253 if (lock_count) 1253 if (lock_count)
1254 *lock_count = lock_num + 1; 1254 *lock_count = lock_num + 1;
1255 1255
1256#ifdef ENABLE_ASSOC_DHT 1256 friend->num_to_bootstrap = get_close_nodes(dht, friend->public_key, friend->to_bootstrap, 0, 1, 0);
1257
1258 if (dht->assoc) {
1259 /* get up to MAX_FRIEND_CLIENTS connectable nodes */
1260 DHT_Friend *friend = &dht->friends_list[dht->num_friends - 1];
1261
1262 Assoc_close_entries close_entries;
1263 memset(&close_entries, 0, sizeof(close_entries));
1264 close_entries.wanted_id = public_key;
1265 close_entries.count_good = MAX_FRIEND_CLIENTS / 2;
1266 close_entries.count = MAX_FRIEND_CLIENTS;
1267 close_entries.result = calloc(MAX_FRIEND_CLIENTS, sizeof(*close_entries.result));
1268
1269 uint8_t i, found = Assoc_get_close_entries(dht->assoc, &close_entries);
1270
1271 for (i = 0; i < found; i++)
1272 memcpy(&friend->client_list[i], close_entries.result[i], sizeof(*close_entries.result[i]));
1273
1274 if (found) {
1275 /* send getnodes to the "best" entry */
1276 Client_data *client = &friend->client_list[0];
1277
1278 if (ipport_isset(&client->assoc4.ip_port))
1279 getnodes(dht, client->assoc4.ip_port, client->public_key, friend->public_key, NULL);
1280
1281 if (ipport_isset(&client->assoc6.ip_port))
1282 getnodes(dht, client->assoc6.ip_port, client->public_key, friend->public_key, NULL);
1283 }
1284 }
1285
1286#endif
1287 1257
1288 return 0; 1258 return 0;
1289} 1259}
@@ -1464,11 +1434,20 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
1464 */ 1434 */
1465static void do_DHT_friends(DHT *dht) 1435static void do_DHT_friends(DHT *dht)
1466{ 1436{
1467 uint32_t i; 1437 unsigned int i, j;
1468 1438
1469 for (i = 0; i < dht->num_friends; ++i) 1439 for (i = 0; i < dht->num_friends; ++i) {
1470 do_ping_and_sendnode_requests(dht, &dht->friends_list[i].lastgetnode, dht->friends_list[i].public_key, 1440 DHT_Friend *friend = &dht->friends_list[i];
1471 dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, &dht->friends_list[i].bootstrap_times); 1441
1442 for (j = 0; j < friend->num_to_bootstrap; ++j) {
1443 getnodes(dht, friend->to_bootstrap[j].ip_port, friend->to_bootstrap[j].public_key, friend->public_key, NULL);
1444 }
1445
1446 friend->num_to_bootstrap = 0;
1447
1448 do_ping_and_sendnode_requests(dht, &friend->lastgetnode, friend->public_key, friend->client_list, MAX_FRIEND_CLIENTS,
1449 &friend->bootstrap_times);
1450 }
1472} 1451}
1473 1452
1474/* Ping each client in the close nodes list every PING_INTERVAL seconds. 1453/* Ping each client in the close nodes list every PING_INTERVAL seconds.
@@ -2151,17 +2130,16 @@ Node_format random_node(DHT *dht, sa_family_t sa_family)
2151 * 2130 *
2152 * return the number of nodes. 2131 * return the number of nodes.
2153 */ 2132 */
2154uint16_t closelist_nodes(DHT *dht, Node_format *nodes, uint16_t max_num) 2133uint16_t list_nodes(Client_data *list, unsigned int length, Node_format *nodes, uint16_t max_num)
2155{ 2134{
2156 if (max_num == 0) 2135 if (max_num == 0)
2157 return 0; 2136 return 0;
2158 2137
2159 uint16_t count = 0; 2138 uint16_t count = 0;
2160 Client_data *list = dht->close_clientlist;
2161 2139
2162 uint32_t i; 2140 unsigned int i;
2163 2141
2164 for (i = LCLIENT_LIST; i != 0; --i) { 2142 for (i = length; i != 0; --i) {
2165 IPPTsPng *assoc = NULL; 2143 IPPTsPng *assoc = NULL;
2166 2144
2167 if (!is_timeout(list[i - 1].assoc4.timestamp, BAD_NODE_TIMEOUT)) 2145 if (!is_timeout(list[i - 1].assoc4.timestamp, BAD_NODE_TIMEOUT))
@@ -2187,6 +2165,38 @@ uint16_t closelist_nodes(DHT *dht, Node_format *nodes, uint16_t max_num)
2187 return count; 2165 return count;
2188} 2166}
2189 2167
2168/* Put up to max_num nodes in nodes from the random friends.
2169 *
2170 * return the number of nodes.
2171 */
2172uint16_t randfriends_nodes(DHT *dht, Node_format *nodes, uint16_t max_num)
2173{
2174 if (max_num == 0)
2175 return 0;
2176
2177 uint16_t count = 0;
2178 unsigned int i, r = rand();
2179
2180 for (i = 0; i < DHT_FAKE_FRIEND_NUMBER; ++i) {
2181 count += list_nodes(dht->friends_list[(i + r) % DHT_FAKE_FRIEND_NUMBER].client_list, MAX_FRIEND_CLIENTS, nodes + count,
2182 max_num - count);
2183
2184 if (count >= max_num)
2185 break;
2186 }
2187
2188 return count;
2189}
2190
2191/* Put up to max_num nodes in nodes from the closelist.
2192 *
2193 * return the number of nodes.
2194 */
2195uint16_t closelist_nodes(DHT *dht, Node_format *nodes, uint16_t max_num)
2196{
2197 return list_nodes(dht->close_clientlist, LCLIENT_LIST, nodes, max_num);
2198}
2199
2190void do_hardening(DHT *dht) 2200void do_hardening(DHT *dht)
2191{ 2201{
2192 uint32_t i; 2202 uint32_t i;
@@ -2321,7 +2331,11 @@ DHT *new_DHT(Networking_Core *net)
2321 for (i = 0; i < DHT_FAKE_FRIEND_NUMBER; ++i) { 2331 for (i = 0; i < DHT_FAKE_FRIEND_NUMBER; ++i) {
2322 uint8_t random_key_bytes[crypto_box_PUBLICKEYBYTES]; 2332 uint8_t random_key_bytes[crypto_box_PUBLICKEYBYTES];
2323 randombytes(random_key_bytes, sizeof(random_key_bytes)); 2333 randombytes(random_key_bytes, sizeof(random_key_bytes));
2324 DHT_addfriend(dht, random_key_bytes, 0, 0, 0, 0); 2334
2335 if (DHT_addfriend(dht, random_key_bytes, 0, 0, 0, 0) != 0) {
2336 kill_DHT(dht);
2337 return NULL;
2338 }
2325 } 2339 }
2326 2340
2327 return dht; 2341 return dht;
diff --git a/toxcore/DHT.h b/toxcore/DHT.h
index 50ab92dc..c83ca073 100644
--- a/toxcore/DHT.h
+++ b/toxcore/DHT.h
@@ -125,6 +125,12 @@ typedef struct {
125 125
126typedef struct { 126typedef struct {
127 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 127 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
128 IP_Port ip_port;
129}
130Node_format;
131
132typedef struct {
133 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
128 Client_data client_list[MAX_FRIEND_CLIENTS]; 134 Client_data client_list[MAX_FRIEND_CLIENTS];
129 135
130 /* Time at which the last get_nodes request was sent. */ 136 /* Time at which the last get_nodes request was sent. */
@@ -142,14 +148,10 @@ typedef struct {
142 int32_t number; 148 int32_t number;
143 } callbacks[DHT_FRIEND_MAX_LOCKS]; 149 } callbacks[DHT_FRIEND_MAX_LOCKS];
144 150
151 Node_format to_bootstrap[MAX_SENT_NODES];
152 unsigned int num_to_bootstrap;
145} DHT_Friend; 153} DHT_Friend;
146 154
147typedef struct {
148 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
149 IP_Port ip_port;
150}
151Node_format;
152
153/* Return packet size of packed node with ip_family on success. 155/* Return packet size of packed node with ip_family on success.
154 * Return -1 on failure. 156 * Return -1 on failure.
155 */ 157 */
@@ -311,6 +313,12 @@ int get_close_nodes(const DHT *dht, const uint8_t *public_key, Node_format *node
311 uint8_t is_LAN, uint8_t want_good); 313 uint8_t is_LAN, uint8_t want_good);
312 314
313 315
316/* Put up to max_num nodes in nodes from the random friends.
317 *
318 * return the number of nodes.
319 */
320uint16_t randfriends_nodes(DHT *dht, Node_format *nodes, uint16_t max_num);
321
314/* Put up to max_num nodes in nodes from the closelist. 322/* Put up to max_num nodes in nodes from the closelist.
315 * 323 *
316 * return the number of nodes. 324 * return the number of nodes.
diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c
index 61378fd0..11a7b629 100644
--- a/toxcore/onion_client.c
+++ b/toxcore/onion_client.c
@@ -1209,16 +1209,14 @@ int onion_set_friend_online(Onion_Client *onion_c, int friend_num, uint8_t is_on
1209 1209
1210static void populate_path_nodes(Onion_Client *onion_c) 1210static void populate_path_nodes(Onion_Client *onion_c)
1211{ 1211{
1212 Node_format nodes_list[MAX_SENT_NODES]; 1212 Node_format nodes_list[MAX_FRIEND_CLIENTS];
1213 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 1213
1214 uint32_t random_num = rand(); 1214 unsigned int num_nodes = randfriends_nodes(onion_c->dht, nodes_list, MAX_FRIEND_CLIENTS);
1215 memcpy(public_key, &random_num, sizeof(random_num));
1216 1215
1217 unsigned int num_nodes = get_close_nodes(onion_c->dht, public_key, nodes_list, (rand() % 2) ? AF_INET : AF_INET6, 1, 0);
1218 unsigned int i; 1216 unsigned int i;
1219 1217
1220 for (i = 0; i < num_nodes; ++i) { 1218 for (i = 0; i < num_nodes; ++i) {
1221 onion_add_path_node(onion_c, nodes_list[i].ip_port, nodes_list[i].public_key); 1219 int r = onion_add_path_node(onion_c, nodes_list[i].ip_port, nodes_list[i].public_key);
1222 } 1220 }
1223} 1221}
1224 1222
@@ -1415,7 +1413,7 @@ static int onion_isconnected(const Onion_Client *onion_c)
1415 return 0; 1413 return 0;
1416} 1414}
1417 1415
1418#define ONION_CONNECTION_SECONDS 2 1416#define ONION_CONNECTION_SECONDS 3
1419 1417
1420/* return 0 if we are not connected to the network. 1418/* return 0 if we are not connected to the network.
1421 * return 1 if we are connected with TCP only. 1419 * return 1 if we are connected with TCP only.
@@ -1441,8 +1439,6 @@ void do_onion_client(Onion_Client *onion_c)
1441 if (onion_c->last_run == unix_time()) 1439 if (onion_c->last_run == unix_time())
1442 return; 1440 return;
1443 1441
1444 populate_path_nodes(onion_c);
1445
1446 do_announce(onion_c); 1442 do_announce(onion_c);
1447 1443
1448 if (onion_isconnected(onion_c)) { 1444 if (onion_isconnected(onion_c)) {
@@ -1461,6 +1457,7 @@ void do_onion_client(Onion_Client *onion_c)
1461 _Bool UDP_connected = DHT_non_lan_connected(onion_c->dht); 1457 _Bool UDP_connected = DHT_non_lan_connected(onion_c->dht);
1462 1458
1463 if (is_timeout(onion_c->first_run, ONION_CONNECTION_SECONDS)) { 1459 if (is_timeout(onion_c->first_run, ONION_CONNECTION_SECONDS)) {
1460 populate_path_nodes(onion_c);
1464 set_tcp_onion_status(onion_c->c->tcp_c, !UDP_connected); 1461 set_tcp_onion_status(onion_c->c->tcp_c, !UDP_connected);
1465 } 1462 }
1466 1463