diff options
author | Nathan S. Evans <evans@in.tum.de> | 2010-08-30 16:33:42 +0000 |
---|---|---|
committer | Nathan S. Evans <evans@in.tum.de> | 2010-08-30 16:33:42 +0000 |
commit | 810b7ad575e584d4a3fa9923d2c8df85976739d5 (patch) | |
tree | 0d2f42c5036f9b7e9e4d3a8e39258b328b52f9c0 /src/dht/gnunet-service-dht.c | |
parent | 2bd55ef10bc6fdbfb28ad875ce8d1dd4a8cf1c50 (diff) | |
download | gnunet-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.c | 480 |
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 | */ |
150 | struct P2PPendingMessage | 167 | struct 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 | */ | ||
512 | struct 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 | */ |
489 | struct DHTResults | 524 | struct DHTResults |
@@ -518,17 +553,49 @@ struct RecentRequests | |||
518 | 553 | ||
519 | struct RecentRequest | 554 | struct 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 | */ |
530 | static struct RecentRequests recent; | 592 | static struct RecentRequests recent; |
531 | #endif | 593 | |
594 | /** | ||
595 | * Context to use to calculate find peer rates. | ||
596 | */ | ||
597 | static 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; | |||
547 | static int stop_on_found; | 614 | static 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 | */ | ||
620 | static 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 | */ |
663 | static unsigned int malicious_getter; | 736 | static 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 | */ |
669 | static unsigned int malicious_putter; | 742 | static unsigned int malicious_putter; |
670 | 743 | ||
744 | /** | ||
745 | * Frequency for malicious get requests. | ||
746 | */ | ||
671 | static unsigned long long malicious_get_frequency; | 747 | static unsigned long long malicious_get_frequency; |
672 | 748 | ||
749 | /** | ||
750 | * Frequency for malicious put requests. | ||
751 | */ | ||
673 | static unsigned long long malicious_put_frequency; | 752 | static 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 | */ | ||
758 | static struct GNUNET_TIME_Relative reply_times[MAX_REPLY_TIMES]; | ||
759 | |||
760 | /** | ||
761 | * Current counter for replies. | ||
762 | */ | ||
763 | static unsigned int reply_counter; | ||
764 | |||
765 | /** | ||
676 | * Forward declaration. | 766 | * Forward declaration. |
677 | */ | 767 | */ |
678 | static size_t send_generic_reply (void *cls, size_t size, void *buf); | 768 | static 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 */ |
681 | size_t core_transmit_notify (void *cls, | 771 | size_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 | */ | ||
780 | static void | ||
781 | hash_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 | */ | ||
796 | static 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 | */ | ||
828 | static 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 | |||
684 | static void | 845 | static void |
685 | increment_stats(const char *value) | 846 | increment_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 | */ |
2180 | int | 2351 | int |
2181 | am_closest_peer (const GNUNET_HashCode * target) | 2352 | am_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 | */ | ||
2550 | static void | ||
2551 | remove_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 | |||
2726 | malicious_get_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 2941 | malicious_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, |