aboutsummaryrefslogtreecommitdiff
path: root/src/dht/gnunet-service-dht_neighbours.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dht/gnunet-service-dht_neighbours.c')
-rw-r--r--src/dht/gnunet-service-dht_neighbours.c96
1 files changed, 40 insertions, 56 deletions
diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c
index d48d2a5df..3cb788a06 100644
--- a/src/dht/gnunet-service-dht_neighbours.c
+++ b/src/dht/gnunet-service-dht_neighbours.c
@@ -430,9 +430,13 @@ static struct GNUNET_ATS_ConnectivityHandle *ats_ch;
430static int 430static int
431find_bucket (const struct GNUNET_HashCode *hc) 431find_bucket (const struct GNUNET_HashCode *hc)
432{ 432{
433 struct GNUNET_HashCode xor;
433 unsigned int bits; 434 unsigned int bits;
434 435
435 bits = GNUNET_CRYPTO_hash_matching_bits (&my_identity_hash, hc); 436 GNUNET_CRYPTO_hash_xor (hc,
437 &my_identity_hash,
438 &xor);
439 bits = GNUNET_CRYPTO_hash_count_leading_zeros (&xor);
436 if (bits == MAX_BUCKETS) 440 if (bits == MAX_BUCKETS)
437 { 441 {
438 /* How can all bits match? Got my own ID? */ 442 /* How can all bits match? Got my own ID? */
@@ -889,40 +893,6 @@ get_forward_count (uint32_t hop_count,
889 893
890 894
891/** 895/**
892 * Compute the distance between have and target as a 64-bit value.
893 * Differences in the lower bits must count stronger than differences
894 * in the higher bits.
895 *
896 * @param target
897 * @param have
898 * @param bucket up to which offset are @a target and @a have identical and thus those bits should not be considered
899 * @return 0 if have==target, otherwise a number
900 * that is larger as the distance between
901 * the two hash codes increases
902 */
903static uint64_t
904get_distance (const struct GNUNET_HashCode *target,
905 const struct GNUNET_HashCode *have,
906 unsigned int bucket)
907{
908 uint64_t lsb = 0;
909
910 for (unsigned int i = bucket + 1;
911 (i < sizeof(struct GNUNET_HashCode) * 8) &&
912 (i < bucket + 1 + 64);
913 i++)
914 {
915 if (GNUNET_CRYPTO_hash_get_bit_rtl (target, i) !=
916 GNUNET_CRYPTO_hash_get_bit_rtl (have, i))
917 lsb |= (1LLU << (bucket + 64 - i)); /* first bit set will be 1,
918 * last bit set will be 63 -- if
919 * i does not reach 512 first... */
920 }
921 return lsb;
922}
923
924
925/**
926 * Check whether my identity is closer than any known peers. If a 896 * Check whether my identity is closer than any known peers. If a
927 * non-null bloomfilter is given, check if this is the closest peer 897 * non-null bloomfilter is given, check if this is the closest peer
928 * that hasn't already been routed to. 898 * that hasn't already been routed to.
@@ -936,7 +906,7 @@ enum GNUNET_GenericReturnValue
936GDS_am_closest_peer (const struct GNUNET_HashCode *key, 906GDS_am_closest_peer (const struct GNUNET_HashCode *key,
937 const struct GNUNET_CONTAINER_BloomFilter *bloom) 907 const struct GNUNET_CONTAINER_BloomFilter *bloom)
938{ 908{
939 int bits; 909 struct GNUNET_HashCode xor;
940 int other_bits; 910 int other_bits;
941 int bucket_num; 911 int bucket_num;
942 struct PeerInfo *pos; 912 struct PeerInfo *pos;
@@ -946,8 +916,6 @@ GDS_am_closest_peer (const struct GNUNET_HashCode *key,
946 return GNUNET_YES; 916 return GNUNET_YES;
947 bucket_num = find_bucket (key); 917 bucket_num = find_bucket (key);
948 GNUNET_assert (bucket_num >= 0); 918 GNUNET_assert (bucket_num >= 0);
949 bits = GNUNET_CRYPTO_hash_matching_bits (&my_identity_hash,
950 key);
951 pos = k_buckets[bucket_num].head; 919 pos = k_buckets[bucket_num].head;
952 while (NULL != pos) 920 while (NULL != pos)
953 { 921 {
@@ -959,9 +927,11 @@ GDS_am_closest_peer (const struct GNUNET_HashCode *key,
959 pos = pos->next; 927 pos = pos->next;
960 continue; /* Skip already checked entries */ 928 continue; /* Skip already checked entries */
961 } 929 }
962 other_bits = GNUNET_CRYPTO_hash_matching_bits (&pos->phash, 930 GNUNET_CRYPTO_hash_xor (&pos->phash,
963 key); 931 key,
964 if (other_bits > bits) 932 &xor);
933 other_bits = GNUNET_CRYPTO_hash_count_leading_zeros (&xor);
934 if (other_bits > bucket_num)
965 return GNUNET_NO; 935 return GNUNET_NO;
966 pos = pos->next; 936 pos = pos->next;
967 } 937 }
@@ -1013,14 +983,16 @@ select_peer (const struct GNUNET_HashCode *key,
1013 (count < bucket_size); 983 (count < bucket_size);
1014 pos = pos->next) 984 pos = pos->next)
1015 { 985 {
986 struct GNUNET_HashCode xor;
1016 unsigned int bucket; 987 unsigned int bucket;
1017 uint64_t dist; 988 uint64_t dist;
1018 989
1019 bucket = GNUNET_CRYPTO_hash_matching_bits (key, 990 GNUNET_CRYPTO_hash_xor (key,
1020 &pos->phash); 991 &pos->phash,
1021 dist = get_distance (key, 992 &xor);
1022 &pos->phash, 993 bucket = GNUNET_CRYPTO_hash_count_leading_zeros (&xor);
1023 bucket); 994 dist = GNUNET_CRYPTO_hash_bucket_distance (&xor,
995 bucket);
1024 if (bucket < best_bucket) 996 if (bucket < best_bucket)
1025 continue; 997 continue;
1026 if (dist > best_in_bucket) 998 if (dist > best_in_bucket)
@@ -1691,7 +1663,15 @@ handle_dht_p2p_put (void *cls,
1691 { 1663 {
1692 char *tmp; 1664 char *tmp;
1693 char *pp; 1665 char *pp;
1694 1666 struct GNUNET_HashCode mxor;
1667 struct GNUNET_HashCode pxor;
1668
1669 GNUNET_CRYPTO_hash_xor (&my_identity_hash,
1670 &put->key,
1671 &mxor);
1672 GNUNET_CRYPTO_hash_xor (&peer->phash,
1673 &put->key,
1674 &pxor);
1695 pp = GNUNET_STRINGS_pp2s (put_path, 1675 pp = GNUNET_STRINGS_pp2s (put_path,
1696 putlen); 1676 putlen);
1697 tmp = GNUNET_strdup (GNUNET_i2s (&my_identity)); 1677 tmp = GNUNET_strdup (GNUNET_i2s (&my_identity));
@@ -1701,10 +1681,8 @@ handle_dht_p2p_put (void *cls,
1701 GNUNET_i2s (peer->id), 1681 GNUNET_i2s (peer->id),
1702 tmp, 1682 tmp,
1703 ntohl (put->hop_count), 1683 ntohl (put->hop_count),
1704 GNUNET_CRYPTO_hash_matching_bits (&peer->phash, 1684 GNUNET_CRYPTO_hash_count_leading_zeros (&pxor),
1705 &put->key), 1685 GNUNET_CRYPTO_hash_count_leading_zeros (&mxor),
1706 GNUNET_CRYPTO_hash_matching_bits (&my_identity_hash,
1707 &put->key),
1708 pp); 1686 pp);
1709 GNUNET_free (pp); 1687 GNUNET_free (pp);
1710 GNUNET_free (tmp); 1688 GNUNET_free (tmp);
@@ -2070,7 +2048,15 @@ handle_dht_p2p_get (void *cls,
2070 if (GNUNET_YES == log_route_details_stderr) 2048 if (GNUNET_YES == log_route_details_stderr)
2071 { 2049 {
2072 char *tmp; 2050 char *tmp;
2073 2051 struct GNUNET_HashCode mxor;
2052 struct GNUNET_HashCode pxor;
2053
2054 GNUNET_CRYPTO_hash_xor (&my_identity_hash,
2055 &get->key,
2056 &mxor);
2057 GNUNET_CRYPTO_hash_xor (&peer->phash,
2058 &get->key,
2059 &pxor);
2074 tmp = GNUNET_strdup (GNUNET_i2s (&my_identity)); 2060 tmp = GNUNET_strdup (GNUNET_i2s (&my_identity));
2075 LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, 2061 LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG,
2076 "R5N GET %s: %s->%s (%u, %u=>%u) xq: %.*s\n", 2062 "R5N GET %s: %s->%s (%u, %u=>%u) xq: %.*s\n",
@@ -2078,10 +2064,8 @@ handle_dht_p2p_get (void *cls,
2078 GNUNET_i2s (peer->id), 2064 GNUNET_i2s (peer->id),
2079 tmp, 2065 tmp,
2080 ntohl (get->hop_count), 2066 ntohl (get->hop_count),
2081 GNUNET_CRYPTO_hash_matching_bits (&peer->phash, 2067 GNUNET_CRYPTO_hash_count_leading_zeros (&pxor),
2082 &get->key), 2068 GNUNET_CRYPTO_hash_count_leading_zeros (&mxor),
2083 GNUNET_CRYPTO_hash_matching_bits (&my_identity_hash,
2084 &get->key),
2085 ntohl (get->xquery_size), 2069 ntohl (get->xquery_size),
2086 (const char *) xquery); 2070 (const char *) xquery);
2087 GNUNET_free (tmp); 2071 GNUNET_free (tmp);