aboutsummaryrefslogtreecommitdiff
path: root/src/dht/gnunet-service-dht.c
diff options
context:
space:
mode:
authorNathan S. Evans <evans@in.tum.de>2010-08-30 16:33:42 +0000
committerNathan S. Evans <evans@in.tum.de>2010-08-30 16:33:42 +0000
commit810b7ad575e584d4a3fa9923d2c8df85976739d5 (patch)
tree0d2f42c5036f9b7e9e4d3a8e39258b328b52f9c0 /src/dht/gnunet-service-dht.c
parent2bd55ef10bc6fdbfb28ad875ce8d1dd4a8cf1c50 (diff)
downloadgnunet-810b7ad575e584d4a3fa9923d2c8df85976739d5.tar.gz
gnunet-810b7ad575e584d4a3fa9923d2c8df85976739d5.zip
assorted dht changes, fixes, etc.
Diffstat (limited to 'src/dht/gnunet-service-dht.c')
-rw-r--r--src/dht/gnunet-service-dht.c480
1 files changed, 371 insertions, 109 deletions
diff --git a/src/dht/gnunet-service-dht.c b/src/dht/gnunet-service-dht.c
index 98e02d2a0..e28682ee4 100644
--- a/src/dht/gnunet-service-dht.c
+++ b/src/dht/gnunet-service-dht.c
@@ -67,14 +67,14 @@
67 */ 67 */
68#define MINIMUM_PEER_THRESHOLD 20 68#define MINIMUM_PEER_THRESHOLD 20
69 69
70
71
72#define DHT_MAX_RECENT 100 70#define DHT_MAX_RECENT 100
73 71
72#define FIND_PEER_CALC_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60)
73
74/** 74/**
75 * Default time to wait to send messages on behalf of other peers. 75 * Default time to wait to send messages on behalf of other peers.
76 */ 76 */
77#define DHT_DEFAULT_P2P_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10); 77#define DHT_DEFAULT_P2P_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
78 78
79/** 79/**
80 * Default importance for handling messages on behalf of other peers. 80 * Default importance for handling messages on behalf of other peers.
@@ -82,9 +82,14 @@
82#define DHT_DEFAULT_P2P_IMPORTANCE 0 82#define DHT_DEFAULT_P2P_IMPORTANCE 0
83 83
84/** 84/**
85 * How long to keep recent requests arounds by default.
86 */
87#define DEFAULT_RECENT_REMOVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 60)
88
89/**
85 * Default time to wait to send find peer messages sent by the dht service. 90 * Default time to wait to send find peer messages sent by the dht service.
86 */ 91 */
87#define DHT_DEFAULT_FIND_PEER_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30); 92#define DHT_DEFAULT_FIND_PEER_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
88 93
89/** 94/**
90 * Default importance for find peer messages sent by the dht service. 95 * Default importance for find peer messages sent by the dht service.
@@ -99,7 +104,7 @@
99/** 104/**
100 * Default options for find peer requests sent by the dht service. 105 * Default options for find peer requests sent by the dht service.
101 */ 106 */
102#define DHT_DEFAULT_FIND_PEER_OPTIONS GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE 107#define DHT_DEFAULT_FIND_PEER_OPTIONS GNUNET_DHT_RO_NONE
103 108
104/** 109/**
105 * How long at least to wait before sending another find peer request. 110 * How long at least to wait before sending another find peer request.
@@ -109,7 +114,7 @@
109/** 114/**
110 * How long at most to wait before sending another find peer request. 115 * How long at most to wait before sending another find peer request.
111 */ 116 */
112#define DHT_MAXIMUM_FIND_PEER_INTERVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 5) 117#define DHT_MAXIMUM_FIND_PEER_INTERVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 8)
113 118
114/** 119/**
115 * How often to update our preference levels for peers in our routing tables. 120 * How often to update our preference levels for peers in our routing tables.
@@ -117,6 +122,12 @@
117#define DHT_DEFAULT_PREFERENCE_INTERVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2) 122#define DHT_DEFAULT_PREFERENCE_INTERVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2)
118 123
119/** 124/**
125 * How long at most on average will we allow a reply forward to take
126 * (before we quit sending out new requests)
127 */
128#define MAX_REQUEST_TIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1)
129
130/**
120 * How many initial requests to send out (in true Kademlia fashion) 131 * How many initial requests to send out (in true Kademlia fashion)
121 */ 132 */
122#define DHT_KADEMLIA_REPLICATION 3 133#define DHT_KADEMLIA_REPLICATION 3
@@ -145,6 +156,12 @@
145#define MAX_HOPS 20 156#define MAX_HOPS 20
146 157
147/** 158/**
159 * How many time differences between requesting a core send and
160 * the actual callback to remember.
161 */
162#define MAX_REPLY_TIMES 8
163
164/**
148 * Linked list of messages to send to clients. 165 * Linked list of messages to send to clients.
149 */ 166 */
150struct P2PPendingMessage 167struct P2PPendingMessage
@@ -165,6 +182,11 @@ struct P2PPendingMessage
165 unsigned int importance; 182 unsigned int importance;
166 183
167 /** 184 /**
185 * Time when this request was scheduled to be sent.
186 */
187 struct GNUNET_TIME_Absolute scheduled;
188
189 /**
168 * How long to wait before sending message. 190 * How long to wait before sending message.
169 */ 191 */
170 struct GNUNET_TIME_Relative timeout; 192 struct GNUNET_TIME_Relative timeout;
@@ -251,7 +273,6 @@ struct PeerInfo
251 * Task for scheduling periodic ping messages for this peer. 273 * Task for scheduling periodic ping messages for this peer.
252 */ 274 */
253 GNUNET_SCHEDULER_TaskIdentifier ping_task; 275 GNUNET_SCHEDULER_TaskIdentifier ping_task;
254
255}; 276};
256 277
257/** 278/**
@@ -329,7 +350,6 @@ struct ClientList
329 * Tail of linked list of pending messages for this client 350 * Tail of linked list of pending messages for this client
330 */ 351 */
331 struct PendingMessage *pending_tail; 352 struct PendingMessage *pending_tail;
332
333}; 353};
334 354
335 355
@@ -353,7 +373,7 @@ struct DHT_MessageContext
353 /** 373 /**
354 * The key this request was about 374 * The key this request was about
355 */ 375 */
356 const GNUNET_HashCode *key; 376 GNUNET_HashCode key;
357 377
358 /** 378 /**
359 * The unique identifier of this request 379 * The unique identifier of this request
@@ -484,6 +504,21 @@ struct DHTQueryRecord
484}; 504};
485 505
486/** 506/**
507 * Context used to calculate the number of find peer messages
508 * per X time units since our last scheduled find peer message
509 * was sent. If we have seen too many messages, delay or don't
510 * send our own out.
511 */
512struct FindPeerMessageContext
513{
514 unsigned int count;
515
516 struct GNUNET_TIME_Absolute start;
517
518 struct GNUNET_TIME_Absolute end;
519};
520
521/**
487 * DHT Routing results structure 522 * DHT Routing results structure
488 */ 523 */
489struct DHTResults 524struct DHTResults
@@ -518,17 +553,49 @@ struct RecentRequests
518 553
519struct RecentRequest 554struct RecentRequest
520{ 555{
556 /**
557 * Position of this node in the min heap.
558 */
559 struct GNUNET_CONTAINER_HeapNode *heap_node;
560
561 /**
562 * Bloomfilter containing entries for peers
563 * we forwarded this request to.
564 */
565 struct GNUNET_CONTAINER_BloomFilter *bloom;
566
567 /**
568 * Timestamp of this request, for ordering
569 * the min heap.
570 */
571 struct GNUNET_TIME_Absolute timestamp;
572
573 /**
574 * Key of this request.
575 */
521 GNUNET_HashCode key; 576 GNUNET_HashCode key;
577
578 /**
579 * Unique identifier for this request.
580 */
522 uint64_t uid; 581 uint64_t uid;
523};
524 582
583 /**
584 * Task to remove this entry on timeout.
585 */
586 GNUNET_SCHEDULER_TaskIdentifier remove_task;
587};
525 588
526#if 0
527/** 589/**
528 * Recent requests by hash/uid and by time inserted. 590 * Recent requests by hash/uid and by time inserted.
529 */ 591 */
530static struct RecentRequests recent; 592static struct RecentRequests recent;
531#endif 593
594/**
595 * Context to use to calculate find peer rates.
596 */
597static struct FindPeerMessageContext find_peer_context;
598
532/** 599/**
533 * Don't use our routing algorithm, always route 600 * Don't use our routing algorithm, always route
534 * to closest peer; initially send requests to 3 601 * to closest peer; initially send requests to 3
@@ -547,6 +614,12 @@ static int stop_on_closest;
547static int stop_on_found; 614static int stop_on_found;
548 615
549/** 616/**
617 * Whether DHT needs to manage find peer requests, or
618 * an external force will do it on behalf of the DHT.
619 */
620static int do_find_peer;
621
622/**
550 * How many peers have we added since we sent out our last 623 * How many peers have we added since we sent out our last
551 * find peer request? 624 * find peer request?
552 */ 625 */
@@ -662,25 +735,113 @@ static unsigned int malicious_dropper;
662 */ 735 */
663static unsigned int malicious_getter; 736static unsigned int malicious_getter;
664 737
665/* 738/**
666 * GNUNET_YES or GNUNET_NO, whether or not to act as 739 * GNUNET_YES or GNUNET_NO, whether or not to act as
667 * a malicious node which sends out lots of PUTS 740 * a malicious node which sends out lots of PUTS
668 */ 741 */
669static unsigned int malicious_putter; 742static unsigned int malicious_putter;
670 743
744/**
745 * Frequency for malicious get requests.
746 */
671static unsigned long long malicious_get_frequency; 747static unsigned long long malicious_get_frequency;
672 748
749/**
750 * Frequency for malicious put requests.
751 */
673static unsigned long long malicious_put_frequency; 752static unsigned long long malicious_put_frequency;
674 753
675/** 754/**
755 * Reply times for requests, if we are busy, don't send any
756 * more requests!
757 */
758static struct GNUNET_TIME_Relative reply_times[MAX_REPLY_TIMES];
759
760/**
761 * Current counter for replies.
762 */
763static unsigned int reply_counter;
764
765/**
676 * Forward declaration. 766 * Forward declaration.
677 */ 767 */
678static size_t send_generic_reply (void *cls, size_t size, void *buf); 768static size_t send_generic_reply (void *cls, size_t size, void *buf);
679 769
680/* Declare here so retry_core_send is aware of it */ 770/** Declare here so retry_core_send is aware of it */
681size_t core_transmit_notify (void *cls, 771size_t core_transmit_notify (void *cls,
682 size_t size, void *buf); 772 size_t size, void *buf);
683 773
774/**
775 * Convert unique ID to hash code.
776 *
777 * @param uid unique ID to convert
778 * @param hash set to uid (extended with zeros)
779 */
780static void
781hash_from_uid (uint64_t uid,
782 GNUNET_HashCode *hash)
783{
784 memset (hash, 0, sizeof(GNUNET_HashCode));
785 *((uint64_t*)hash) = uid;
786}
787
788#if AVG
789/**
790 * Calculate the average send time between messages so that we can
791 * ignore certain requests if we get too busy.
792 *
793 * @return the average time between asking core to send a message
794 * and when the buffer for copying it is passed
795 */
796static struct GNUNET_TIME_Relative get_average_send_delay()
797{
798 unsigned int i;
799 unsigned int divisor;
800 struct GNUNET_TIME_Relative average_time;
801 average_time = GNUNET_TIME_relative_get_zero();
802 divisor = 0;
803 for (i = 0; i < MAX_REPLY_TIMES; i++)
804 {
805 average_time = GNUNET_TIME_relative_add(average_time, reply_times[i]);
806 if (reply_times[i].value == (uint64_t)0)
807 continue;
808 else
809 divisor++;
810 }
811 if (divisor == 0)
812 {
813 return average_time;
814 }
815
816 average_time = GNUNET_TIME_relative_divide(average_time, divisor);
817 fprintf(stderr, "Avg send delay: %u sends is %llu\n", divisor, (long long unsigned int)average_time.value);
818 return average_time;
819}
820#endif
821
822/**
823 * Find the maximum send time of the recently sent values.
824 *
825 * @return the average time between asking core to send a message
826 * and when the buffer for copying it is passed
827 */
828static struct GNUNET_TIME_Relative get_max_send_delay()
829{
830 unsigned int i;
831 struct GNUNET_TIME_Relative max_time;
832 max_time = GNUNET_TIME_relative_get_zero();
833
834 for (i = 0; i < MAX_REPLY_TIMES; i++)
835 {
836 if (reply_times[i].value > max_time.value)
837 max_time.value = reply_times[i].value;
838 }
839
840 if (max_time.value > MAX_REQUEST_TIME.value)
841 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Max send delay was %llu\n", (long long unsigned int)max_time.value);
842 return max_time;
843}
844
684static void 845static void
685increment_stats(const char *value) 846increment_stats(const char *value)
686{ 847{
@@ -718,6 +879,10 @@ try_core_send (void *cls,
718 "`%s:%s': Calling notify_transmit_ready with size %d for peer %s\n", my_short_id, 879 "`%s:%s': Calling notify_transmit_ready with size %d for peer %s\n", my_short_id,
719 "DHT", ssize, GNUNET_i2s(&peer->id)); 880 "DHT", ssize, GNUNET_i2s(&peer->id));
720#endif 881#endif
882 pending->scheduled = GNUNET_TIME_absolute_get();
883 reply_counter++;
884 if (reply_counter >= MAX_REPLY_TIMES)
885 reply_counter = 0;
721 peer->th = GNUNET_CORE_notify_transmit_ready(coreAPI, pending->importance, 886 peer->th = GNUNET_CORE_notify_transmit_ready(coreAPI, pending->importance,
722 pending->timeout, &peer->id, 887 pending->timeout, &peer->id,
723 ssize, &core_transmit_notify, peer); 888 ssize, &core_transmit_notify, peer);
@@ -759,7 +924,7 @@ static void forward_result_message (void *cls,
759 result_message->hop_count = htonl(msg_ctx->hop_count + 1); 924 result_message->hop_count = htonl(msg_ctx->hop_count + 1);
760 GNUNET_assert(GNUNET_OK == GNUNET_CONTAINER_bloomfilter_get_raw_data(msg_ctx->bloom, result_message->bloomfilter, DHT_BLOOM_SIZE)); 925 GNUNET_assert(GNUNET_OK == GNUNET_CONTAINER_bloomfilter_get_raw_data(msg_ctx->bloom, result_message->bloomfilter, DHT_BLOOM_SIZE));
761 result_message->unique_id = GNUNET_htonll(msg_ctx->unique_id); 926 result_message->unique_id = GNUNET_htonll(msg_ctx->unique_id);
762 memcpy(&result_message->key, msg_ctx->key, sizeof(GNUNET_HashCode)); 927 memcpy(&result_message->key, &msg_ctx->key, sizeof(GNUNET_HashCode));
763 memcpy(&result_message[1], msg, ntohs(msg->size)); 928 memcpy(&result_message[1], msg, ntohs(msg->size));
764#if DEBUG_DHT > 1 929#if DEBUG_DHT > 1
765 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s:%s Adding pending message size %d for peer %s\n", my_short_id, "DHT", msize, GNUNET_i2s(&peer->id)); 930 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s:%s Adding pending message size %d for peer %s\n", my_short_id, "DHT", msize, GNUNET_i2s(&peer->id));
@@ -802,6 +967,7 @@ size_t core_transmit_notify (void *cls,
802 peer->th = NULL; 967 peer->th = NULL;
803 off = 0; 968 off = 0;
804 pending = peer->head; 969 pending = peer->head;
970 reply_times[reply_counter] = GNUNET_TIME_absolute_get_difference(pending->scheduled, GNUNET_TIME_absolute_get());
805 msize = ntohs(pending->msg->size); 971 msize = ntohs(pending->msg->size);
806 if (msize <= size) 972 if (msize <= size)
807 { 973 {
@@ -1246,6 +1412,7 @@ static int move_lowest_bucket (void *cls,
1246 struct PeerInfo *peer = value; 1412 struct PeerInfo *peer = value;
1247 int new_bucket; 1413 int new_bucket;
1248 1414
1415 GNUNET_assert(lowest_bucket > 0);
1249 new_bucket = lowest_bucket - 1; 1416 new_bucket = lowest_bucket - 1;
1250 remove_peer(peer, lowest_bucket); 1417 remove_peer(peer, lowest_bucket);
1251 GNUNET_CONTAINER_DLL_insert_after(k_buckets[new_bucket].head, 1418 GNUNET_CONTAINER_DLL_insert_after(k_buckets[new_bucket].head,
@@ -1358,7 +1525,7 @@ static void forward_message (void *cls,
1358 1525
1359 increment_stats(STAT_ROUTE_FORWARDS); 1526 increment_stats(STAT_ROUTE_FORWARDS);
1360 1527
1361 if ((msg_ctx->closest != GNUNET_YES) && (peer == find_closest_peer(msg_ctx->key))) 1528 if ((msg_ctx->closest != GNUNET_YES) && (peer == find_closest_peer(&msg_ctx->key)))
1362 increment_stats(STAT_ROUTE_FORWARDS_CLOSEST); 1529 increment_stats(STAT_ROUTE_FORWARDS_CLOSEST);
1363 1530
1364 msize = sizeof (struct GNUNET_DHT_P2PRouteMessage) + ntohs(msg->size); 1531 msize = sizeof (struct GNUNET_DHT_P2PRouteMessage) + ntohs(msg->size);
@@ -1378,8 +1545,7 @@ static void forward_message (void *cls,
1378 route_message->unique_id = GNUNET_htonll(msg_ctx->unique_id); 1545 route_message->unique_id = GNUNET_htonll(msg_ctx->unique_id);
1379 if (msg_ctx->bloom != NULL) 1546 if (msg_ctx->bloom != NULL)
1380 GNUNET_assert(GNUNET_OK == GNUNET_CONTAINER_bloomfilter_get_raw_data(msg_ctx->bloom, route_message->bloomfilter, DHT_BLOOM_SIZE)); 1547 GNUNET_assert(GNUNET_OK == GNUNET_CONTAINER_bloomfilter_get_raw_data(msg_ctx->bloom, route_message->bloomfilter, DHT_BLOOM_SIZE));
1381 if (msg_ctx->key != NULL) 1548 memcpy(&route_message->key, &msg_ctx->key, sizeof(GNUNET_HashCode));
1382 memcpy(&route_message->key, msg_ctx->key, sizeof(GNUNET_HashCode));
1383 memcpy(&route_message[1], msg, ntohs(msg->size)); 1549 memcpy(&route_message[1], msg, ntohs(msg->size));
1384#if DEBUG_DHT > 1 1550#if DEBUG_DHT > 1
1385 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s:%s Adding pending message size %d for peer %s\n", my_short_id, "DHT", msize, GNUNET_i2s(&peer->id)); 1551 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s:%s Adding pending message size %d for peer %s\n", my_short_id, "DHT", msize, GNUNET_i2s(&peer->id));
@@ -1625,6 +1791,8 @@ static int consider_peer (struct GNUNET_PeerIdentity *peer)
1625 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(all_known_peers, &peer->hashPubKey)) 1791 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(all_known_peers, &peer->hashPubKey))
1626 return GNUNET_NO; /* We already know this peer (are connected even!) */ 1792 return GNUNET_NO; /* We already know this peer (are connected even!) */
1627 bucket = find_current_bucket(&peer->hashPubKey); 1793 bucket = find_current_bucket(&peer->hashPubKey);
1794 if (bucket == GNUNET_SYSERR)
1795 return GNUNET_NO;
1628 if ((k_buckets[bucket].peers_size < bucket_size) || ((bucket == lowest_bucket) && (lowest_bucket > 0))) 1796 if ((k_buckets[bucket].peers_size < bucket_size) || ((bucket == lowest_bucket) && (lowest_bucket > 0)))
1629 return GNUNET_YES; 1797 return GNUNET_YES;
1630 1798
@@ -1667,6 +1835,7 @@ static int route_result_message(void *cls,
1667 } 1835 }
1668 else /* We have a valid hello, and peer id stored in new_peer */ 1836 else /* We have a valid hello, and peer id stored in new_peer */
1669 { 1837 {
1838 find_peer_context.count++;
1670 increment_stats(STAT_FIND_PEER_REPLY); 1839 increment_stats(STAT_FIND_PEER_REPLY);
1671 if (GNUNET_YES == consider_peer(&new_peer)) 1840 if (GNUNET_YES == consider_peer(&new_peer))
1672 { 1841 {
@@ -1682,7 +1851,7 @@ static int route_result_message(void *cls,
1682 if (malicious_dropper == GNUNET_YES) 1851 if (malicious_dropper == GNUNET_YES)
1683 record = NULL; 1852 record = NULL;
1684 else 1853 else
1685 record = GNUNET_CONTAINER_multihashmap_get(forward_list.hashmap, message_context->key); 1854 record = GNUNET_CONTAINER_multihashmap_get(forward_list.hashmap, &message_context->key);
1686 1855
1687 if (record == NULL) /* No record of this message! */ 1856 if (record == NULL) /* No record of this message! */
1688 { 1857 {
@@ -1701,7 +1870,7 @@ static int route_result_message(void *cls,
1701 message_context->hop_count, 1870 message_context->hop_count,
1702 GNUNET_SYSERR, 1871 GNUNET_SYSERR,
1703 &my_identity, 1872 &my_identity,
1704 message_context->key, 1873 &message_context->key,
1705 message_context->peer, NULL); 1874 message_context->peer, NULL);
1706 } 1875 }
1707#endif 1876#endif
@@ -1728,7 +1897,7 @@ static int route_result_message(void *cls,
1728 { 1897 {
1729 dhtlog_handle->insert_route (NULL, message_context->unique_id, DHTLOG_RESULT, 1898 dhtlog_handle->insert_route (NULL, message_context->unique_id, DHTLOG_RESULT,
1730 message_context->hop_count, 1899 message_context->hop_count,
1731 GNUNET_YES, &my_identity, message_context->key, 1900 GNUNET_YES, &my_identity, &message_context->key,
1732 message_context->peer, NULL); 1901 message_context->peer, NULL);
1733 } 1902 }
1734#endif 1903#endif
@@ -1763,7 +1932,7 @@ static int route_result_message(void *cls,
1763 dhtlog_handle->insert_route (NULL, message_context->unique_id, 1932 dhtlog_handle->insert_route (NULL, message_context->unique_id,
1764 DHTLOG_RESULT, 1933 DHTLOG_RESULT,
1765 message_context->hop_count, 1934 message_context->hop_count,
1766 GNUNET_NO, &my_identity, message_context->key, 1935 GNUNET_NO, &my_identity, &message_context->key,
1767 message_context->peer, &pos->source); 1936 message_context->peer, &pos->source);
1768 } 1937 }
1769#endif 1938#endif
@@ -1876,7 +2045,7 @@ handle_dht_get (void *cls,
1876 2045
1877 if (datacache != NULL) 2046 if (datacache != NULL)
1878 results = 2047 results =
1879 GNUNET_DATACACHE_get (datacache, message_context->key, get_type, 2048 GNUNET_DATACACHE_get (datacache, &message_context->key, get_type,
1880 &datacache_get_iterator, message_context); 2049 &datacache_get_iterator, message_context);
1881 2050
1882 if (results >= 1) 2051 if (results >= 1)
@@ -1891,14 +2060,14 @@ handle_dht_get (void *cls,
1891 { 2060 {
1892 dhtlog_handle->insert_query (NULL, message_context->unique_id, DHTLOG_GET, 2061 dhtlog_handle->insert_query (NULL, message_context->unique_id, DHTLOG_GET,
1893 message_context->hop_count, GNUNET_YES, &my_identity, 2062 message_context->hop_count, GNUNET_YES, &my_identity,
1894 message_context->key); 2063 &message_context->key);
1895 } 2064 }
1896 2065
1897 if ((debug_routes_extended) && (dhtlog_handle != NULL)) 2066 if ((debug_routes_extended) && (dhtlog_handle != NULL))
1898 { 2067 {
1899 dhtlog_handle->insert_route (NULL, message_context->unique_id, DHTLOG_ROUTE, 2068 dhtlog_handle->insert_route (NULL, message_context->unique_id, DHTLOG_ROUTE,
1900 message_context->hop_count, GNUNET_YES, 2069 message_context->hop_count, GNUNET_YES,
1901 &my_identity, message_context->key, message_context->peer, 2070 &my_identity, &message_context->key, message_context->peer,
1902 NULL); 2071 NULL);
1903 } 2072 }
1904#endif 2073#endif
@@ -1911,7 +2080,7 @@ handle_dht_get (void *cls,
1911 { 2080 {
1912 dhtlog_handle->insert_query (NULL, message_context->unique_id, DHTLOG_GET, 2081 dhtlog_handle->insert_query (NULL, message_context->unique_id, DHTLOG_GET,
1913 message_context->hop_count, GNUNET_NO, &my_identity, 2082 message_context->hop_count, GNUNET_NO, &my_identity,
1914 message_context->key); 2083 &message_context->key);
1915 } 2084 }
1916#endif 2085#endif
1917 } 2086 }
@@ -2000,7 +2169,7 @@ handle_dht_find_peer (void *cls,
2000 { 2169 {
2001 dhtlog_handle->insert_query (NULL, message_context->unique_id, DHTLOG_FIND_PEER, 2170 dhtlog_handle->insert_query (NULL, message_context->unique_id, DHTLOG_FIND_PEER,
2002 message_context->hop_count, GNUNET_YES, &my_identity, 2171 message_context->hop_count, GNUNET_YES, &my_identity,
2003 message_context->key); 2172 &message_context->key);
2004 } 2173 }
2005#endif 2174#endif
2006 GNUNET_free(find_peer_result); 2175 GNUNET_free(find_peer_result);
@@ -2046,7 +2215,7 @@ handle_dht_put (void *cls,
2046 { 2215 {
2047 dhtlog_handle->insert_query (NULL, message_context->unique_id, DHTLOG_PUT, 2216 dhtlog_handle->insert_query (NULL, message_context->unique_id, DHTLOG_PUT,
2048 message_context->hop_count, GNUNET_NO, &my_identity, 2217 message_context->hop_count, GNUNET_NO, &my_identity,
2049 message_context->key); 2218 &message_context->key);
2050 } 2219 }
2051 } 2220 }
2052#endif 2221#endif
@@ -2059,7 +2228,7 @@ handle_dht_put (void *cls,
2059 { 2228 {
2060 dhtlog_handle->insert_route (NULL, message_context->unique_id, DHTLOG_ROUTE, 2229 dhtlog_handle->insert_route (NULL, message_context->unique_id, DHTLOG_ROUTE,
2061 message_context->hop_count, GNUNET_YES, 2230 message_context->hop_count, GNUNET_YES,
2062 &my_identity, message_context->key, message_context->peer, 2231 &my_identity, &message_context->key, message_context->peer,
2063 NULL); 2232 NULL);
2064 } 2233 }
2065 2234
@@ -2067,13 +2236,13 @@ handle_dht_put (void *cls,
2067 { 2236 {
2068 dhtlog_handle->insert_query (NULL, message_context->unique_id, DHTLOG_PUT, 2237 dhtlog_handle->insert_query (NULL, message_context->unique_id, DHTLOG_PUT,
2069 message_context->hop_count, GNUNET_YES, &my_identity, 2238 message_context->hop_count, GNUNET_YES, &my_identity,
2070 message_context->key); 2239 &message_context->key);
2071 } 2240 }
2072#endif 2241#endif
2073 2242
2074 increment_stats(STAT_PUTS_INSERTED); 2243 increment_stats(STAT_PUTS_INSERTED);
2075 if (datacache != NULL) 2244 if (datacache != NULL)
2076 GNUNET_DATACACHE_put (datacache, message_context->key, data_size, 2245 GNUNET_DATACACHE_put (datacache, &message_context->key, data_size,
2077 (char *) &put_msg[1], put_type, 2246 (char *) &put_msg[1], put_type,
2078 GNUNET_TIME_absolute_ntoh(put_msg->expiration)); 2247 GNUNET_TIME_absolute_ntoh(put_msg->expiration));
2079 else 2248 else
@@ -2154,9 +2323,8 @@ get_forward_count (unsigned int hop_count, size_t target_replication)
2154 } 2323 }
2155 target_count = /* target_count is ALWAYS < 1 unless replication is < 1 */ 2324 target_count = /* target_count is ALWAYS < 1 unless replication is < 1 */
2156 target_replication / (target_replication * (hop_count + 1) + diameter); 2325 target_replication / (target_replication * (hop_count + 1) + diameter);
2157 target_value = 0;
2158
2159#if NONSENSE 2326#if NONSENSE
2327 target_value = 0;
2160 while (target_value < target_count) 2328 while (target_value < target_count)
2161 target_value++; /* target_value is ALWAYS 1 after this "loop" */ 2329 target_value++; /* target_value is ALWAYS 1 after this "loop" */
2162#else 2330#else
@@ -2171,33 +2339,44 @@ get_forward_count (unsigned int hop_count, size_t target_replication)
2171 2339
2172/* 2340/*
2173 * Check whether my identity is closer than any known peers. 2341 * Check whether my identity is closer than any known peers.
2342 * If a non-null bloomfilter is given, check if this is the closest
2343 * peer that hasn't already been routed to.
2174 * 2344 *
2175 * @param target hash code to check closeness to 2345 * @param target hash code to check closeness to
2346 * @param bloom bloomfilter, exclude these entries from the decision
2176 * 2347 *
2177 * Return GNUNET_YES if node location is closest, GNUNET_NO 2348 * Return GNUNET_YES if node location is closest, GNUNET_NO
2178 * otherwise. 2349 * otherwise.
2179 */ 2350 */
2180int 2351int
2181am_closest_peer (const GNUNET_HashCode * target) 2352am_closest_peer (const GNUNET_HashCode * target, struct GNUNET_CONTAINER_BloomFilter *bloom)
2182{ 2353{
2183 int bits; 2354 int bits;
2184 int other_bits; 2355 int other_bits;
2185 int bucket_num; 2356 int bucket_num;
2186 int count; 2357 int count;
2187 struct PeerInfo *pos; 2358 struct PeerInfo *pos;
2359#if INTEGER_DISTANCE
2188 unsigned int my_distance; 2360 unsigned int my_distance;
2189 2361#endif
2190 bucket_num = find_current_bucket(target); 2362 bucket_num = find_current_bucket(target);
2191 if (bucket_num == GNUNET_SYSERR) /* Same key! */ 2363 if (bucket_num == GNUNET_SYSERR) /* Same key! */
2192 return GNUNET_YES; 2364 return GNUNET_YES;
2193 2365
2194 bits = matching_bits(&my_identity.hashPubKey, target); 2366 bits = matching_bits(&my_identity.hashPubKey, target);
2367#if INTEGER_DISTANCE
2195 my_distance = distance(&my_identity.hashPubKey, target); 2368 my_distance = distance(&my_identity.hashPubKey, target);
2196 2369#endif
2197 pos = k_buckets[bucket_num].head; 2370 pos = k_buckets[bucket_num].head;
2198 count = 0; 2371 count = 0;
2199 while ((pos != NULL) && (count < bucket_size)) 2372 while ((pos != NULL) && (count < bucket_size))
2200 { 2373 {
2374 if ((bloom != NULL) && (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test(bloom, &pos->id.hashPubKey)))
2375 {
2376 pos = pos->next;
2377 continue; /* Skip already checked entries */
2378 }
2379
2201 other_bits = matching_bits(&pos->id.hashPubKey, target); 2380 other_bits = matching_bits(&pos->id.hashPubKey, target);
2202 if (other_bits > bits) 2381 if (other_bits > bits)
2203 return GNUNET_NO; 2382 return GNUNET_NO;
@@ -2361,6 +2540,33 @@ select_peer (const GNUNET_HashCode * target,
2361 } 2540 }
2362} 2541}
2363 2542
2543/**
2544 * Task used to remove recent entries, either
2545 * after timeout, when full, or on shutdown.
2546 *
2547 * @param cls the entry to remove
2548 * @param tc context, reason, etc.
2549 */
2550static void
2551remove_recent (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2552{
2553 struct RecentRequest *req = cls;
2554 static GNUNET_HashCode hash;
2555
2556 GNUNET_assert(req != NULL);
2557 hash_from_uid(req->uid, &hash);
2558 GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove(recent.hashmap, &hash, req));
2559 GNUNET_CONTAINER_heap_remove_node(recent.minHeap, req->heap_node);
2560 GNUNET_CONTAINER_bloomfilter_free(req->bloom);
2561 GNUNET_free(req);
2562
2563 if ((tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) && (0 == GNUNET_CONTAINER_multihashmap_size(recent.hashmap)) && (0 == GNUNET_CONTAINER_heap_get_size(recent.minHeap)))
2564 {
2565 GNUNET_CONTAINER_multihashmap_destroy(recent.hashmap);
2566 GNUNET_CONTAINER_heap_destroy(recent.minHeap);
2567 }
2568}
2569
2364 2570
2365/** 2571/**
2366 * Task used to remove forwarding entries, either 2572 * Task used to remove forwarding entries, either
@@ -2408,6 +2614,7 @@ static int cache_response(void *cls, struct DHT_MessageContext *msg_ctx)
2408 while (current_size >= MAX_OUTSTANDING_FORWARDS) 2614 while (current_size >= MAX_OUTSTANDING_FORWARDS)
2409 { 2615 {
2410 source_info = GNUNET_CONTAINER_heap_remove_root(forward_list.minHeap); 2616 source_info = GNUNET_CONTAINER_heap_remove_root(forward_list.minHeap);
2617 GNUNET_assert(source_info != NULL);
2411 record = source_info->record; 2618 record = source_info->record;
2412 GNUNET_CONTAINER_DLL_remove(record->head, record->tail, source_info); 2619 GNUNET_CONTAINER_DLL_remove(record->head, record->tail, source_info);
2413 if (record->head == NULL) /* No more entries in DLL */ 2620 if (record->head == NULL) /* No more entries in DLL */
@@ -2420,7 +2627,7 @@ static int cache_response(void *cls, struct DHT_MessageContext *msg_ctx)
2420 current_size = GNUNET_CONTAINER_multihashmap_size(forward_list.hashmap); 2627 current_size = GNUNET_CONTAINER_multihashmap_size(forward_list.hashmap);
2421 } 2628 }
2422 now = GNUNET_TIME_absolute_get(); 2629 now = GNUNET_TIME_absolute_get();
2423 record = GNUNET_CONTAINER_multihashmap_get(forward_list.hashmap, msg_ctx->key); 2630 record = GNUNET_CONTAINER_multihashmap_get(forward_list.hashmap, &msg_ctx->key);
2424 if (record != NULL) /* Already know this request! */ 2631 if (record != NULL) /* Already know this request! */
2425 { 2632 {
2426 pos = record->head; 2633 pos = record->head;
@@ -2439,8 +2646,8 @@ static int cache_response(void *cls, struct DHT_MessageContext *msg_ctx)
2439 else 2646 else
2440 { 2647 {
2441 record = GNUNET_malloc(sizeof (struct DHTQueryRecord)); 2648 record = GNUNET_malloc(sizeof (struct DHTQueryRecord));
2442 GNUNET_assert(GNUNET_OK == GNUNET_CONTAINER_multihashmap_put(forward_list.hashmap, msg_ctx->key, record, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 2649 GNUNET_assert(GNUNET_OK == GNUNET_CONTAINER_multihashmap_put(forward_list.hashmap, &msg_ctx->key, record, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
2443 memcpy(&record->key, msg_ctx->key, sizeof(GNUNET_HashCode)); 2650 memcpy(&record->key, &msg_ctx->key, sizeof(GNUNET_HashCode));
2444 } 2651 }
2445 2652
2446 source_info = GNUNET_malloc(sizeof(struct DHTRouteSource)); 2653 source_info = GNUNET_malloc(sizeof(struct DHTRouteSource));
@@ -2480,11 +2687,12 @@ static int route_message(void *cls,
2480{ 2687{
2481 int i; 2688 int i;
2482 struct PeerInfo *selected; 2689 struct PeerInfo *selected;
2690#if DEBUG_DHT_ROUTING > 1
2483 struct PeerInfo *nearest; 2691 struct PeerInfo *nearest;
2484 unsigned int forward_count;
2485#if DEBUG_DHT
2486 char *nearest_buf;
2487#endif 2692#endif
2693 unsigned int forward_count;
2694 struct RecentRequest *recent_req;
2695 GNUNET_HashCode unique_hash;
2488#if DEBUG_DHT_ROUTING 2696#if DEBUG_DHT_ROUTING
2489 int ret; 2697 int ret;
2490#endif 2698#endif
@@ -2496,7 +2704,7 @@ static int route_message(void *cls,
2496 { 2704 {
2497 dhtlog_handle->insert_route (NULL, message_context->unique_id, DHTLOG_ROUTE, 2705 dhtlog_handle->insert_route (NULL, message_context->unique_id, DHTLOG_ROUTE,
2498 message_context->hop_count, GNUNET_SYSERR, 2706 message_context->hop_count, GNUNET_SYSERR,
2499 &my_identity, message_context->key, message_context->peer, 2707 &my_identity, &message_context->key, message_context->peer,
2500 NULL); 2708 NULL);
2501 } 2709 }
2502#endif 2710#endif
@@ -2506,15 +2714,16 @@ static int route_message(void *cls,
2506 } 2714 }
2507 2715
2508 increment_stats(STAT_ROUTES); 2716 increment_stats(STAT_ROUTES);
2509 message_context->closest = am_closest_peer(message_context->key); 2717 /* Semantics of this call means we find whether we are the closest peer out of those already
2718 * routed to on this messages path.
2719 */
2720 message_context->closest = am_closest_peer(&message_context->key, message_context->bloom);
2510 forward_count = get_forward_count(message_context->hop_count, message_context->replication); 2721 forward_count = get_forward_count(message_context->hop_count, message_context->replication);
2511 nearest = find_closest_peer(message_context->key); 2722
2512
2513 if (message_context->bloom == NULL) 2723 if (message_context->bloom == NULL)
2514 message_context->bloom = GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K); 2724 message_context->bloom = GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K);
2515 2725
2516 if ((stop_on_closest == GNUNET_YES) && (message_context->closest == GNUNET_YES) && (ntohs(msg->type) == GNUNET_MESSAGE_TYPE_DHT_PUT)) 2726 if ((stop_on_closest == GNUNET_YES) && (message_context->closest == GNUNET_YES) && (ntohs(msg->type) == GNUNET_MESSAGE_TYPE_DHT_PUT))
2517/* || ((strict_kademlia == GNUNET_YES) && (message_context->closest == GNUNET_YES))) */
2518 forward_count = 0; 2727 forward_count = 0;
2519 2728
2520#if DEBUG_DHT_ROUTING 2729#if DEBUG_DHT_ROUTING
@@ -2527,7 +2736,7 @@ static int route_message(void *cls,
2527 { 2736 {
2528 dhtlog_handle->insert_route (NULL, message_context->unique_id, DHTLOG_ROUTE, 2737 dhtlog_handle->insert_route (NULL, message_context->unique_id, DHTLOG_ROUTE,
2529 message_context->hop_count, ret, 2738 message_context->hop_count, ret,
2530 &my_identity, message_context->key, message_context->peer, 2739 &my_identity, &message_context->key, message_context->peer,
2531 NULL); 2740 NULL);
2532 } 2741 }
2533#endif 2742#endif
@@ -2556,10 +2765,10 @@ static int route_message(void *cls,
2556 { 2765 {
2557 if ((debug_routes) && (dhtlog_handle != NULL)) 2766 if ((debug_routes) && (dhtlog_handle != NULL))
2558 { 2767 {
2559 dhtlog_handle->insert_dhtkey(NULL, message_context->key); 2768 dhtlog_handle->insert_dhtkey(NULL, &message_context->key);
2560 dhtlog_handle->insert_query (NULL, message_context->unique_id, DHTLOG_FIND_PEER, 2769 dhtlog_handle->insert_query (NULL, message_context->unique_id, DHTLOG_FIND_PEER,
2561 message_context->hop_count, GNUNET_NO, &my_identity, 2770 message_context->hop_count, GNUNET_NO, &my_identity,
2562 message_context->key); 2771 &message_context->key);
2563 } 2772 }
2564 } 2773 }
2565#endif 2774#endif
@@ -2570,42 +2779,47 @@ static int route_message(void *cls,
2570 } 2779 }
2571 2780
2572 GNUNET_CONTAINER_bloomfilter_add (message_context->bloom, &my_identity.hashPubKey); 2781 GNUNET_CONTAINER_bloomfilter_add (message_context->bloom, &my_identity.hashPubKey);
2573#if 0 2782 hash_from_uid(message_context->unique_id, &unique_hash);
2574 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(recent->hashmap, message_context->key)) 2783 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(recent.hashmap, &unique_hash))
2575 { 2784 {
2576 if (GNUNET_SYSERR = GNUNET_CONTAINER_multihashmap_get_multiple (recent->hashmap, message_context->key, &find_matching_recent, &message_context)) /* Have too recently seen this request! */ 2785 recent_req = GNUNET_CONTAINER_multihashmap_get(recent.hashmap, &unique_hash);
2577 { 2786 GNUNET_assert(recent_req != NULL);
2578 forward_count = 0; 2787 if (0 != memcmp(&recent_req->key, &message_context->key, sizeof(GNUNET_HashCode)))
2579 } 2788 increment_stats(STAT_DUPLICATE_UID);
2580 else /* Exact match not found, but same key found */ 2789 else
2581 { 2790 {
2582 recent_req = GNUNET_CONTAINER_multihashmap_get(recent->hashmap, message_context->key); 2791 increment_stats(STAT_RECENT_SEEN);
2583 } 2792 GNUNET_CONTAINER_bloomfilter_or2(message_context->bloom, recent_req->bloom, DHT_BLOOM_SIZE);
2793 }
2584 } 2794 }
2585 else 2795 else
2586 { 2796 {
2587 recent_req = GNUNET_malloc(sizeof(struct RecentRequest)); 2797 recent_req = GNUNET_malloc(sizeof(struct RecentRequest));
2588 recent_req->uid = message_context->unique_id; 2798 recent_req->uid = message_context->unique_id;
2589 memcmp(&recent_req->key, message_context->key, sizeof(GNUNET_HashCode)); 2799 memcpy(&recent_req->key, &message_context->key, sizeof(GNUNET_HashCode));
2590 recent_req->remove_task = GNUNET_SCHEDULER_add_delayed(sched, DEFAULT_RECENT_REMOVAL, &remove_recent, recent_req); 2800 recent_req->remove_task = GNUNET_SCHEDULER_add_delayed(sched, DEFAULT_RECENT_REMOVAL, &remove_recent, recent_req);
2591 GNUNET_CONTAINER_heap_insert(recent->minHeap, recent_req, GNUNET_TIME_absolute_get()); 2801 recent_req->heap_node = GNUNET_CONTAINER_heap_insert(recent.minHeap, recent_req, GNUNET_TIME_absolute_get().value);
2592 GNUNET_CONTAINER_multihashmap_put(recent->hashmap, message_context->key, recent_req, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); 2802 recent_req->bloom = GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K);
2803 GNUNET_CONTAINER_multihashmap_put(recent.hashmap, &unique_hash, recent_req, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
2593 } 2804 }
2594 2805
2595 if (GNUNET_CONTAINER_multihashmap_size(recent->hashmap) > DHT_MAX_RECENT) 2806 if (GNUNET_CONTAINER_multihashmap_size(recent.hashmap) > DHT_MAX_RECENT)
2596 { 2807 {
2597 remove_oldest_recent(); 2808 recent_req = GNUNET_CONTAINER_heap_peek(recent.minHeap);
2809 GNUNET_assert(recent_req != NULL);
2810 GNUNET_SCHEDULER_cancel(sched, recent_req->remove_task);
2811 GNUNET_SCHEDULER_add_now(sched, &remove_recent, recent_req);
2598 } 2812 }
2599#endif
2600 2813
2601 for (i = 0; i < forward_count; i++) 2814 for (i = 0; i < forward_count; i++)
2602 { 2815 {
2603 selected = select_peer(message_context->key, message_context->bloom); 2816 selected = select_peer(&message_context->key, message_context->bloom);
2604 2817
2605 if (selected != NULL) 2818 if (selected != NULL)
2606 { 2819 {
2607 GNUNET_CONTAINER_bloomfilter_add(message_context->bloom, &selected->id.hashPubKey); 2820 GNUNET_CONTAINER_bloomfilter_add(message_context->bloom, &selected->id.hashPubKey);
2608#if DEBUG_DHT_ROUTING > 1 2821#if DEBUG_DHT_ROUTING > 1
2822 nearest = find_closest_peer(&message_context->key);
2609 nearest_buf = GNUNET_strdup(GNUNET_i2s(&nearest->id)); 2823 nearest_buf = GNUNET_strdup(GNUNET_i2s(&nearest->id));
2610 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2824 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2611 "`%s:%s': Forwarding request key %s uid %llu to peer %s (closest %s, bits %d, distance %u)\n", my_short_id, 2825 "`%s:%s': Forwarding request key %s uid %llu to peer %s (closest %s, bits %d, distance %u)\n", my_short_id,
@@ -2616,7 +2830,7 @@ static int route_message(void *cls,
2616 { 2830 {
2617 dhtlog_handle->insert_route (NULL, message_context->unique_id, DHTLOG_ROUTE, 2831 dhtlog_handle->insert_route (NULL, message_context->unique_id, DHTLOG_ROUTE,
2618 message_context->hop_count, GNUNET_NO, 2832 message_context->hop_count, GNUNET_NO,
2619 &my_identity, message_context->key, message_context->peer, 2833 &my_identity, &message_context->key, message_context->peer,
2620 &selected->id); 2834 &selected->id);
2621 } 2835 }
2622 forward_message(cls, msg, selected, message_context); 2836 forward_message(cls, msg, selected, message_context);
@@ -2640,7 +2854,10 @@ static int route_message(void *cls,
2640#endif 2854#endif
2641 2855
2642 if (message_context->bloom != NULL) 2856 if (message_context->bloom != NULL)
2643 GNUNET_CONTAINER_bloomfilter_free(message_context->bloom); 2857 {
2858 GNUNET_CONTAINER_bloomfilter_or2(recent_req->bloom, message_context->bloom, DHT_BLOOM_SIZE);
2859 GNUNET_CONTAINER_bloomfilter_free(message_context->bloom);
2860 }
2644 2861
2645 return forward_count; 2862 return forward_count;
2646} 2863}
@@ -2684,7 +2901,6 @@ malicious_put_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2684 static struct GNUNET_DHT_PutMessage put_message; 2901 static struct GNUNET_DHT_PutMessage put_message;
2685 static struct DHT_MessageContext message_context; 2902 static struct DHT_MessageContext message_context;
2686 static GNUNET_HashCode key; 2903 static GNUNET_HashCode key;
2687 unsigned int mcsize;
2688 uint32_t random_key; 2904 uint32_t random_key;
2689 2905
2690 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) 2906 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
@@ -2694,12 +2910,11 @@ malicious_put_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2694 put_message.header.type = htons(GNUNET_MESSAGE_TYPE_DHT_PUT); 2910 put_message.header.type = htons(GNUNET_MESSAGE_TYPE_DHT_PUT);
2695 put_message.type = htons(DHT_MALICIOUS_MESSAGE_TYPE); 2911 put_message.type = htons(DHT_MALICIOUS_MESSAGE_TYPE);
2696 put_message.expiration = GNUNET_TIME_absolute_hton(GNUNET_TIME_absolute_get_forever()); 2912 put_message.expiration = GNUNET_TIME_absolute_hton(GNUNET_TIME_absolute_get_forever());
2697 mcsize = sizeof(struct DHT_MessageContext) + sizeof(GNUNET_HashCode);
2698 memset(&message_context, 0, sizeof(struct DHT_MessageContext)); 2913 memset(&message_context, 0, sizeof(struct DHT_MessageContext));
2699 message_context.client = NULL; 2914 message_context.client = NULL;
2700 random_key = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, (uint32_t)-1); 2915 random_key = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, (uint32_t)-1);
2701 GNUNET_CRYPTO_hash(&random_key, sizeof(uint32_t), &key); 2916 GNUNET_CRYPTO_hash(&random_key, sizeof(uint32_t), &key);
2702 message_context.key = &key; 2917 memcpy(&message_context.key, &key, sizeof(GNUNET_HashCode));
2703 message_context.unique_id = GNUNET_ntohll (GNUNET_CRYPTO_random_u64(GNUNET_CRYPTO_QUALITY_WEAK, (uint64_t)-1)); 2918 message_context.unique_id = GNUNET_ntohll (GNUNET_CRYPTO_random_u64(GNUNET_CRYPTO_QUALITY_WEAK, (uint64_t)-1));
2704 message_context.replication = ntohl (DHT_DEFAULT_FIND_PEER_REPLICATION); 2919 message_context.replication = ntohl (DHT_DEFAULT_FIND_PEER_REPLICATION);
2705 message_context.msg_options = ntohl (0); 2920 message_context.msg_options = ntohl (0);
@@ -2726,9 +2941,8 @@ static void
2726malicious_get_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 2941malicious_get_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2727{ 2942{
2728 static struct GNUNET_DHT_GetMessage get_message; 2943 static struct GNUNET_DHT_GetMessage get_message;
2729 static struct DHT_MessageContext message_context; 2944 struct DHT_MessageContext message_context;
2730 static GNUNET_HashCode key; 2945 static GNUNET_HashCode key;
2731 unsigned int mcsize;
2732 uint32_t random_key; 2946 uint32_t random_key;
2733 2947
2734 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) 2948 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
@@ -2737,12 +2951,11 @@ malicious_get_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2737 get_message.header.size = htons(sizeof(struct GNUNET_DHT_GetMessage)); 2951 get_message.header.size = htons(sizeof(struct GNUNET_DHT_GetMessage));
2738 get_message.header.type = htons(GNUNET_MESSAGE_TYPE_DHT_GET); 2952 get_message.header.type = htons(GNUNET_MESSAGE_TYPE_DHT_GET);
2739 get_message.type = htons(DHT_MALICIOUS_MESSAGE_TYPE); 2953 get_message.type = htons(DHT_MALICIOUS_MESSAGE_TYPE);
2740 mcsize = sizeof(struct DHT_MessageContext) + sizeof(GNUNET_HashCode);
2741 memset(&message_context, 0, sizeof(struct DHT_MessageContext)); 2954 memset(&message_context, 0, sizeof(struct DHT_MessageContext));
2742 message_context.client = NULL; 2955 message_context.client = NULL;
2743 random_key = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, (uint32_t)-1); 2956 random_key = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, (uint32_t)-1);
2744 GNUNET_CRYPTO_hash(&random_key, sizeof(uint32_t), &key); 2957 GNUNET_CRYPTO_hash(&random_key, sizeof(uint32_t), &key);
2745 message_context.key = &key; 2958 memcpy(&message_context.key, &key, sizeof(GNUNET_HashCode));
2746 message_context.unique_id = GNUNET_ntohll (GNUNET_CRYPTO_random_u64(GNUNET_CRYPTO_QUALITY_WEAK, (uint64_t)-1)); 2959 message_context.unique_id = GNUNET_ntohll (GNUNET_CRYPTO_random_u64(GNUNET_CRYPTO_QUALITY_WEAK, (uint64_t)-1));
2747 message_context.replication = ntohl (DHT_DEFAULT_FIND_PEER_REPLICATION); 2960 message_context.replication = ntohl (DHT_DEFAULT_FIND_PEER_REPLICATION);
2748 message_context.msg_options = ntohl (0); 2961 message_context.msg_options = ntohl (0);
@@ -2754,13 +2967,10 @@ malicious_get_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2754 dhtlog_handle->insert_dhtkey(NULL, &key); 2967 dhtlog_handle->insert_dhtkey(NULL, &key);
2755 increment_stats(STAT_GET_START); 2968 increment_stats(STAT_GET_START);
2756 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s:%s Sending malicious GET message with hash %s", my_short_id, "DHT", GNUNET_h2s(&key)); 2969 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s:%s Sending malicious GET message with hash %s", my_short_id, "DHT", GNUNET_h2s(&key));
2757 route_message(NULL, &get_message.header, &message_context); 2970 route_message (NULL, &get_message.header, &message_context);
2758 GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, malicious_get_frequency), &malicious_get_task, NULL); 2971 GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, malicious_get_frequency), &malicious_get_task, NULL);
2759} 2972}
2760 2973
2761#if DO_FIND_PEER
2762
2763
2764/** 2974/**
2765 * Iterator over hash map entries. 2975 * Iterator over hash map entries.
2766 * 2976 *
@@ -2797,11 +3007,41 @@ send_find_peer_message (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc
2797 int ret; 3007 int ret;
2798 struct GNUNET_TIME_Relative next_send_time; 3008 struct GNUNET_TIME_Relative next_send_time;
2799 struct GNUNET_CONTAINER_BloomFilter *temp_bloom; 3009 struct GNUNET_CONTAINER_BloomFilter *temp_bloom;
2800 3010#if COUNT_INTERVAL
3011 struct GNUNET_TIME_Relative time_diff;
3012 struct GNUNET_TIME_Absolute end;
3013 double multiplier;
3014 double count_per_interval;
3015#endif
2801 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) 3016 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
2802 return; 3017 return;
2803 3018
3019 if ((newly_found_peers > bucket_size) && (GNUNET_YES == do_find_peer)) /* If we are finding peers already, no need to send out our request right now! */
3020 {
3021 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Have %d newly found peers since last find peer message sent!\n", newly_found_peers);
3022 GNUNET_SCHEDULER_add_delayed (sched,
3023 GNUNET_TIME_UNIT_MINUTES,
3024 &send_find_peer_message, NULL);
3025 newly_found_peers = 0;
3026 return;
3027 }
3028
2804 increment_stats(STAT_FIND_PEER_START); 3029 increment_stats(STAT_FIND_PEER_START);
3030#if COUNT_INTERVAL
3031 end = GNUNET_TIME_absolute_get();
3032 time_diff = GNUNET_TIME_absolute_get_difference(find_peer_context.start, end);
3033
3034 if (time_diff.value > FIND_PEER_CALC_INTERVAL.value)
3035 {
3036 multiplier = time_diff.value / FIND_PEER_CALC_INTERVAL.value;
3037 count_per_interval = find_peer_context.count / multiplier;
3038 }
3039 else
3040 {
3041 multiplier = FIND_PEER_CALC_INTERVAL.value / time_diff.value;
3042 count_per_interval = find_peer_context.count * multiplier;
3043 }
3044#endif
2805 3045
2806 find_peer_msg = GNUNET_malloc(sizeof(struct GNUNET_DHT_FindPeerMessage)); 3046 find_peer_msg = GNUNET_malloc(sizeof(struct GNUNET_DHT_FindPeerMessage));
2807 find_peer_msg->header.size = htons(sizeof(struct GNUNET_DHT_FindPeerMessage)); 3047 find_peer_msg->header.size = htons(sizeof(struct GNUNET_DHT_FindPeerMessage));
@@ -2810,10 +3050,10 @@ send_find_peer_message (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc
2810 GNUNET_CONTAINER_multihashmap_iterate(all_known_peers, &add_known_to_bloom, temp_bloom); 3050 GNUNET_CONTAINER_multihashmap_iterate(all_known_peers, &add_known_to_bloom, temp_bloom);
2811 GNUNET_assert(GNUNET_OK == GNUNET_CONTAINER_bloomfilter_get_raw_data(temp_bloom, find_peer_msg->bloomfilter, DHT_BLOOM_SIZE)); 3051 GNUNET_assert(GNUNET_OK == GNUNET_CONTAINER_bloomfilter_get_raw_data(temp_bloom, find_peer_msg->bloomfilter, DHT_BLOOM_SIZE));
2812 memset(&message_context, 0, sizeof(struct DHT_MessageContext)); 3052 memset(&message_context, 0, sizeof(struct DHT_MessageContext));
2813 message_context.key = &my_identity.hashPubKey; 3053 memcpy(&message_context.key, &my_identity.hashPubKey, sizeof(GNUNET_HashCode));
2814 message_context.unique_id = GNUNET_ntohll (GNUNET_CRYPTO_random_u64(GNUNET_CRYPTO_QUALITY_STRONG, (uint64_t)-1)); 3054 message_context.unique_id = GNUNET_ntohll (GNUNET_CRYPTO_random_u64(GNUNET_CRYPTO_QUALITY_STRONG, (uint64_t)-1));
2815 message_context.replication = ntohl (DHT_DEFAULT_FIND_PEER_REPLICATION); 3055 message_context.replication = DHT_DEFAULT_FIND_PEER_REPLICATION;
2816 message_context.msg_options = ntohl (DHT_DEFAULT_FIND_PEER_OPTIONS); 3056 message_context.msg_options = DHT_DEFAULT_FIND_PEER_OPTIONS;
2817 message_context.network_size = estimate_diameter(); 3057 message_context.network_size = estimate_diameter();
2818 message_context.peer = &my_identity; 3058 message_context.peer = &my_identity;
2819 message_context.importance = DHT_DEFAULT_FIND_PEER_IMPORTANCE; 3059 message_context.importance = DHT_DEFAULT_FIND_PEER_IMPORTANCE;
@@ -2836,12 +3076,18 @@ send_find_peer_message (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc
2836 GNUNET_CRYPTO_random_u64(GNUNET_CRYPTO_QUALITY_STRONG, 3076 GNUNET_CRYPTO_random_u64(GNUNET_CRYPTO_QUALITY_STRONG,
2837 DHT_MAXIMUM_FIND_PEER_INTERVAL.value - DHT_MINIMUM_FIND_PEER_INTERVAL.value); 3077 DHT_MAXIMUM_FIND_PEER_INTERVAL.value - DHT_MINIMUM_FIND_PEER_INTERVAL.value);
2838 } 3078 }
3079
3080 GNUNET_assert (next_send_time.value != 0);
3081 find_peer_context.count = 0;
2839 newly_found_peers = 0; 3082 newly_found_peers = 0;
2840 GNUNET_SCHEDULER_add_delayed (sched, 3083 find_peer_context.start = GNUNET_TIME_absolute_get();
2841 next_send_time, 3084 if (GNUNET_YES == do_find_peer)
2842 &send_find_peer_message, NULL); 3085 {
3086 GNUNET_SCHEDULER_add_delayed (sched,
3087 next_send_time,
3088 &send_find_peer_message, NULL);
3089 }
2843} 3090}
2844#endif
2845 3091
2846/** 3092/**
2847 * Handler for any generic DHT messages, calls the appropriate handler 3093 * Handler for any generic DHT messages, calls the appropriate handler
@@ -2859,11 +3105,7 @@ handle_dht_local_route_request (void *cls, struct GNUNET_SERVER_Client *client,
2859 const struct GNUNET_DHT_RouteMessage *dht_msg = (const struct GNUNET_DHT_RouteMessage *) message; 3105 const struct GNUNET_DHT_RouteMessage *dht_msg = (const struct GNUNET_DHT_RouteMessage *) message;
2860 const struct GNUNET_MessageHeader *enc_msg; 3106 const struct GNUNET_MessageHeader *enc_msg;
2861 struct DHT_MessageContext message_context; 3107 struct DHT_MessageContext message_context;
2862 size_t enc_type;
2863
2864 enc_msg = (const struct GNUNET_MessageHeader *) &dht_msg[1]; 3108 enc_msg = (const struct GNUNET_MessageHeader *) &dht_msg[1];
2865 enc_type = ntohs (enc_msg->type);
2866
2867#if DEBUG_DHT 3109#if DEBUG_DHT
2868 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3110 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2869 "`%s:%s': Received `%s' request from client, message type %d, key %s, uid %llu\n", 3111 "`%s:%s': Received `%s' request from client, message type %d, key %s, uid %llu\n",
@@ -2876,7 +3118,7 @@ handle_dht_local_route_request (void *cls, struct GNUNET_SERVER_Client *client,
2876#endif 3118#endif
2877 memset(&message_context, 0, sizeof(struct DHT_MessageContext)); 3119 memset(&message_context, 0, sizeof(struct DHT_MessageContext));
2878 message_context.client = find_active_client (client); 3120 message_context.client = find_active_client (client);
2879 message_context.key = &dht_msg->key; 3121 memcpy(&message_context.key, &dht_msg->key, sizeof(GNUNET_HashCode));
2880 message_context.unique_id = GNUNET_ntohll (dht_msg->unique_id); 3122 message_context.unique_id = GNUNET_ntohll (dht_msg->unique_id);
2881 message_context.replication = ntohl (dht_msg->desired_replication_level); 3123 message_context.replication = ntohl (dht_msg->desired_replication_level);
2882 message_context.msg_options = ntohl (dht_msg->options); 3124 message_context.msg_options = ntohl (dht_msg->options);
@@ -2920,6 +3162,10 @@ handle_dht_control_message (void *cls, struct GNUNET_SERVER_Client *client,
2920 3162
2921 switch (ntohs(dht_control_msg->command)) 3163 switch (ntohs(dht_control_msg->command))
2922 { 3164 {
3165 case GNUNET_MESSAGE_TYPE_DHT_FIND_PEER:
3166 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Sending self seeking find peer request!\n");
3167 GNUNET_SCHEDULER_add_now(sched, &send_find_peer_message, NULL);
3168 break;
2923 case GNUNET_MESSAGE_TYPE_DHT_MALICIOUS_GET: 3169 case GNUNET_MESSAGE_TYPE_DHT_MALICIOUS_GET:
2924 if (ntohs(dht_control_msg->variable) > 0) 3170 if (ntohs(dht_control_msg->variable) > 0)
2925 malicious_get_frequency = ntohs(dht_control_msg->variable); 3171 malicious_get_frequency = ntohs(dht_control_msg->variable);
@@ -2971,15 +3217,11 @@ handle_dht_local_route_stop(void *cls, struct GNUNET_SERVER_Client *client,
2971 (const struct GNUNET_DHT_StopMessage *) message; 3217 (const struct GNUNET_DHT_StopMessage *) message;
2972 struct DHTQueryRecord *record; 3218 struct DHTQueryRecord *record;
2973 struct DHTRouteSource *pos; 3219 struct DHTRouteSource *pos;
2974 uint64_t uid;
2975#if DEBUG_DHT 3220#if DEBUG_DHT
2976 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3221 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2977 "`%s:%s': Received `%s' request from client, uid %llu\n", my_short_id, "DHT", 3222 "`%s:%s': Received `%s' request from client, uid %llu\n", my_short_id, "DHT",
2978 "GENERIC STOP", GNUNET_ntohll (dht_stop_msg->unique_id)); 3223 "GENERIC STOP", GNUNET_ntohll (dht_stop_msg->unique_id));
2979#endif 3224#endif
2980
2981 uid = GNUNET_ntohll(dht_stop_msg->unique_id);
2982
2983 record = GNUNET_CONTAINER_multihashmap_get(forward_list.hashmap, &dht_stop_msg->key); 3225 record = GNUNET_CONTAINER_multihashmap_get(forward_list.hashmap, &dht_stop_msg->key);
2984 if (record != NULL) 3226 if (record != NULL)
2985 { 3227 {
@@ -3017,6 +3259,12 @@ handle_dht_p2p_route_request (void *cls,
3017 struct GNUNET_MessageHeader *enc_msg = (struct GNUNET_MessageHeader *)&incoming[1]; 3259 struct GNUNET_MessageHeader *enc_msg = (struct GNUNET_MessageHeader *)&incoming[1];
3018 struct DHT_MessageContext *message_context; 3260 struct DHT_MessageContext *message_context;
3019 3261
3262 if (get_max_send_delay().value > MAX_REQUEST_TIME.value)
3263 {
3264 fprintf(stderr, "Sending of previous requests has taken far too long, backing off!\n");
3265 return GNUNET_YES;
3266 }
3267
3020 if (ntohs(enc_msg->type) == GNUNET_MESSAGE_TYPE_DHT_P2P_PING) /* Throw these away. FIXME: Don't throw these away? (reply)*/ 3268 if (ntohs(enc_msg->type) == GNUNET_MESSAGE_TYPE_DHT_P2P_PING) /* Throw these away. FIXME: Don't throw these away? (reply)*/
3021 { 3269 {
3022#if DEBUG_PING 3270#if DEBUG_PING
@@ -3034,7 +3282,7 @@ handle_dht_p2p_route_request (void *cls,
3034 message_context->bloom = GNUNET_CONTAINER_bloomfilter_init(incoming->bloomfilter, DHT_BLOOM_SIZE, DHT_BLOOM_K); 3282 message_context->bloom = GNUNET_CONTAINER_bloomfilter_init(incoming->bloomfilter, DHT_BLOOM_SIZE, DHT_BLOOM_K);
3035 GNUNET_assert(message_context->bloom != NULL); 3283 GNUNET_assert(message_context->bloom != NULL);
3036 message_context->hop_count = ntohl(incoming->hop_count); 3284 message_context->hop_count = ntohl(incoming->hop_count);
3037 message_context->key = &incoming->key; 3285 memcpy(&message_context->key, &incoming->key, sizeof(GNUNET_HashCode));
3038 message_context->replication = ntohl(incoming->desired_replication_level); 3286 message_context->replication = ntohl(incoming->desired_replication_level);
3039 message_context->unique_id = GNUNET_ntohll(incoming->unique_id); 3287 message_context->unique_id = GNUNET_ntohll(incoming->unique_id);
3040 message_context->msg_options = ntohl(incoming->options); 3288 message_context->msg_options = ntohl(incoming->options);
@@ -3074,7 +3322,7 @@ handle_dht_p2p_route_result (void *cls,
3074 memset(&message_context, 0, sizeof(struct DHT_MessageContext)); 3322 memset(&message_context, 0, sizeof(struct DHT_MessageContext));
3075 message_context.bloom = GNUNET_CONTAINER_bloomfilter_init(incoming->bloomfilter, DHT_BLOOM_SIZE, DHT_BLOOM_K); 3323 message_context.bloom = GNUNET_CONTAINER_bloomfilter_init(incoming->bloomfilter, DHT_BLOOM_SIZE, DHT_BLOOM_K);
3076 GNUNET_assert(message_context.bloom != NULL); 3324 GNUNET_assert(message_context.bloom != NULL);
3077 message_context.key = &incoming->key; 3325 memcpy(&message_context.key, &incoming->key, sizeof(GNUNET_HashCode));
3078 message_context.unique_id = GNUNET_ntohll(incoming->unique_id); 3326 message_context.unique_id = GNUNET_ntohll(incoming->unique_id);
3079 message_context.msg_options = ntohl(incoming->options); 3327 message_context.msg_options = ntohl(incoming->options);
3080 message_context.hop_count = ntohl(incoming->hop_count); 3328 message_context.hop_count = ntohl(incoming->hop_count);
@@ -3322,7 +3570,7 @@ run (void *cls,
3322 coreAPI = GNUNET_CORE_connect (sched, /* Main scheduler */ 3570 coreAPI = GNUNET_CORE_connect (sched, /* Main scheduler */
3323 cfg, /* Main configuration */ 3571 cfg, /* Main configuration */
3324 GNUNET_TIME_UNIT_FOREVER_REL, 3572 GNUNET_TIME_UNIT_FOREVER_REL,
3325 NULL, /* Closure passed to DHT functionas around? */ 3573 NULL, /* Closure passed to DHT functions */
3326 &core_init, /* Call core_init once connected */ 3574 &core_init, /* Call core_init once connected */
3327 &handle_core_connect, /* Handle connects */ 3575 &handle_core_connect, /* Handle connects */
3328 &handle_core_disconnect, /* remove peers on disconnects */ 3576 &handle_core_disconnect, /* remove peers on disconnects */
@@ -3402,6 +3650,15 @@ run (void *cls,
3402 malicious_dropper = GNUNET_YES; 3650 malicious_dropper = GNUNET_YES;
3403 } 3651 }
3404 3652
3653 if (GNUNET_NO ==
3654 GNUNET_CONFIGURATION_get_value_yesno(cfg, "dht",
3655 "do_find_peer"))
3656 {
3657 do_find_peer = GNUNET_NO;
3658 }
3659 else
3660 do_find_peer = GNUNET_YES;
3661
3405 if (GNUNET_YES == 3662 if (GNUNET_YES ==
3406 GNUNET_CONFIGURATION_get_value_yesno(cfg, "dht_testing", 3663 GNUNET_CONFIGURATION_get_value_yesno(cfg, "dht_testing",
3407 "mysql_logging_extended")) 3664 "mysql_logging_extended"))
@@ -3445,14 +3702,19 @@ run (void *cls,
3445 GNUNET_STATISTICS_set(stats, STAT_HELLOS_PROVIDED, 0, GNUNET_NO); 3702 GNUNET_STATISTICS_set(stats, STAT_HELLOS_PROVIDED, 0, GNUNET_NO);
3446 GNUNET_STATISTICS_set(stats, STAT_DISCONNECTS, 0, GNUNET_NO); 3703 GNUNET_STATISTICS_set(stats, STAT_DISCONNECTS, 0, GNUNET_NO);
3447 } 3704 }
3448#if DO_FIND_PEER 3705 /* FIXME: if there are no recent requests then these never get freed, but alternative is _annoying_! */
3449 next_send_time.value = DHT_MINIMUM_FIND_PEER_INTERVAL.value + 3706 recent.hashmap = GNUNET_CONTAINER_multihashmap_create(DHT_MAX_RECENT / 2);
3450 GNUNET_CRYPTO_random_u64(GNUNET_CRYPTO_QUALITY_STRONG, 3707 recent.minHeap = GNUNET_CONTAINER_heap_create(GNUNET_CONTAINER_HEAP_ORDER_MIN);
3451 (DHT_MAXIMUM_FIND_PEER_INTERVAL.value / 2) - DHT_MINIMUM_FIND_PEER_INTERVAL.value); 3708 if (GNUNET_YES == do_find_peer)
3452 GNUNET_SCHEDULER_add_delayed (sched, 3709 {
3453 next_send_time, 3710 next_send_time.value = DHT_MINIMUM_FIND_PEER_INTERVAL.value +
3454 &send_find_peer_message, NULL); 3711 GNUNET_CRYPTO_random_u64(GNUNET_CRYPTO_QUALITY_STRONG,
3455#endif 3712 (DHT_MAXIMUM_FIND_PEER_INTERVAL.value / 2) - DHT_MINIMUM_FIND_PEER_INTERVAL.value);
3713 find_peer_context.start = GNUNET_TIME_absolute_get();
3714 GNUNET_SCHEDULER_add_delayed (sched,
3715 next_send_time,
3716 &send_find_peer_message, &find_peer_context);
3717 }
3456 3718
3457 /* Scheduled the task to clean up when shutdown is called */ 3719 /* Scheduled the task to clean up when shutdown is called */
3458 cleanup_task = GNUNET_SCHEDULER_add_delayed (sched, 3720 cleanup_task = GNUNET_SCHEDULER_add_delayed (sched,