summaryrefslogtreecommitdiff
path: root/toxcore/DHT.c
diff options
context:
space:
mode:
authorDiadlo <polsha3@gmail.com>2017-06-04 23:32:19 +0300
committerDiadlo <polsha3@gmail.com>2017-06-05 01:51:12 +0300
commitdb7b422f0c0e834f1fa9a3232a6a2b14868ed4f6 (patch)
tree147d1697b3ed754b2b86e6ea445f13e93678477b /toxcore/DHT.c
parentb3174bb6c4cf1f98d51d45a744b6cfbd3fe61ce0 (diff)
Add 'index_of' functions
- Replace 'for' with long body - Replace friend_number function on index_of_friend_pk - Replace client_in_nodelist on index_of_node_pk
Diffstat (limited to 'toxcore/DHT.c')
-rw-r--r--toxcore/DHT.c269
1 files changed, 143 insertions, 126 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c
index dbe7c6e7..31512a39 100644
--- a/toxcore/DHT.c
+++ b/toxcore/DHT.c
@@ -519,7 +519,49 @@ int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed
519 return num; 519 return num;
520} 520}
521 521
522/* Find index of ##type with public_key equal to pk.
523 *
524 * return index or UINT32_MAX if not found.
525 */
526#define INDEX_OF_PK \
527 for (uint32_t i = 0; i < size; i++) { \
528 if (id_equal(array[i].public_key, pk)) { \
529 return i; \
530 } \
531 } \
532 \
533 return UINT32_MAX;
522 534
535static uint32_t index_of_client_pk(const Client_data *array, uint32_t size, const uint8_t *pk)
536{
537 INDEX_OF_PK
538}
539
540static uint32_t index_of_friend_pk(const DHT_Friend *array, uint32_t size, const uint8_t *pk)
541{
542 INDEX_OF_PK
543}
544
545static uint32_t index_of_node_pk(const Node_format *array, uint32_t size, const uint8_t *pk)
546{
547 INDEX_OF_PK
548}
549
550/* Find index of Client_data with ip_port equal to param ip_port.
551 *
552 * return index or UINT32_MAX if not found.
553 */
554static uint32_t index_of_client_ip_port(const Client_data *array, uint32_t size, const IP_Port *ip_port)
555{
556 for (uint32_t i = 0; i < size; ++i) {
557 if (ip_port->ip.family == AF_INET && ipport_equal(&array[i].assoc4.ip_port, ip_port) ||
558 ip_port->ip.family == AF_INET6 && ipport_equal(&array[i].assoc6.ip_port, ip_port)) {
559 return i;
560 }
561 }
562
563 return UINT32_MAX;
564}
523 565
524/* Check if client with public_key is already in list of length length. 566/* Check if client with public_key is already in list of length length.
525 * If it is then set its corresponding timestamp to current time. 567 * If it is then set its corresponding timestamp to current time.
@@ -532,113 +574,85 @@ static int client_or_ip_port_in_list(Logger *log, Client_data *list, uint16_t le
532 IP_Port ip_port) 574 IP_Port ip_port)
533{ 575{
534 uint64_t temp_time = unix_time(); 576 uint64_t temp_time = unix_time();
577 uint32_t index = index_of_client_pk(list, length, public_key);
535 578
536 /* if public_key is in list, find it and maybe overwrite ip_port */ 579 /* if public_key is in list, find it and maybe overwrite ip_port */
537 for (uint32_t i = 0; i < length; ++i) { 580 if (index != UINT32_MAX) {
538 if (id_equal(list[i].public_key, public_key)) { 581 /* Refresh the client timestamp. */
539 /* Refresh the client timestamp. */ 582 if (ip_port.ip.family == AF_INET) {
540 if (ip_port.ip.family == AF_INET) { 583 if (!ipport_equal(&list[index].assoc4.ip_port, &ip_port)) {
541 584 char ip_str[IP_NTOA_LEN];
542 if (!ipport_equal(&list[i].assoc4.ip_port, &ip_port)) { 585 LOGGER_TRACE(log, "coipil[%u]: switching ipv4 from %s:%u to %s:%u", index,
543 char ip_str[IP_NTOA_LEN]; 586 ip_ntoa(&list[index].assoc4.ip_port.ip, ip_str, sizeof(ip_str)),
544 LOGGER_TRACE(log, "coipil[%u]: switching ipv4 from %s:%u to %s:%u", i, 587 net_ntohs(list[index].assoc4.ip_port.port),
545 ip_ntoa(&list[i].assoc4.ip_port.ip, ip_str, sizeof(ip_str)), 588 ip_ntoa(&ip_port.ip, ip_str, sizeof(ip_str)),
546 net_ntohs(list[i].assoc4.ip_port.port), 589 net_ntohs(ip_port.port));
547 ip_ntoa(&ip_port.ip, ip_str, sizeof(ip_str)), 590 }
548 net_ntohs(ip_port.port)); 591
549 } 592 if (LAN_ip(list[index].assoc4.ip_port.ip) != 0 && LAN_ip(ip_port.ip) == 0) {
550 593 return 1;
551 if (LAN_ip(list[i].assoc4.ip_port.ip) != 0 && LAN_ip(ip_port.ip) == 0) { 594 }
552 return 1; 595
553 } 596 list[index].assoc4.ip_port = ip_port;
554 597 list[index].assoc4.timestamp = temp_time;
555 list[i].assoc4.ip_port = ip_port; 598 } else if (ip_port.ip.family == AF_INET6) {
556 list[i].assoc4.timestamp = temp_time; 599
557 } else if (ip_port.ip.family == AF_INET6) { 600 if (!ipport_equal(&list[index].assoc6.ip_port, &ip_port)) {
558 601 char ip_str[IP_NTOA_LEN];
559 if (!ipport_equal(&list[i].assoc6.ip_port, &ip_port)) { 602 LOGGER_TRACE(log, "coipil[%u]: switching ipv6 from %s:%u to %s:%u", index,
560 char ip_str[IP_NTOA_LEN]; 603 ip_ntoa(&list[index].assoc6.ip_port.ip, ip_str, sizeof(ip_str)),
561 LOGGER_TRACE(log, "coipil[%u]: switching ipv6 from %s:%u to %s:%u", i, 604 net_ntohs(list[index].assoc6.ip_port.port),
562 ip_ntoa(&list[i].assoc6.ip_port.ip, ip_str, sizeof(ip_str)), 605 ip_ntoa(&ip_port.ip, ip_str, sizeof(ip_str)),
563 net_ntohs(list[i].assoc6.ip_port.port), 606 net_ntohs(ip_port.port));
564 ip_ntoa(&ip_port.ip, ip_str, sizeof(ip_str)), 607 }
565 net_ntohs(ip_port.port));
566 }
567
568 if (LAN_ip(list[i].assoc6.ip_port.ip) != 0 && LAN_ip(ip_port.ip) == 0) {
569 return 1;
570 }
571 608
572 list[i].assoc6.ip_port = ip_port; 609 if (LAN_ip(list[index].assoc6.ip_port.ip) != 0 && LAN_ip(ip_port.ip) == 0) {
573 list[i].assoc6.timestamp = temp_time; 610 return 1;
574 } 611 }
575 612
576 return 1; 613 list[index].assoc6.ip_port = ip_port;
614 list[index].assoc6.timestamp = temp_time;
577 } 615 }
616
617 return 1;
578 } 618 }
579 619
580 /* public_key not in list yet: see if we can find an identical ip_port, in 620 /* public_key not in list yet: see if we can find an identical ip_port, in
581 * that case we kill the old public_key by overwriting it with the new one 621 * that case we kill the old public_key by overwriting it with the new one
582 * TODO(irungentoo): maybe we SHOULDN'T do that if that public_key is in a friend_list 622 * TODO(irungentoo): maybe we SHOULDN'T do that if that public_key is in a friend_list
583 * and the one who is the actual friend's public_key/address set? */ 623 * and the one who is the actual friend's public_key/address set?
584 for (uint32_t i = 0; i < length; ++i) { 624 * MAYBE: check the other address, if valid, don't nuke? */
585 /* MAYBE: check the other address, if valid, don't nuke? */ 625 index = index_of_client_ip_port(list, length, &ip_port);
586 if ((ip_port.ip.family == AF_INET) && ipport_equal(&list[i].assoc4.ip_port, &ip_port)) {
587 /* Initialize client timestamp. */
588 list[i].assoc4.timestamp = temp_time;
589 memcpy(list[i].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
590
591 LOGGER_DEBUG(log, "coipil[%u]: switching public_key (ipv4)", i);
592
593 /* kill the other address, if it was set */
594 memset(&list[i].assoc6, 0, sizeof(list[i].assoc6));
595 return 1;
596 }
597
598 if ((ip_port.ip.family == AF_INET6) && ipport_equal(&list[i].assoc6.ip_port, &ip_port)) {
599 /* Initialize client timestamp. */
600 list[i].assoc6.timestamp = temp_time;
601 memcpy(list[i].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
602
603 LOGGER_DEBUG(log, "coipil[%u]: switching public_key (ipv6)", i);
604 626
605 /* kill the other address, if it was set */ 627 if (index == UINT32_MAX) {
606 memset(&list[i].assoc4, 0, sizeof(list[i].assoc4)); 628 return 0;
607 return 1;
608 }
609 } 629 }
610 630
611 return 0; 631 if (ip_port.ip.family == AF_INET) {
612} 632 /* Initialize client timestamp. */
633 list[index].assoc4.timestamp = temp_time;
634 memcpy(list[index].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
613 635
614/* Check if client with public_key is already in node format list of length length. 636 LOGGER_DEBUG(log, "coipil[%u]: switching public_key (ipv4)", index);
615 * 637
616 * return 1 if true. 638 /* kill the other address, if it was set */
617 * return 0 if false. 639 memset(&list[index].assoc6, 0, sizeof(list[index].assoc6));
618 */ 640 return 1;
619static int client_in_nodelist(const Node_format *list, uint16_t length, const uint8_t *public_key)
620{
621 for (uint32_t i = 0; i < length; ++i) {
622 if (id_equal(list[i].public_key, public_key)) {
623 return 1;
624 }
625 } 641 }
626 642
627 return 0; 643 if (ip_port.ip.family == AF_INET6) {
628} 644 /* Initialize client timestamp. */
645 list[index].assoc6.timestamp = temp_time;
646 memcpy(list[index].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
629 647
630/* return friend number from the public_key. 648 LOGGER_DEBUG(log, "coipil[%u]: switching public_key (ipv6)", index);
631 * return -1 if a failure occurs. 649
632 */ 650 /* kill the other address, if it was set */
633static int friend_number(const DHT *dht, const uint8_t *public_key) 651 memset(&list[index].assoc4, 0, sizeof(list[index].assoc4));
634{ 652 return 1;
635 for (uint32_t i = 0; i < dht->num_friends; ++i) {
636 if (id_equal(dht->friends_list[i].public_key, public_key)) {
637 return i;
638 }
639 } 653 }
640 654
641 return -1; 655 return 0;
642} 656}
643 657
644/* Add node to the node list making sure only the nodes closest to cmp_pk are in the list. 658/* Add node to the node list making sure only the nodes closest to cmp_pk are in the list.
@@ -696,7 +710,7 @@ static void get_close_nodes_inner(const uint8_t *public_key, Node_format *nodes_
696 const Client_data *client = &client_list[i]; 710 const Client_data *client = &client_list[i];
697 711
698 /* node already in list? */ 712 /* node already in list? */
699 if (client_in_nodelist(nodes_list, MAX_SENT_NODES, client->public_key)) { 713 if (index_of_node_pk(nodes_list, MAX_SENT_NODES, client->public_key) != UINT32_MAX) {
700 continue; 714 continue;
701 } 715 }
702 716
@@ -998,13 +1012,15 @@ bool node_addable_to_close_list(DHT *dht, const uint8_t *public_key, IP_Port ip_
998static bool is_pk_in_client_list(Client_data *list, unsigned int client_list_length, const uint8_t *public_key, 1012static bool is_pk_in_client_list(Client_data *list, unsigned int client_list_length, const uint8_t *public_key,
999 IP_Port ip_port) 1013 IP_Port ip_port)
1000{ 1014{
1001 for (uint32_t i = 0; i < client_list_length; ++i) { 1015 uint32_t index = index_of_client_pk(list, client_list_length, public_key);
1002 if ((ip_port.ip.family == AF_INET && !is_timeout(list[i].assoc4.timestamp, BAD_NODE_TIMEOUT)) 1016
1003 || (ip_port.ip.family == AF_INET6 && !is_timeout(list[i].assoc6.timestamp, BAD_NODE_TIMEOUT))) { 1017 if (index == UINT32_MAX) {
1004 if (public_key_cmp(list[i].public_key, public_key) == 0) { 1018 return 0;
1005 return 1; 1019 }
1006 } 1020
1007 } 1021 if ((ip_port.ip.family == AF_INET && !is_timeout(list[index].assoc4.timestamp, BAD_NODE_TIMEOUT))
1022 || (ip_port.ip.family == AF_INET6 && !is_timeout(list[index].assoc6.timestamp, BAD_NODE_TIMEOUT))) {
1023 return 1;
1008 } 1024 }
1009 1025
1010 return 0; 1026 return 0;
@@ -1035,7 +1051,7 @@ static unsigned int ping_node_from_getnodes_ok(DHT *dht, const uint8_t *public_k
1035 ret = 1; 1051 ret = 1;
1036 } 1052 }
1037 1053
1038 if (ret && !client_in_nodelist(dht->to_bootstrap, dht->num_to_bootstrap, public_key) 1054 if (ret && index_of_node_pk(dht->to_bootstrap, dht->num_to_bootstrap, public_key) == UINT32_MAX
1039 && !is_pk_in_close_list(dht, public_key, ip_port)) { 1055 && !is_pk_in_close_list(dht, public_key, ip_port)) {
1040 if (dht->num_to_bootstrap < MAX_CLOSE_TO_BOOTSTRAP_NODES) { 1056 if (dht->num_to_bootstrap < MAX_CLOSE_TO_BOOTSTRAP_NODES) {
1041 memcpy(dht->to_bootstrap[dht->num_to_bootstrap].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE); 1057 memcpy(dht->to_bootstrap[dht->num_to_bootstrap].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
@@ -1060,7 +1076,7 @@ static unsigned int ping_node_from_getnodes_ok(DHT *dht, const uint8_t *public_k
1060 store_ok = 1; 1076 store_ok = 1;
1061 } 1077 }
1062 1078
1063 if (store_ok && !client_in_nodelist(dht_friend->to_bootstrap, dht_friend->num_to_bootstrap, public_key) 1079 if (store_ok && index_of_node_pk(dht->to_bootstrap, dht->num_to_bootstrap, public_key) == UINT32_MAX
1064 && !is_pk_in_client_list(dht_friend->client_list, MAX_FRIEND_CLIENTS, public_key, ip_port)) { 1080 && !is_pk_in_client_list(dht_friend->client_list, MAX_FRIEND_CLIENTS, public_key, ip_port)) {
1065 if (dht_friend->num_to_bootstrap < MAX_SENT_NODES) { 1081 if (dht_friend->num_to_bootstrap < MAX_SENT_NODES) {
1066 memcpy(dht_friend->to_bootstrap[dht_friend->num_to_bootstrap].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE); 1082 memcpy(dht_friend->to_bootstrap[dht_friend->num_to_bootstrap].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
@@ -1456,11 +1472,11 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, const uint8_t *pa
1456int DHT_addfriend(DHT *dht, const uint8_t *public_key, void (*ip_callback)(void *data, int32_t number, IP_Port), 1472int DHT_addfriend(DHT *dht, const uint8_t *public_key, void (*ip_callback)(void *data, int32_t number, IP_Port),
1457 void *data, int32_t number, uint16_t *lock_count) 1473 void *data, int32_t number, uint16_t *lock_count)
1458{ 1474{
1459 int friend_num = friend_number(dht, public_key); 1475 uint32_t friend_num = index_of_friend_pk(dht->friends_list, dht->num_friends, public_key);
1460 1476
1461 uint16_t lock_num; 1477 uint16_t lock_num;
1462 1478
1463 if (friend_num != -1) { /* Is friend already in DHT? */ 1479 if (friend_num != UINT32_MAX) { /* Is friend already in DHT? */
1464 DHT_Friend *dht_friend = &dht->friends_list[friend_num]; 1480 DHT_Friend *dht_friend = &dht->friends_list[friend_num];
1465 1481
1466 if (dht_friend->lock_count == DHT_FRIEND_MAX_LOCKS) { 1482 if (dht_friend->lock_count == DHT_FRIEND_MAX_LOCKS) {
@@ -1511,9 +1527,9 @@ int DHT_addfriend(DHT *dht, const uint8_t *public_key, void (*ip_callback)(void
1511 1527
1512int DHT_delfriend(DHT *dht, const uint8_t *public_key, uint16_t lock_count) 1528int DHT_delfriend(DHT *dht, const uint8_t *public_key, uint16_t lock_count)
1513{ 1529{
1514 int friend_num = friend_number(dht, public_key); 1530 uint32_t friend_num = index_of_friend_pk(dht->friends_list, dht->num_friends, public_key);
1515 1531
1516 if (friend_num == -1) { 1532 if (friend_num == UINT32_MAX) {
1517 return -1; 1533 return -1;
1518 } 1534 }
1519 1535
@@ -1558,26 +1574,27 @@ int DHT_getfriendip(const DHT *dht, const uint8_t *public_key, IP_Port *ip_port)
1558 ip_reset(&ip_port->ip); 1574 ip_reset(&ip_port->ip);
1559 ip_port->port = 0; 1575 ip_port->port = 0;
1560 1576
1561 for (uint32_t i = 0; i < dht->num_friends; ++i) { 1577 int index = index_of_friend_pk(dht->friends_list, dht->num_friends, public_key);
1562 /* Equal */
1563 if (id_equal(dht->friends_list[i].public_key, public_key)) {
1564 for (uint32_t j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
1565 Client_data *client = &dht->friends_list[i].client_list[j];
1566
1567 if (id_equal(client->public_key, public_key)) {
1568 IPPTsPng *assoc = NULL;
1569 uint32_t a;
1570
1571 for (a = 0, assoc = &client->assoc6; a < 2; a++, assoc = &client->assoc4) {
1572 if (!is_timeout(assoc->timestamp, BAD_NODE_TIMEOUT)) {
1573 *ip_port = assoc->ip_port;
1574 return 1;
1575 }
1576 }
1577 }
1578 }
1579 1578
1580 return 0; 1579 if (index == UINT32_MAX) {
1580 return -1;
1581 }
1582
1583 DHT_Friend *frnd = &dht->friends_list[index];
1584 index = index_of_client_pk(frnd->client_list, MAX_FRIEND_CLIENTS, public_key);
1585
1586 if (index == UINT32_MAX) {
1587 return -1;
1588 }
1589
1590 Client_data *client = &frnd->client_list[index];
1591 IPPTsPng *assoc = NULL;
1592 uint32_t a;
1593
1594 for (a = 0, assoc = &client->assoc6; a < 2; a++, assoc = &client->assoc4) {
1595 if (!is_timeout(assoc->timestamp, BAD_NODE_TIMEOUT)) {
1596 *ip_port = assoc->ip_port;
1597 return 1;
1581 } 1598 }
1582 } 1599 }
1583 1600
@@ -1854,9 +1871,9 @@ static int friend_iplist(const DHT *dht, IP_Port *ip_portlist, uint16_t friend_n
1854 */ 1871 */
1855int route_tofriend(const DHT *dht, const uint8_t *friend_id, const uint8_t *packet, uint16_t length) 1872int route_tofriend(const DHT *dht, const uint8_t *friend_id, const uint8_t *packet, uint16_t length)
1856{ 1873{
1857 int num = friend_number(dht, friend_id); 1874 uint32_t num = index_of_friend_pk(dht->friends_list, dht->num_friends, friend_id);
1858 1875
1859 if (num == -1) { 1876 if (num == UINT32_MAX) {
1860 return 0; 1877 return 0;
1861 } 1878 }
1862 1879
@@ -1913,9 +1930,9 @@ int route_tofriend(const DHT *dht, const uint8_t *friend_id, const uint8_t *pack
1913 */ 1930 */
1914static int routeone_tofriend(DHT *dht, const uint8_t *friend_id, const uint8_t *packet, uint16_t length) 1931static int routeone_tofriend(DHT *dht, const uint8_t *friend_id, const uint8_t *packet, uint16_t length)
1915{ 1932{
1916 int num = friend_number(dht, friend_id); 1933 uint32_t num = index_of_friend_pk(dht->friends_list, dht->num_friends, friend_id);
1917 1934
1918 if (num == -1) { 1935 if (num == UINT32_MAX) {
1919 return 0; 1936 return 0;
1920 } 1937 }
1921 1938
@@ -2005,9 +2022,9 @@ static int handle_NATping(void *object, IP_Port source, const uint8_t *source_pu
2005 uint64_t ping_id; 2022 uint64_t ping_id;
2006 memcpy(&ping_id, packet + 1, sizeof(uint64_t)); 2023 memcpy(&ping_id, packet + 1, sizeof(uint64_t));
2007 2024
2008 int friendnumber = friend_number(dht, source_pubkey); 2025 uint32_t friendnumber = index_of_friend_pk(dht->friends_list, dht->num_friends, source_pubkey);
2009 2026
2010 if (friendnumber == -1) { 2027 if (friendnumber == UINT32_MAX) {
2011 return 1; 2028 return 1;
2012 } 2029 }
2013 2030