diff options
author | irungentoo <irungentoo@gmail.com> | 2015-12-11 16:48:10 -0500 |
---|---|---|
committer | irungentoo <irungentoo@gmail.com> | 2015-12-11 16:48:10 -0500 |
commit | 22b1ebb46e5470d919e1f6896c99a82c29b443d3 (patch) | |
tree | 474a3b52421e5a889dea85501f61e6f0d082dabf | |
parent | ae801b3257ccd2c13b18c013619674bee229dcae (diff) |
DHT improvements.
Feed better nodes to onion, bootstrap off close clients when DHT friend is added.
-rw-r--r-- | toxcore/DHT.c | 94 | ||||
-rw-r--r-- | toxcore/DHT.h | 20 | ||||
-rw-r--r-- | toxcore/onion_client.c | 15 |
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 | */ |
1465 | static void do_DHT_friends(DHT *dht) | 1435 | static 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 | */ |
2154 | uint16_t closelist_nodes(DHT *dht, Node_format *nodes, uint16_t max_num) | 2133 | uint16_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 | */ | ||
2172 | uint16_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 | */ | ||
2195 | uint16_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 | |||
2190 | void do_hardening(DHT *dht) | 2200 | void 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 | ||
126 | typedef struct { | 126 | typedef struct { |
127 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | 127 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; |
128 | IP_Port ip_port; | ||
129 | } | ||
130 | Node_format; | ||
131 | |||
132 | typedef 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 | ||
147 | typedef struct { | ||
148 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | ||
149 | IP_Port ip_port; | ||
150 | } | ||
151 | Node_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 | */ | ||
320 | uint16_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 | ||
1210 | static void populate_path_nodes(Onion_Client *onion_c) | 1210 | static 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 | ||